mirror of
https://salsa.debian.org/gnuk-team/gnuk/gnuk.git
synced 2024-09-19 18:30:15 +00:00
keccak.c also provides SHA-3 and SHAKE128.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
6814773294
commit
739f17781c
@ -1,3 +1,9 @@
|
||||
2024-04-18 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/keccak.c, src/keccak.h: Rename. Also offer SHA-3.
|
||||
* src/ecc-ed448.c (ed448_sign): Use keccak_context.
|
||||
* src/openpgp-do.c (proc_key_import, gpg_do_keygen): Likewise.
|
||||
|
||||
2024-02-02 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/modinv.c (modinv_normalize): Fix the computation.
|
||||
|
@ -13,7 +13,7 @@ CSRC = main.c \
|
||||
modp256k1.c jpc_p256k1.c ec_p256k1.c call-ec_p256k1.c \
|
||||
mod25638.c ecc-ed25519.c ecc-x25519.c sha512.c \
|
||||
p448.c ecc-x448.c \
|
||||
ecc-ed448.c shake256.c \
|
||||
ecc-ed448.c keccak.c \
|
||||
random.c neug.c sha256.c
|
||||
|
||||
INCDIR =
|
||||
|
@ -3,7 +3,7 @@
|
||||
* the twisted Edwards curve: -x^2 + y^2 = 1 + d*x^2*y^2
|
||||
* d = -39081
|
||||
*
|
||||
* Copyright (C) 2021 Free Software Initiative of Japan
|
||||
* Copyright (C) 2021, 2024 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@ -41,7 +41,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "p448.h"
|
||||
#include "shake256.h"
|
||||
#include "keccak.h"
|
||||
|
||||
|
||||
#define C_WORDS 7
|
||||
@ -761,7 +761,7 @@ ed448_sign (uint8_t *out, const uint8_t *input, unsigned int ilen,
|
||||
const uint8_t *a_in, const uint8_t *seed, const uint8_t *pk)
|
||||
{
|
||||
bn448 a[1], k[1], s[1];
|
||||
shake_context ctx;
|
||||
keccak_context ctx;
|
||||
const unsigned char x_olen[2] = { 0, 0 };
|
||||
uint32_t hash[BN912_WORDS];
|
||||
uint8_t r[57];
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* shake256.c -- Compute SHAKE hash.
|
||||
* keccak.c -- Compute Keccak hash.
|
||||
*
|
||||
* Copyright (C) 2021 Free Software Initiative of Japan
|
||||
* Copyright (C) 2021, 2024 Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@ -17,7 +17,7 @@
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -29,8 +29,25 @@
|
||||
* August 2015.
|
||||
*/
|
||||
|
||||
#define SHAKE_BITS 256
|
||||
#define SHAKE_INDEX_MAX (200 - (SHAKE_BITS >> 2))
|
||||
#define INDEX_MAX(cap) (200 - (cap >> 3))
|
||||
|
||||
#define SHAKE256_CAPACITY 512
|
||||
#define SHAKE256_INDEX_MAX INDEX_MAX (SHAKE256_CAPACITY)
|
||||
|
||||
#define SHAKE128_CAPACITY 256
|
||||
#define SHAKE128_INDEX_MAX INDEX_MAX (SHAKE128_CAPACITY)
|
||||
|
||||
#define SHA3_512_CAPACITY 1024
|
||||
#define SHA3_512_INDEX_MAX INDEX_MAX (SHA3_512_CAPACITY)
|
||||
|
||||
/*
|
||||
* SHAKE is defined appending 11 at the end to RawSHAKE,
|
||||
* RawSHAKE is defined adding 11 at the end to KECCAK,
|
||||
* and KECCACK uses pad10*1 at the end.
|
||||
* This means adding 111110*1 at the end.
|
||||
*/
|
||||
#define SHAKE_SUFFIX 0x1F
|
||||
#define SHA3_SUFFIX 0x06
|
||||
|
||||
/*
|
||||
* b=1600
|
||||
@ -43,7 +60,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "shake256.h"
|
||||
#include <stdarg.h>
|
||||
#include "keccak.h"
|
||||
|
||||
/* Round constants in iota step. */
|
||||
static const uint64_t rc[24] = {
|
||||
@ -144,59 +162,128 @@ keccak_f1600 (uint64_t s[25])
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
shake256_start (struct shake_context *shake)
|
||||
{
|
||||
memset (shake, 0, sizeof (shake_context));
|
||||
}
|
||||
|
||||
void
|
||||
shake256_update (struct shake_context *shake,
|
||||
const unsigned char *src, unsigned int size)
|
||||
static void
|
||||
keccak_update (struct keccak_context *keccak,
|
||||
const unsigned char *src, unsigned int size)
|
||||
{
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
while (1)
|
||||
{
|
||||
absorb (shake->state, shake->index, *src++);
|
||||
if (++shake->index == SHAKE_INDEX_MAX)
|
||||
absorb (keccak->state, keccak->index, *src++);
|
||||
if (++keccak->index == keccak->index_max)
|
||||
{
|
||||
keccak_f1600 (shake->state);
|
||||
shake->index = 0;
|
||||
keccak_f1600 (keccak->state);
|
||||
keccak->index = 0;
|
||||
}
|
||||
if (--size == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
shake256_finish (struct shake_context *shake,
|
||||
unsigned char *dst, unsigned int size)
|
||||
static void
|
||||
keccak_finish (struct keccak_context *keccak,
|
||||
unsigned char *dst, unsigned int size, uint8_t suffix)
|
||||
{
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* SHAKE is defined appending 11 at the end to RawSHAKE,
|
||||
* RawSHAKE is defined adding 11 at the end to KECCAK,
|
||||
* and KECCACK uses pad10*1 at the end.
|
||||
* This means adding 111110*1 at the end.
|
||||
*/
|
||||
absorb (shake->state, shake->index, 0x1F);
|
||||
absorb (shake->state, SHAKE_INDEX_MAX - 1, 0x80);
|
||||
keccak_f1600 (shake->state);
|
||||
shake->index = 0;
|
||||
absorb (keccak->state, keccak->index, suffix);
|
||||
absorb (keccak->state, keccak->index_max - 1, 0x80);
|
||||
keccak_f1600 (keccak->state);
|
||||
keccak->index = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
*dst++ = squeeze (shake->state, shake->index);
|
||||
*dst++ = squeeze (keccak->state, keccak->index);
|
||||
if (--size == 0)
|
||||
break;
|
||||
if (++shake->index == SHAKE_INDEX_MAX)
|
||||
if (++keccak->index == keccak->index_max)
|
||||
{
|
||||
keccak_f1600 (shake->state);
|
||||
shake->index = 0;
|
||||
keccak_f1600 (keccak->state);
|
||||
keccak->index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
shake128_start (struct keccak_context *shake)
|
||||
{
|
||||
memset (shake, 0, sizeof (keccak_context));
|
||||
shake->index_max = SHAKE128_INDEX_MAX;
|
||||
}
|
||||
|
||||
void
|
||||
shake256_start (struct keccak_context *shake)
|
||||
{
|
||||
memset (shake, 0, sizeof (keccak_context));
|
||||
shake->index_max = SHAKE256_INDEX_MAX;
|
||||
}
|
||||
|
||||
void
|
||||
shake128_update (struct keccak_context *shake,
|
||||
const unsigned char *src, unsigned int size)
|
||||
{
|
||||
keccak_update (shake, src, size);
|
||||
}
|
||||
|
||||
void
|
||||
shake256_update (struct keccak_context *shake,
|
||||
const unsigned char *src, unsigned int size)
|
||||
{
|
||||
keccak_update (shake, src, size);
|
||||
}
|
||||
|
||||
void
|
||||
shake128_finish (struct keccak_context *shake,
|
||||
unsigned char *dst, unsigned int size)
|
||||
{
|
||||
keccak_finish (shake, dst, size, SHAKE_SUFFIX);
|
||||
}
|
||||
|
||||
void
|
||||
shake256_finish (struct keccak_context *shake,
|
||||
unsigned char *dst, unsigned int size)
|
||||
{
|
||||
keccak_finish (shake, dst, size, SHAKE_SUFFIX);
|
||||
}
|
||||
|
||||
void
|
||||
shake256v (uint8_t *out, size_t outlen, ...)
|
||||
{
|
||||
struct keccak_context ctx;
|
||||
va_list ap;
|
||||
void *p;
|
||||
size_t len;
|
||||
|
||||
shake256_start (&ctx);
|
||||
|
||||
va_start (ap, outlen);
|
||||
while (1)
|
||||
{
|
||||
p = va_arg (ap, void *);
|
||||
len = va_arg (ap, size_t);
|
||||
if (!p)
|
||||
break;
|
||||
|
||||
shake256_update (&ctx, p, len);
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
shake256_finish (&ctx, out, outlen);
|
||||
}
|
||||
|
||||
void
|
||||
sha3_512 (uint8_t h[64], const uint8_t *in, size_t inlen)
|
||||
|
||||
{
|
||||
struct keccak_context ctx;
|
||||
|
||||
memset (&ctx, 0, sizeof (keccak_context));
|
||||
ctx.index_max = SHA3_512_INDEX_MAX;
|
||||
|
||||
keccak_update (&ctx, in, inlen);
|
||||
|
||||
keccak_finish (&ctx, h, 64, SHA3_SUFFIX);
|
||||
}
|
24
src/keccak.h
Normal file
24
src/keccak.h
Normal file
@ -0,0 +1,24 @@
|
||||
#include <stdint.h>
|
||||
|
||||
struct keccak_context {
|
||||
uint64_t state[25];
|
||||
uint32_t index : 8;
|
||||
uint32_t index_max : 8;
|
||||
};
|
||||
typedef struct keccak_context keccak_context;
|
||||
|
||||
void shake128_start (struct keccak_context *keccak);
|
||||
void shake128_update (struct keccak_context *keccak,
|
||||
const unsigned char *src, unsigned int size);
|
||||
void shake128_finish (struct keccak_context *keccak,
|
||||
unsigned char *dst, unsigned int size);
|
||||
|
||||
void shake256_start (struct keccak_context *keccak);
|
||||
void shake256_update (struct keccak_context *keccak,
|
||||
const unsigned char *src, unsigned int size);
|
||||
void shake256_finish (struct keccak_context *keccak,
|
||||
unsigned char *dst, unsigned int size);
|
||||
|
||||
void shake256v (uint8_t *out, size_t outlen, ...);
|
||||
|
||||
void sha3_512 (uint8_t h[64], const uint8_t *in, size_t inlen);
|
@ -2,7 +2,7 @@
|
||||
* openpgp-do.c -- OpenPGP card Data Objects (DO) handling
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018,
|
||||
* 2020, 2021, 2022
|
||||
* 2020, 2021, 2022, 2024
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@ -34,7 +34,7 @@
|
||||
#include "random.h"
|
||||
#include "aes.h"
|
||||
#include "sha512.h"
|
||||
#include "shake256.h"
|
||||
#include "keccak.h"
|
||||
|
||||
/* Forward declaration */
|
||||
#define CLEAN_PAGE_FULL 1
|
||||
@ -1567,7 +1567,7 @@ proc_key_import (const uint8_t *data, int len)
|
||||
}
|
||||
else if (attr == ALGO_ED448)
|
||||
{
|
||||
shake_context ctx;
|
||||
keccak_context ctx;
|
||||
uint8_t hash[128];
|
||||
|
||||
if (len - 12 != 57)
|
||||
@ -2348,7 +2348,7 @@ gpg_do_keygen (uint8_t *buf)
|
||||
}
|
||||
else if (attr == ALGO_ED448)
|
||||
{
|
||||
shake_context ctx;
|
||||
keccak_context ctx;
|
||||
rnd = random_bytes_get ();
|
||||
shake256_start (&ctx);
|
||||
shake256_update (&ctx, rnd, 32);
|
||||
|
@ -1,13 +0,0 @@
|
||||
#include <stdint.h>
|
||||
|
||||
struct shake_context {
|
||||
uint64_t state[25];
|
||||
uint32_t index;
|
||||
};
|
||||
typedef struct shake_context shake_context;
|
||||
|
||||
void shake256_start (struct shake_context *shake);
|
||||
void shake256_update (struct shake_context *shake,
|
||||
const unsigned char *src, unsigned int size);
|
||||
void shake256_finish (struct shake_context *shake,
|
||||
unsigned char *dst, unsigned int size);
|
Loading…
Reference in New Issue
Block a user