[PATCH] Keccak: Add SHAKE Extendable-Output Functions
Jussi Kivilinna
jussi.kivilinna at iki.fi
Sat Oct 31 13:39:34 CET 2015
* src/hash-common.c (_gcry_hash_selftest_check_one): Add handling for
XOFs.
* src/keccak.c (keccak_ops_t): Rename 'extract_inplace' to 'extract'
and add 'pos' argument.
(KECCAK_CONTEXT): Add 'suffix'.
(keccak_extract_inplace64): Rename to...
(keccak_extract64): ...this; Add handling for 'pos' argument.
(keccak_extract_inplace32bi): Rename to...
(keccak_extract32bi): ...this; Add handling for 'pos' argument.
(keccak_extract_inplace64): Rename to...
(keccak_extract64): ...this; Add handling for 'pos' argument.
(keccak_extract_inplace32bi_bmi2): Rename to...
(keccak_extract32bi_bmi2): ...this; Add handling for 'pos' argument.
(keccak_init): Setup 'suffix'; add SHAKE128 & SHAKE256.
(shake128_init, shake256_init): New.
(keccak_final): Do not initial permute for SHAKE output; use correct
suffix for SHAKE.
(keccak_extract): New.
(keccak_selftests_keccak): Add SHAKE128 & SHAKE256 test-vectors.
(run_selftests): Add SHAKE128 & SHAKE256.
(shake128_asn, oid_spec_shake128, shake256_asn, oid_spec_shake256)
(_gcry_digest_spec_shake128, _gcry_digest_spec_shake256): New.
* cipher/md.c (digest_list): Add SHAKE128 & SHAKE256.
* doc/gcrypt.texi: Ditto.
* src/cipher.h (_gcry_digest_spec_shake128)
(_gcry_digest_spec_shake256): New.
* src/gcrypt.h.in (GCRY_MD_SHAKE128, GCRY_MD_SHAKE256): New.
* tests/basic.c (check_one_md): Add XOF check; Add 'elen' argument.
(check_one_md_multi): Skip if algo is XOF.
(check_digests): Add SHAKE128 & SHAKE256 test vectors.
* tests/bench-slope.c (kdf_bench_one): Skip XOFs.
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
cipher/hash-common.c | 28 +++
cipher/keccak.c | 275 +++++++++++++++++++++++++++++----
cipher/md.c | 2
doc/gcrypt.texi | 12 +
src/cipher.h | 2
src/gcrypt.h.in | 4
tests/basic.c | 423 ++++++++++++++++++++++++++++++++++++++++++++++++--
tests/bench-slope.c | 6 +
8 files changed, 700 insertions(+), 52 deletions(-)
diff --git a/cipher/hash-common.c b/cipher/hash-common.c
index 6743f09..a750d644 100644
--- a/cipher/hash-common.c
+++ b/cipher/hash-common.c
@@ -49,8 +49,12 @@ _gcry_hash_selftest_check_one (int algo,
gcry_error_t err = 0;
gcry_md_hd_t hd;
unsigned char *digest;
+ char aaa[1000];
+ int xof = 0;
- if (_gcry_md_get_algo_dlen (algo) != expectlen)
+ if (_gcry_md_get_algo_dlen (algo) == 0)
+ xof = 1;
+ else if (_gcry_md_get_algo_dlen (algo) != expectlen)
return "digest size does not match expected size";
err = _gcry_md_open (&hd, algo, 0);
@@ -65,7 +69,6 @@ _gcry_hash_selftest_check_one (int algo,
case 1: /* Hash one million times an "a". */
{
- char aaa[1000];
int i;
/* Write in odd size chunks so that we test the buffering. */
@@ -81,10 +84,23 @@ _gcry_hash_selftest_check_one (int algo,
if (!result)
{
- digest = _gcry_md_read (hd, algo);
-
- if ( memcmp (digest, expect, expectlen) )
- result = "digest mismatch";
+ if (!xof)
+ {
+ digest = _gcry_md_read (hd, algo);
+
+ if ( memcmp (digest, expect, expectlen) )
+ result = "digest mismatch";
+ }
+ else
+ {
+ gcry_assert(expectlen <= sizeof(aaa));
+
+ err = _gcry_md_extract (hd, algo, aaa, expectlen);
+ if (err)
+ result = "error extracting output from XOF";
+ else if ( memcmp (aaa, expect, expectlen) )
+ result = "digest mismatch";
+ }
}
_gcry_md_close (hd);
diff --git a/cipher/keccak.c b/cipher/keccak.c
index d46d9cb..f4f0ef3 100644
--- a/cipher/keccak.c
+++ b/cipher/keccak.c
@@ -90,7 +90,8 @@ typedef struct
unsigned int (*permute)(KECCAK_STATE *hd);
unsigned int (*absorb)(KECCAK_STATE *hd, int pos, const byte *lanes,
unsigned int nlanes, int blocklanes);
- unsigned int (*extract_inplace) (KECCAK_STATE *hd, unsigned int outlen);
+ unsigned int (*extract) (KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
+ unsigned int outlen);
} keccak_ops_t;
@@ -100,6 +101,7 @@ typedef struct KECCAK_CONTEXT_S
unsigned int outlen;
unsigned int blocksize;
unsigned int count;
+ unsigned int suffix;
const keccak_ops_t *ops;
} KECCAK_CONTEXT;
@@ -124,13 +126,18 @@ static const u64 round_consts_64bit[24] =
};
static unsigned int
-keccak_extract_inplace64(KECCAK_STATE *hd, unsigned int outlen)
+keccak_extract64(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
+ unsigned int outlen)
{
unsigned int i;
- for (i = 0; i < outlen / 8 + !!(outlen % 8); i++)
+ /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
+
+ for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
{
- hd->u.state64[i] = le_bswap64(hd->u.state64[i]);
+ u64 tmp = hd->u.state64[i];
+ buf_put_le64(outbuf, tmp);
+ outbuf += 8;
}
return 0;
@@ -158,14 +165,17 @@ static const u32 round_consts_32bit[2 * 24] =
};
static unsigned int
-keccak_extract_inplace32bi(KECCAK_STATE *hd, unsigned int outlen)
+keccak_extract32bi(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
+ unsigned int outlen)
{
unsigned int i;
u32 x0;
u32 x1;
u32 t;
- for (i = 0; i < outlen / 8 + !!(outlen % 8); i++)
+ /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
+
+ for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
{
x0 = hd->u.state32bi[i * 2 + 0];
x1 = hd->u.state32bi[i * 2 + 1];
@@ -182,8 +192,9 @@ keccak_extract_inplace32bi(KECCAK_STATE *hd, unsigned int outlen)
t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0CUL; x1 = x1 ^ t ^ (t << 2);
t = (x1 ^ (x1 >> 1)) & 0x22222222UL; x1 = x1 ^ t ^ (t << 1);
- hd->u.state32bi[i * 2 + 0] = le_bswap32(x0);
- hd->u.state32bi[i * 2 + 1] = le_bswap32(x1);
+ buf_put_le32(&outbuf[0], x0);
+ buf_put_le32(&outbuf[4], x1);
+ outbuf += 8;
}
return 0;
@@ -249,7 +260,7 @@ static const keccak_ops_t keccak_generic64_ops =
{
.permute = keccak_f1600_state_permute64,
.absorb = keccak_absorb_lanes64,
- .extract_inplace = keccak_extract_inplace64,
+ .extract = keccak_extract64,
};
#endif /* USE_64BIT */
@@ -300,7 +311,7 @@ static const keccak_ops_t keccak_shld_64_ops =
{
.permute = keccak_f1600_state_permute64_shld,
.absorb = keccak_absorb_lanes64_shld,
- .extract_inplace = keccak_extract_inplace64,
+ .extract = keccak_extract64,
};
#endif /* USE_64BIT_SHLD */
@@ -356,7 +367,7 @@ static const keccak_ops_t keccak_bmi2_64_ops =
{
.permute = keccak_f1600_state_permute64_bmi2,
.absorb = keccak_absorb_lanes64_bmi2,
- .extract_inplace = keccak_extract_inplace64,
+ .extract = keccak_extract64,
};
#endif /* USE_64BIT_BMI2 */
@@ -404,7 +415,7 @@ static const keccak_ops_t keccak_generic32bi_ops =
{
.permute = keccak_f1600_state_permute32bi,
.absorb = keccak_absorb_lanes32bi,
- .extract_inplace = keccak_extract_inplace32bi,
+ .extract = keccak_extract32bi,
};
#endif /* USE_32BIT */
@@ -483,14 +494,17 @@ keccak_absorb_lanes32bi_bmi2(KECCAK_STATE *hd, int pos, const byte *lanes,
}
static unsigned int
-keccak_extract_inplace32bi_bmi2(KECCAK_STATE *hd, unsigned int outlen)
+keccak_extract32bi_bmi2(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
+ unsigned int outlen)
{
unsigned int i;
u32 x0;
u32 x1;
u32 t;
- for (i = 0; i < outlen / 8 + !!(outlen % 8); i++)
+ /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
+
+ for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
{
x0 = hd->u.state32bi[i * 2 + 0];
x1 = hd->u.state32bi[i * 2 + 1];
@@ -502,8 +516,9 @@ keccak_extract_inplace32bi_bmi2(KECCAK_STATE *hd, unsigned int outlen)
x0 = pdep(pext(x0, 0xffff0001), 0xaaaaaaab) | pdep(x0 >> 1, 0x55555554);
x1 = pdep(pext(x1, 0xffff0001), 0xaaaaaaab) | pdep(x1 >> 1, 0x55555554);
- hd->u.state32bi[i * 2 + 0] = le_bswap32(x0);
- hd->u.state32bi[i * 2 + 1] = le_bswap32(x1);
+ buf_put_le32(&outbuf[0], x0);
+ buf_put_le32(&outbuf[4], x1);
+ outbuf += 8;
}
return 0;
@@ -513,7 +528,7 @@ static const keccak_ops_t keccak_bmi2_32bi_ops =
{
.permute = keccak_f1600_state_permute32bi_bmi2,
.absorb = keccak_absorb_lanes32bi_bmi2,
- .extract_inplace = keccak_extract_inplace32bi_bmi2,
+ .extract = keccak_extract32bi_bmi2,
};
#endif /* USE_32BIT */
@@ -638,21 +653,35 @@ keccak_init (int algo, void *context, unsigned int flags)
switch (algo)
{
case GCRY_MD_SHA3_224:
+ ctx->suffix = SHA3_DELIMITED_SUFFIX;
ctx->blocksize = 1152 / 8;
ctx->outlen = 224 / 8;
break;
case GCRY_MD_SHA3_256:
+ ctx->suffix = SHA3_DELIMITED_SUFFIX;
ctx->blocksize = 1088 / 8;
ctx->outlen = 256 / 8;
break;
case GCRY_MD_SHA3_384:
+ ctx->suffix = SHA3_DELIMITED_SUFFIX;
ctx->blocksize = 832 / 8;
ctx->outlen = 384 / 8;
break;
case GCRY_MD_SHA3_512:
+ ctx->suffix = SHA3_DELIMITED_SUFFIX;
ctx->blocksize = 576 / 8;
ctx->outlen = 512 / 8;
break;
+ case GCRY_MD_SHAKE128:
+ ctx->suffix = SHAKE_DELIMITED_SUFFIX;
+ ctx->blocksize = 1344 / 8;
+ ctx->outlen = 0;
+ break;
+ case GCRY_MD_SHAKE256:
+ ctx->suffix = SHAKE_DELIMITED_SUFFIX;
+ ctx->blocksize = 1088 / 8;
+ ctx->outlen = 0;
+ break;
default:
BUG();
}
@@ -682,6 +711,17 @@ sha3_512_init (void *context, unsigned int flags)
keccak_init (GCRY_MD_SHA3_512, context, flags);
}
+static void
+shake128_init (void *context, unsigned int flags)
+{
+ keccak_init (GCRY_MD_SHAKE128, context, flags);
+}
+
+static void
+shake256_init (void *context, unsigned int flags)
+{
+ keccak_init (GCRY_MD_SHAKE256, context, flags);
+}
/* The routine final terminates the computation and
* returns the digest.
@@ -696,7 +736,7 @@ keccak_final (void *context)
KECCAK_CONTEXT *ctx = context;
KECCAK_STATE *hd = &ctx->state;
const size_t bsize = ctx->blocksize;
- const byte suffix = SHA3_DELIMITED_SUFFIX;
+ const byte suffix = ctx->suffix;
unsigned int nburn, burn = 0;
unsigned int lastbytes;
byte lane[8];
@@ -716,21 +756,21 @@ keccak_final (void *context)
nburn = ctx->ops->absorb(&ctx->state, (bsize - 1) / 8, lane, 1, -1);
burn = nburn > burn ? nburn : burn;
- /* Switch to the squeezing phase. */
- nburn = ctx->ops->permute(hd);
- burn = nburn > burn ? nburn : burn;
-
- /* Squeeze out all the output blocks */
- if (ctx->outlen < bsize)
+ if (suffix == SHA3_DELIMITED_SUFFIX)
{
- /* Output SHA3 digest. */
- nburn = ctx->ops->extract_inplace(hd, ctx->outlen);
+ /* Switch to the squeezing phase. */
+ nburn = ctx->ops->permute(hd);
+ burn = nburn > burn ? nburn : burn;
+
+ /* Squeeze out the SHA3 digest. */
+ nburn = ctx->ops->extract(hd, 0, (void *)hd, ctx->outlen);
burn = nburn > burn ? nburn : burn;
}
else
{
- /* Output SHAKE digest. */
- BUG();
+ /* Output for SHAKE can now be read with md_extract(). */
+
+ ctx->count = 0;
}
wipememory(lane, sizeof(lane));
@@ -748,6 +788,124 @@ keccak_read (void *context)
}
+static void
+keccak_extract (void *context, void *out, size_t outlen)
+{
+ KECCAK_CONTEXT *ctx = context;
+ KECCAK_STATE *hd = &ctx->state;
+ const size_t bsize = ctx->blocksize;
+ unsigned int nburn, burn = 0;
+ byte *outbuf = out;
+ unsigned int nlanes;
+ unsigned int nleft;
+ unsigned int count;
+ unsigned int i;
+ byte lane[8];
+
+ count = ctx->count;
+
+ while (count && outlen && (outlen < 8 || count % 8))
+ {
+ /* Extract partial lane. */
+ nburn = ctx->ops->extract(hd, count / 8, lane, 8);
+ burn = nburn > burn ? nburn : burn;
+
+ for (i = count % 8; outlen && i < 8; i++)
+ {
+ *outbuf++ = lane[i];
+ outlen--;
+ count++;
+ }
+
+ gcry_assert(count <= bsize);
+
+ if (count == bsize)
+ count = 0;
+ }
+
+ if (outlen >= 8 && count)
+ {
+ /* Extract tail of partial block. */
+ nlanes = outlen / 8;
+ nleft = (bsize - count) / 8;
+ nlanes = nlanes < nleft ? nlanes : nleft;
+
+ nburn = ctx->ops->extract(hd, count / 8, outbuf, nlanes * 8);
+ burn = nburn > burn ? nburn : burn;
+ outlen -= nlanes * 8;
+ outbuf += nlanes * 8;
+ count += nlanes * 8;
+
+ gcry_assert(count <= bsize);
+
+ if (count == bsize)
+ count = 0;
+ }
+
+ while (outlen >= bsize)
+ {
+ gcry_assert(count == 0);
+
+ /* Squeeze more. */
+ nburn = ctx->ops->permute(hd);
+ burn = nburn > burn ? nburn : burn;
+
+ /* Extract full block. */
+ nburn = ctx->ops->extract(hd, 0, outbuf, bsize);
+ burn = nburn > burn ? nburn : burn;
+
+ outlen -= bsize;
+ outbuf += bsize;
+ }
+
+ if (outlen)
+ {
+ gcry_assert(outlen < bsize);
+
+ if (count == 0)
+ {
+ /* Squeeze more. */
+ nburn = ctx->ops->permute(hd);
+ burn = nburn > burn ? nburn : burn;
+ }
+
+ if (outlen >= 8)
+ {
+ /* Extract head of partial block. */
+ nlanes = outlen / 8;
+ nburn = ctx->ops->extract(hd, count / 8, outbuf, nlanes * 8);
+ burn = nburn > burn ? nburn : burn;
+ outlen -= nlanes * 8;
+ outbuf += nlanes * 8;
+ count += nlanes * 8;
+
+ gcry_assert(count < bsize);
+ }
+
+ if (outlen)
+ {
+ /* Extract head of partial lane. */
+ nburn = ctx->ops->extract(hd, count / 8, lane, 8);
+ burn = nburn > burn ? nburn : burn;
+
+ for (i = count % 8; outlen && i < 8; i++)
+ {
+ *outbuf++ = lane[i];
+ outlen--;
+ count++;
+ }
+
+ gcry_assert(count < bsize);
+ }
+ }
+
+ ctx->count = count;
+
+ if (burn)
+ _gcry_burn_stack (burn);
+}
+
+
/*
Self-test section.
@@ -829,6 +987,32 @@ selftests_keccak (int algo, int extended, selftest_report_func_t report)
"\xa8\xaa\x18\xac\xe8\x28\x2a\x0e\x0d\xb5\x96\xc9\x0b\x0a\x7b\x87";
hash_len = 64;
break;
+
+ case GCRY_MD_SHAKE128:
+ short_hash =
+ "\x58\x81\x09\x2d\xd8\x18\xbf\x5c\xf8\xa3\xdd\xb7\x93\xfb\xcb\xa7"
+ "\x40\x97\xd5\xc5\x26\xa6\xd3\x5f\x97\xb8\x33\x51\x94\x0f\x2c\xc8";
+ long_hash =
+ "\x7b\x6d\xf6\xff\x18\x11\x73\xb6\xd7\x89\x8d\x7f\xf6\x3f\xb0\x7b"
+ "\x7c\x23\x7d\xaf\x47\x1a\x5a\xe5\x60\x2a\xdb\xcc\xef\x9c\xcf\x4b";
+ one_million_a_hash =
+ "\x9d\x22\x2c\x79\xc4\xff\x9d\x09\x2c\xf6\xca\x86\x14\x3a\xa4\x11"
+ "\xe3\x69\x97\x38\x08\xef\x97\x09\x32\x55\x82\x6c\x55\x72\xef\x58";
+ hash_len = 32;
+ break;
+
+ case GCRY_MD_SHAKE256:
+ short_hash =
+ "\x48\x33\x66\x60\x13\x60\xa8\x77\x1c\x68\x63\x08\x0c\xc4\x11\x4d"
+ "\x8d\xb4\x45\x30\xf8\xf1\xe1\xee\x4f\x94\xea\x37\xe7\x8b\x57\x39";
+ long_hash =
+ "\x98\xbe\x04\x51\x6c\x04\xcc\x73\x59\x3f\xef\x3e\xd0\x35\x2e\xa9"
+ "\xf6\x44\x39\x42\xd6\x95\x0e\x29\xa3\x72\xa6\x81\xc3\xde\xaf\x45";
+ one_million_a_hash =
+ "\x35\x78\xa7\xa4\xca\x91\x37\x56\x9c\xdf\x76\xed\x61\x7d\x31\xbb"
+ "\x99\x4f\xca\x9c\x1b\xbf\x8b\x18\x40\x13\xde\x82\x34\xdf\xd1\x3a";
+ hash_len = 32;
+ break;
}
what = "short string";
@@ -876,6 +1060,8 @@ run_selftests (int algo, int extended, selftest_report_func_t report)
case GCRY_MD_SHA3_256:
case GCRY_MD_SHA3_384:
case GCRY_MD_SHA3_512:
+ case GCRY_MD_SHAKE128:
+ case GCRY_MD_SHAKE256:
ec = selftests_keccak (algo, extended, report);
break;
default:
@@ -921,7 +1107,22 @@ static gcry_md_oid_spec_t oid_spec_sha3_512[] =
{ "?" },
{ NULL }
};
-
+static byte shake128_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_shake128[] =
+ {
+ { "2.16.840.1.101.3.4.2.11" },
+ /* PKCS#1 shake128WithRSAEncryption */
+ { "?" },
+ { NULL }
+ };
+static byte shake256_asn[] = { 0x30 };
+static gcry_md_oid_spec_t oid_spec_shake256[] =
+ {
+ { "2.16.840.1.101.3.4.2.12" },
+ /* PKCS#1 shake256WithRSAEncryption */
+ { "?" },
+ { NULL }
+ };
gcry_md_spec_t _gcry_digest_spec_sha3_224 =
{
@@ -955,3 +1156,19 @@ gcry_md_spec_t _gcry_digest_spec_sha3_512 =
sizeof (KECCAK_CONTEXT),
run_selftests
};
+gcry_md_spec_t _gcry_digest_spec_shake128 =
+ {
+ GCRY_MD_SHAKE128, {0, 1},
+ "SHAKE128", shake128_asn, DIM (shake128_asn), oid_spec_shake128, 0,
+ shake128_init, keccak_write, keccak_final, NULL, keccak_extract,
+ sizeof (KECCAK_CONTEXT),
+ run_selftests
+ };
+gcry_md_spec_t _gcry_digest_spec_shake256 =
+ {
+ GCRY_MD_SHAKE256, {0, 1},
+ "SHAKE256", shake256_asn, DIM (shake256_asn), oid_spec_shake256, 0,
+ shake256_init, keccak_write, keccak_final, NULL, keccak_extract,
+ sizeof (KECCAK_CONTEXT),
+ run_selftests
+ };
diff --git a/cipher/md.c b/cipher/md.c
index 6ef8fee..15d944d 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -56,6 +56,8 @@ static gcry_md_spec_t *digest_list[] =
&_gcry_digest_spec_sha3_256,
&_gcry_digest_spec_sha3_384,
&_gcry_digest_spec_sha3_512,
+ &_gcry_digest_spec_shake128,
+ &_gcry_digest_spec_shake256,
#endif
#ifdef USE_GOST_R_3411_94
&_gcry_digest_spec_gost3411_94,
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index facdf65..cdb7644 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -3037,7 +3037,7 @@ are also supported.
@c begin table of hash algorithms
@cindex SHA-1
@cindex SHA-224, SHA-256, SHA-384, SHA-512
- at cindex SHA3-224, SHA3-256, SHA3-384, SHA3-512
+ at cindex SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE256
@cindex RIPE-MD-160
@cindex MD2, MD4, MD5
@cindex TIGER, TIGER1, TIGER2
@@ -3126,6 +3126,16 @@ See FIPS 202 for the specification.
This is the SHA3-384 algorithm which yields a message digest of 64 bytes.
See FIPS 202 for the specification.
+ at item GCRY_MD_SHAKE128
+This is the SHAKE128 extendable-output function (XOF) algorithm with 128 bit
+security strength.
+See FIPS 202 for the specification.
+
+ at item GCRY_MD_SHAKE256
+This is the SHAKE256 extendable-output function (XOF) algorithm with 256 bit
+security strength.
+See FIPS 202 for the specification.
+
@item GCRY_MD_CRC32
This is the ISO 3309 and ITU-T V.42 cyclic redundancy check. It yields
an output of 4 bytes. Note that this is not a hash algorithm in the
diff --git a/src/cipher.h b/src/cipher.h
index d96fdb9..c4b306a 100644
--- a/src/cipher.h
+++ b/src/cipher.h
@@ -295,6 +295,8 @@ extern gcry_md_spec_t _gcry_digest_spec_sha3_224;
extern gcry_md_spec_t _gcry_digest_spec_sha3_256;
extern gcry_md_spec_t _gcry_digest_spec_sha3_512;
extern gcry_md_spec_t _gcry_digest_spec_sha3_384;
+extern gcry_md_spec_t _gcry_digest_spec_shake128;
+extern gcry_md_spec_t _gcry_digest_spec_shake256;
extern gcry_md_spec_t _gcry_digest_spec_tiger;
extern gcry_md_spec_t _gcry_digest_spec_tiger1;
extern gcry_md_spec_t _gcry_digest_spec_tiger2;
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index 39be37a..5ddeee3 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -1174,7 +1174,9 @@ enum gcry_md_algos
GCRY_MD_SHA3_224 = 312,
GCRY_MD_SHA3_256 = 313,
GCRY_MD_SHA3_384 = 314,
- GCRY_MD_SHA3_512 = 315
+ GCRY_MD_SHA3_512 = 315,
+ GCRY_MD_SHAKE128 = 316,
+ GCRY_MD_SHAKE256 = 317
};
/* Flags used with the open function. */
diff --git a/tests/basic.c b/tests/basic.c
index 75ff349..0762a89 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -5265,13 +5265,15 @@ check_cipher_modes(void)
fprintf (stderr, "Completed Cipher Mode checks.\n");
}
+
static void
-check_one_md (int algo, const char *data, int len, const char *expect)
+check_one_md (int algo, const char *data, int len, const char *expect, int elen)
{
gcry_md_hd_t hd, hd2;
unsigned char *p;
int mdlen;
int i;
+ int xof = 0;
gcry_error_t err = 0;
err = gcry_md_open (&hd, algo, 0);
@@ -5284,8 +5286,15 @@ check_one_md (int algo, const char *data, int len, const char *expect)
mdlen = gcry_md_get_algo_dlen (algo);
if (mdlen < 1 || mdlen > 500)
{
- fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen);
- return;
+ if (mdlen == 0 && (algo == GCRY_MD_SHAKE128 || algo == GCRY_MD_SHAKE256))
+ {
+ xof = 1;
+ }
+ else
+ {
+ fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen);
+ return;
+ }
}
if (*data == '!' && !data[1])
@@ -5326,19 +5335,168 @@ check_one_md (int algo, const char *data, int len, const char *expect)
gcry_md_close (hd);
- p = gcry_md_read (hd2, algo);
+ if (!xof)
+ {
+ p = gcry_md_read (hd2, algo);
- if (memcmp (p, expect, mdlen))
+ if (memcmp (p, expect, mdlen))
+ {
+ printf ("computed: ");
+ for (i = 0; i < mdlen; i++)
+ printf ("%02x ", p[i] & 0xFF);
+ printf ("\nexpected: ");
+ for (i = 0; i < mdlen; i++)
+ printf ("%02x ", expect[i] & 0xFF);
+ printf ("\n");
+
+ fail ("algo %d, digest mismatch\n", algo);
+ }
+
+ }
+ else
{
- printf ("computed: ");
- for (i = 0; i < mdlen; i++)
- printf ("%02x ", p[i] & 0xFF);
- printf ("\nexpected: ");
- for (i = 0; i < mdlen; i++)
- printf ("%02x ", expect[i] & 0xFF);
- printf ("\n");
+ char buf[1000];
+ int outmax = sizeof(buf) > elen ? elen : sizeof(buf);
- fail ("algo %d, digest mismatch\n", algo);
+ err = gcry_md_copy (&hd, hd2);
+ if (err)
+ {
+ fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err));
+ }
+
+ err = gcry_md_extract(hd2, algo, buf, outmax);
+ if (err)
+ {
+ fail ("algo %d, gcry_md_extract failed: %s\n", algo, gpg_strerror (err));
+ }
+
+ if (memcmp (buf, expect, outmax))
+ {
+ printf ("computed: ");
+ for (i = 0; i < outmax; i++)
+ printf ("%02x ", buf[i] & 0xFF);
+ printf ("\nexpected: ");
+ for (i = 0; i < outmax; i++)
+ printf ("%02x ", expect[i] & 0xFF);
+ printf ("\n");
+
+ fail ("algo %d, digest mismatch\n", algo);
+ }
+
+ memset(buf, 0, sizeof(buf));
+
+ /* Extract one byte at time. */
+ for (i = 0; i < outmax && !err; i++)
+ err = gcry_md_extract(hd, algo, &buf[i], 1);
+ if (err)
+ {
+ fail ("algo %d, gcry_md_extract failed: %s\n", algo, gpg_strerror (err));
+ }
+
+ if (memcmp (buf, expect, outmax))
+ {
+ printf ("computed: ");
+ for (i = 0; i < outmax; i++)
+ printf ("%02x ", buf[i] & 0xFF);
+ printf ("\nexpected: ");
+ for (i = 0; i < outmax; i++)
+ printf ("%02x ", expect[i] & 0xFF);
+ printf ("\n");
+
+ fail ("algo %d, digest mismatch\n", algo);
+ }
+
+ if (*data == '!' && !data[1])
+ {
+ int crcalgo = GCRY_MD_RMD160;
+ gcry_md_hd_t crc1, crc2;
+ size_t startlen;
+ size_t piecelen;
+ size_t left;
+ const unsigned char *p1, *p2;
+ int crclen;
+
+ crclen = gcry_md_get_algo_dlen (crcalgo);
+
+ err = gcry_md_open (&crc1, crcalgo, 0);
+ if (err)
+ {
+ fail ("algo %d, crcalgo: %d, gcry_md_open failed: %s\n", algo,
+ crcalgo, gpg_strerror (err));
+ return;
+ }
+
+ err = gcry_md_open (&crc2, crcalgo, 0);
+ if (err)
+ {
+ fail ("algo %d, crcalgo: %d, gcry_md_open failed: %s\n", algo,
+ crcalgo, gpg_strerror (err));
+ return;
+ }
+
+ /* Extract large chucks, total 1000000 additional bytes. */
+ for (i = 0; i < 1000; i++)
+ {
+ err = gcry_md_extract(hd, algo, buf, 1000);
+ if (!err)
+ gcry_md_write(crc1, buf, 1000);
+ }
+ if (err)
+ {
+ fail ("algo %d, gcry_md_extract failed: %s\n", algo,
+ gpg_strerror (err));
+ }
+
+ /* Extract in odd size chunks, total 1000000 additional bytes. */
+ left = 1000 * 1000;
+ startlen = 1;
+ piecelen = startlen;
+
+ while (!err && left > 0)
+ {
+ if (piecelen > sizeof(buf))
+ piecelen = sizeof(buf);
+ if (piecelen > left)
+ piecelen = left;
+
+ err = gcry_md_extract (hd2, algo, buf, piecelen);
+ if (!err)
+ gcry_md_write(crc2, buf, piecelen);
+ if (err)
+ {
+ fail ("algo %d, gcry_md_extract failed: %s\n", algo,
+ gpg_strerror (err));
+ }
+
+ left -= piecelen;
+
+ if (piecelen == sizeof(buf))
+ piecelen = ++startlen;
+ else
+ piecelen = piecelen * 2 - ((piecelen != startlen) ? startlen : 0);
+ }
+
+ p1 = gcry_md_read (crc1, crcalgo);
+ p2 = gcry_md_read (crc2, crcalgo);
+
+ if (memcmp (p1, p2, crclen))
+ {
+ printf ("computed: ");
+ for (i = 0; i < crclen; i++)
+ printf ("%02x ", p2[i] & 0xFF);
+ printf ("\nexpected: ");
+ for (i = 0; i < crclen; i++)
+ printf ("%02x ", p1[i] & 0xFF);
+ printf ("\n");
+
+ fail ("algo %d, large xof output mismatch\n", algo);
+ }
+
+ gcry_md_close (crc1);
+ gcry_md_close (crc2);
+ }
+
+ gcry_md_close (hd);
}
gcry_md_close (hd2);
@@ -5358,6 +5516,9 @@ check_one_md_multi (int algo, const char *data, int len, const char *expect)
mdlen = gcry_md_get_algo_dlen (algo);
if (mdlen < 1 || mdlen > 64)
{
+ if (mdlen == 0 && (algo == GCRY_MD_SHAKE128 || algo == GCRY_MD_SHAKE256))
+ return;
+
fail ("check_one_md_multi: algo %d, gcry_md_get_algo_dlen failed: %d\n",
algo, mdlen);
return;
@@ -5420,6 +5581,7 @@ check_digests (void)
const char *data;
const char *expect;
int datalen;
+ int expectlen;
} algos[] =
{
{ GCRY_MD_MD2, "",
@@ -5917,7 +6079,238 @@ check_digests (void)
#include "./sha3-256.h"
#include "./sha3-384.h"
#include "./sha3-512.h"
- { 0 }
+ { GCRY_MD_SHAKE128,
+ "",
+ "\x7F\x9C\x2B\xA4\xE8\x8F\x82\x7D\x61\x60\x45\x50\x76\x05\x85\x3E"
+ "\xD7\x3B\x80\x93\xF6\xEF\xBC\x88\xEB\x1A\x6E\xAC\xFA\x66\xEF\x26"
+ "\x3C\xB1\xEE\xA9\x88\x00\x4B\x93\x10\x3C\xFB\x0A\xEE\xFD\x2A\x68"
+ "\x6E\x01\xFA\x4A\x58\xE8\xA3\x63\x9C\xA8\xA1\xE3\xF9\xAE\x57\xE2"
+ "\x35\xB8\xCC\x87\x3C\x23\xDC\x62\xB8\xD2\x60\x16\x9A\xFA\x2F\x75"
+ "\xAB\x91\x6A\x58\xD9\x74\x91\x88\x35\xD2\x5E\x6A\x43\x50\x85\xB2"
+ "\xBA\xDF\xD6\xDF\xAA\xC3\x59\xA5\xEF\xBB\x7B\xCC\x4B\x59\xD5\x38"
+ "\xDF\x9A\x04\x30\x2E\x10\xC8\xBC\x1C\xBF\x1A\x0B\x3A\x51\x20\xEA"
+ "\x17\xCD\xA7\xCF\xAD\x76\x5F\x56\x23\x47\x4D\x36\x8C\xCC\xA8\xAF"
+ "\x00\x07\xCD\x9F\x5E\x4C\x84\x9F\x16\x7A\x58\x0B\x14\xAA\xBD\xEF"
+ "\xAE\xE7\xEE\xF4\x7C\xB0\xFC\xA9\x76\x7B\xE1\xFD\xA6\x94\x19\xDF"
+ "\xB9\x27\xE9\xDF\x07\x34\x8B\x19\x66\x91\xAB\xAE\xB5\x80\xB3\x2D"
+ "\xEF\x58\x53\x8B\x8D\x23\xF8\x77\x32\xEA\x63\xB0\x2B\x4F\xA0\xF4"
+ "\x87\x33\x60\xE2\x84\x19\x28\xCD\x60\xDD\x4C\xEE\x8C\xC0\xD4\xC9"
+ "\x22\xA9\x61\x88\xD0\x32\x67\x5C\x8A\xC8\x50\x93\x3C\x7A\xFF\x15"
+ "\x33\xB9\x4C\x83\x4A\xDB\xB6\x9C\x61\x15\xBA\xD4\x69\x2D\x86\x19"
+ "\xF9\x0B\x0C\xDF\x8A\x7B\x9C\x26\x40\x29\xAC\x18\x5B\x70\xB8\x3F"
+ "\x28\x01\xF2\xF4\xB3\xF7\x0C\x59\x3E\xA3\xAE\xEB\x61\x3A\x7F\x1B"
+ "\x1D\xE3\x3F\xD7\x50\x81\xF5\x92\x30\x5F\x2E\x45\x26\xED\xC0\x96"
+ "\x31\xB1\x09\x58\xF4\x64\xD8\x89\xF3\x1B\xA0\x10\x25\x0F\xDA\x7F"
+ "\x13\x68\xEC\x29\x67\xFC\x84\xEF\x2A\xE9\xAF\xF2\x68\xE0\xB1\x70"
+ "\x0A\xFF\xC6\x82\x0B\x52\x3A\x3D\x91\x71\x35\xF2\xDF\xF2\xEE\x06"
+ "\xBF\xE7\x2B\x31\x24\x72\x1D\x4A\x26\xC0\x4E\x53\xA7\x5E\x30\xE7"
+ "\x3A\x7A\x9C\x4A\x95\xD9\x1C\x55\xD4\x95\xE9\xF5\x1D\xD0\xB5\xE9"
+ "\xD8\x3C\x6D\x5E\x8C\xE8\x03\xAA\x62\xB8\xD6\x54\xDB\x53\xD0\x9B"
+ "\x8D\xCF\xF2\x73\xCD\xFE\xB5\x73\xFA\xD8\xBC\xD4\x55\x78\xBE\xC2"
+ "\xE7\x70\xD0\x1E\xFD\xE8\x6E\x72\x1A\x3F\x7C\x6C\xCE\x27\x5D\xAB"
+ "\xE6\xE2\x14\x3F\x1A\xF1\x8D\xA7\xEF\xDD\xC4\xC7\xB7\x0B\x5E\x34"
+ "\x5D\xB9\x3C\xC9\x36\xBE\xA3\x23\x49\x1C\xCB\x38\xA3\x88\xF5\x46"
+ "\xA9\xFF\x00\xDD\x4E\x13\x00\xB9\xB2\x15\x3D\x20\x41\xD2\x05\xB4"
+ "\x43\xE4\x1B\x45\xA6\x53\xF2\xA5\xC4\x49\x2C\x1A\xDD\x54\x45\x12"
+ "\xDD\xA2\x52\x98\x33\x46\x2B\x71\xA4\x1A\x45\xBE\x97\x29\x0B\x6F",
+ 0, 512, },
+ { GCRY_MD_SHAKE128,
+ "\x5A\xAB\x62\x75\x6D\x30\x7A\x66\x9D\x14\x6A\xBA\x98\x8D\x90\x74"
+ "\xC5\xA1\x59\xB3\xDE\x85\x15\x1A\x81\x9B\x11\x7C\xA1\xFF\x65\x97"
+ "\xF6\x15\x6E\x80\xFD\xD2\x8C\x9C\x31\x76\x83\x51\x64\xD3\x7D\xA7"
+ "\xDA\x11\xD9\x4E\x09\xAD\xD7\x70\xB6\x8A\x6E\x08\x1C\xD2\x2C\xA0"
+ "\xC0\x04\xBF\xE7\xCD\x28\x3B\xF4\x3A\x58\x8D\xA9\x1F\x50\x9B\x27"
+ "\xA6\x58\x4C\x47\x4A\x4A\x2F\x3E\xE0\xF1\xF5\x64\x47\x37\x92\x40"
+ "\xA5\xAB\x1F\xB7\x7F\xDC\xA4\x9B\x30\x5F\x07\xBA\x86\xB6\x27\x56"
+ "\xFB\x9E\xFB\x4F\xC2\x25\xC8\x68\x45\xF0\x26\xEA\x54\x20\x76\xB9"
+ "\x1A\x0B\xC2\xCD\xD1\x36\xE1\x22\xC6\x59\xBE\x25\x9D\x98\xE5\x84"
+ "\x1D\xF4\xC2\xF6\x03\x30\xD4\xD8\xCD\xEE\x7B\xF1\xA0\xA2\x44\x52"
+ "\x4E\xEC\xC6\x8F\xF2\xAE\xF5\xBF\x00\x69\xC9\xE8\x7A\x11\xC6\xE5"
+ "\x19\xDE\x1A\x40\x62\xA1\x0C\x83\x83\x73\x88\xF7\xEF\x58\x59\x8A"
+ "\x38\x46\xF4\x9D\x49\x96\x82\xB6\x83\xC4\xA0\x62\xB4\x21\x59\x4F"
+ "\xAF\xBC\x13\x83\xC9\x43\xBA\x83\xBD\xEF\x51\x5E\xFC\xF1\x0D",
+ "\xF0\x71\x5D\xE3\x56\x92\xFD\x70\x12\x3D\xC6\x83\x68\xD0\xFE\xEC"
+ "\x06\xA0\xC7\x4C\xF8\xAD\xB0\x5D\xDC\x25\x54\x87\xB1\xA8\xD4\xD1"
+ "\x21\x3E\x9E\xAB\xAF\x41\xF1\x16\x17\x19\xD0\x65\xD7\x94\xB7\x50"
+ "\xF8\x4B\xE3\x2A\x32\x34\xB4\xD5\x36\x46\x0D\x55\x20\x68\x8A\x5A"
+ "\x79\xA1\x7A\x4B\xA8\x98\x7F\xCB\x61\xBF\x7D\xAA\x8B\x54\x7B\xF5"
+ "\xC1\xCE\x36\xB5\x6A\x73\x25\x7D\xBB\xF1\xBA\xBB\x64\xF2\x49\xBD"
+ "\xCE\xB6\x7B\xA1\xC8\x88\x37\x0A\x96\x3D\xFD\x6B\x6A\x2A\xDE\x2C"
+ "\xEF\xD1\x4C\x32\x52\xCB\x37\x58\x52\x0F\x0C\x65\xF4\x52\x46\x82"
+ "\x77\x24\x99\x46\x3A\xE1\xA3\x41\x80\x01\x83\xAA\x60\xEF\xA0\x51"
+ "\x18\xA2\x82\x01\x74\x4F\x7B\xA0\xB0\xA3\x92\x8D\xD7\xC0\x26\x3F"
+ "\xD2\x64\xB7\xCD\x7B\x2E\x2E\x09\xB3\x22\xBF\xCE\xA8\xEE\xD0\x42"
+ "\x75\x79\x5B\xE7\xC0\xF0\x0E\x11\x38\x27\x37\x0D\x05\x1D\x50\x26"
+ "\x95\x80\x30\x00\x05\xAC\x12\x88\xFE\xA6\xCD\x9A\xE9\xF4\xF3\x7C"
+ "\xE0\xF8\xAC\xE8\xBF\x3E\xBE\x1D\x70\x56\x25\x59\x54\xC7\x61\x93"
+ "\x1D\x3C\x42\xED\x62\xF7\xF1\xCE\x1B\x94\x5C\xDE\xCC\x0A\x74\x32"
+ "\x2D\x7F\x64\xD6\x00\x4F\xF2\x16\x84\x14\x93\x07\x28\x8B\x44\x8E"
+ "\x45\x43\x34\x75\xB1\xEA\x13\x14\xB0\x0F\x1F\xC4\x50\x08\x9A\x9D"
+ "\x1F\x77\x10\xC6\xD7\x65\x2E\xCF\x65\x4F\x3B\x48\x7D\x02\x83\xD4"
+ "\xD8\xA2\x8E\xFB\x50\x66\xC4\x25\x0D\x5A\xD6\x98\xE1\x5D\xBA\x88"
+ "\xE9\x25\xE4\xDE\x99\xB6\x9B\xC3\x83\xAC\x80\x45\xB7\xF1\x02\x2A"
+ "\xDD\x39\xD4\x43\x54\x6A\xE0\x92\x4F\x13\xF4\x89\x60\x96\xDF\xDF"
+ "\x37\xCA\x72\x20\x79\x87\xC4\xA7\x70\x5A\x7A\xBE\x72\x4B\x7F\xA1"
+ "\x0C\x90\x9F\x39\x25\x44\x9F\x01\x0D\x61\xE2\x07\xAD\xD9\x52\x19"
+ "\x07\x1A\xCE\xED\xB9\xB9\xDC\xED\x32\xA9\xE1\x23\x56\x1D\x60\x82"
+ "\xD4\x6A\xEF\xAE\x07\xEE\x1B\xD1\x32\x76\x5E\x3E\x51\x3C\x66\x50"
+ "\x1B\x38\x7A\xB2\xEE\x09\xA0\x4A\xE6\x3E\x25\x80\x85\x17\xAF\xEA"
+ "\x3E\x05\x11\x69\xCF\xD2\xFF\xF8\xC5\x85\x8E\x2D\x96\x23\x89\x7C"
+ "\x9E\x85\x17\x5A\xC5\xA8\x63\x94\xCD\x0A\x32\xA0\xA6\x2A\x8F\x5D"
+ "\x6C\xCC\xBF\x49\x3D\xAA\x43\xF7\x83\x62\xBB\xCA\x40\xAD\xF7\x33"
+ "\xF8\x71\xE0\xC0\x09\x98\xD9\xBF\xD6\x88\x06\x56\x66\x6C\xD7\xBE"
+ "\x4F\xE9\x89\x2C\x61\xDC\xD5\xCD\x23\xA5\xE4\x27\x7E\xEE\x8B\x4A"
+ "\xFD\x29\xB6\x9B\xBA\x55\x66\x0A\x21\x71\x12\xFF\x6E\x34\x56\xB1",
+ 223, 512, },
+ { GCRY_MD_SHAKE128,
+ "!",
+ "\x9d\x22\x2c\x79\xc4\xff\x9d\x09\x2c\xf6\xca\x86\x14\x3a\xa4\x11"
+ "\xe3\x69\x97\x38\x08\xef\x97\x09\x32\x55\x82\x6c\x55\x72\xef\x58"
+ "\x42\x4c\x4b\x5c\x28\x47\x5f\xfd\xcf\x98\x16\x63\x86\x7f\xec\x63"
+ "\x21\xc1\x26\x2e\x38\x7b\xcc\xf8\xca\x67\x68\x84\xc4\xa9\xd0\xc1"
+ "\x3b\xfa\x68\x69\x76\x3d\x5a\xe4\xbb\xc9\xb3\xcc\xd0\x9d\x1c\xa5"
+ "\xea\x74\x46\x53\x8d\x69\xb3\xfb\x98\xc7\x2b\x59\xa2\xb4\x81\x7d"
+ "\xb5\xea\xdd\x90\x11\xf9\x0f\xa7\x10\x91\x93\x1f\x81\x34\xf4\xf0"
+ "\x0b\x56\x2e\x2f\xe1\x05\x93\x72\x70\x36\x1c\x19\x09\x86\x2a\xd4"
+ "\x50\x46\xe3\x93\x2f\x5d\xd3\x11\xec\x72\xfe\xc5\xf8\xfb\x8f\x60"
+ "\xb4\x5a\x3b\xee\x3f\x85\xbb\xf7\xfc\xed\xc6\xa5\x55\x67\x76\x48"
+ "\xe0\x65\x4b\x38\x19\x41\xa8\x6b\xd3\xe5\x12\x65\x7b\x0d\x57\xa7"
+ "\x99\x1f\xc4\x54\x3f\x89\xd8\x29\x04\x92\x22\x2c\xe4\xa3\x3e\x17"
+ "\x60\x2b\x3b\x99\xc0\x09\xf7\x65\x5f\x87\x53\x5c\xda\xa3\x71\x6f"
+ "\x58\xc4\x7b\x8a\x15\x7a\xd1\x95\xf0\x28\x09\xf2\x75\x00\xb9\x25"
+ "\x49\x79\x31\x1c\x6b\xb4\x15\x96\x8c\xd1\x04\x31\x16\x9a\x27\xd5"
+ "\xa8\xd6\x1e\x13\xa6\xb8\xb7\x7a\xf1\xf8\xb6\xdd\x2e\xef\xde\xa0"
+ "\x40\x78\x96\x80\x49\x0b\x5e\xdc\xb1\xd3\xe5\x38\xa4\x66\xf7\x57"
+ "\xad\x71\x8f\xe1\xfd\x9f\xae\xef\xa4\x72\x46\xad\x5e\x36\x7f\x87"
+ "\xd3\xb4\x85\x0d\x44\x86\xeb\x21\x99\xe9\x4a\x79\x79\xe2\x09\x1a"
+ "\xbc\xdf\x3b\xc1\x33\x79\xc8\x96\xdc\xeb\x79\xa8\xfd\x08\xf1\x10"
+ "\x73\xf3\x3e\x3f\x99\x23\x22\xb3\x12\x02\xde\xe2\x34\x33\x0c\xf3"
+ "\x30\x4a\x58\x8f\x0d\x59\xda\xe4\xe6\x3b\xa2\xac\x3c\xe6\x82\xcc"
+ "\x19\xd4\xe3\x41\x67\x8c\xc3\xa6\x7a\x47\xc1\x13\xb4\xdb\x89\x0f"
+ "\x30\xa9\x2a\xa0\x8a\x1f\x6d\xc8\xfb\x64\x63\xf8\x03\x8c\x2b\x40"
+ "\xb2\x53\x00\x77\xb2\x36\xce\x88\xaf\xcc\xcd\xa0\x8a\xd6\xd7\x5e"
+ "\xee\x18\x99\xb1\x0c\xd8\x00\xc2\xce\x53\x72\xbf\xf2\x2e\xe3\xa3"
+ "\x39\xd4\xb9\xc1\xa2\xf5\xf4\xb8\x20\xf6\x87\xe5\x51\x9b\xd0\x5b"
+ "\x1f\xc5\xda\x0e\xb4\x53\x36\x81\x4f\x48\x13\x2c\x64\x0e\x66\xc3"
+ "\xa0\x2a\x22\xe6\x35\x98\xf9\x4f\x22\xf3\x51\x84\x11\x04\x46\xb6"
+ "\x48\xcf\x84\x74\xf3\x0c\x43\xea\xd5\x83\x09\xfb\x25\x90\x16\x09"
+ "\xe2\x41\x87\xe8\x01\xc8\x09\x56\x1a\x64\x80\x94\x50\xe6\x03\xc4"
+ "\xa8\x03\x95\x25\xc4\x76\xb5\x8e\x32\xce\x2c\x47\xb3\x7d\xa5\x91",
+ 0, 512, },
+ { GCRY_MD_SHAKE256,
+ "",
+ "\x46\xB9\xDD\x2B\x0B\xA8\x8D\x13\x23\x3B\x3F\xEB\x74\x3E\xEB\x24"
+ "\x3F\xCD\x52\xEA\x62\xB8\x1B\x82\xB5\x0C\x27\x64\x6E\xD5\x76\x2F"
+ "\xD7\x5D\xC4\xDD\xD8\xC0\xF2\x00\xCB\x05\x01\x9D\x67\xB5\x92\xF6"
+ "\xFC\x82\x1C\x49\x47\x9A\xB4\x86\x40\x29\x2E\xAC\xB3\xB7\xC4\xBE"
+ "\x14\x1E\x96\x61\x6F\xB1\x39\x57\x69\x2C\xC7\xED\xD0\xB4\x5A\xE3"
+ "\xDC\x07\x22\x3C\x8E\x92\x93\x7B\xEF\x84\xBC\x0E\xAB\x86\x28\x53"
+ "\x34\x9E\xC7\x55\x46\xF5\x8F\xB7\xC2\x77\x5C\x38\x46\x2C\x50\x10"
+ "\xD8\x46\xC1\x85\xC1\x51\x11\xE5\x95\x52\x2A\x6B\xCD\x16\xCF\x86"
+ "\xF3\xD1\x22\x10\x9E\x3B\x1F\xDD\x94\x3B\x6A\xEC\x46\x8A\x2D\x62"
+ "\x1A\x7C\x06\xC6\xA9\x57\xC6\x2B\x54\xDA\xFC\x3B\xE8\x75\x67\xD6"
+ "\x77\x23\x13\x95\xF6\x14\x72\x93\xB6\x8C\xEA\xB7\xA9\xE0\xC5\x8D"
+ "\x86\x4E\x8E\xFD\xE4\xE1\xB9\xA4\x6C\xBE\x85\x47\x13\x67\x2F\x5C"
+ "\xAA\xAE\x31\x4E\xD9\x08\x3D\xAB\x4B\x09\x9F\x8E\x30\x0F\x01\xB8"
+ "\x65\x0F\x1F\x4B\x1D\x8F\xCF\x3F\x3C\xB5\x3F\xB8\xE9\xEB\x2E\xA2"
+ "\x03\xBD\xC9\x70\xF5\x0A\xE5\x54\x28\xA9\x1F\x7F\x53\xAC\x26\x6B"
+ "\x28\x41\x9C\x37\x78\xA1\x5F\xD2\x48\xD3\x39\xED\xE7\x85\xFB\x7F"
+ "\x5A\x1A\xAA\x96\xD3\x13\xEA\xCC\x89\x09\x36\xC1\x73\xCD\xCD\x0F"
+ "\xAB\x88\x2C\x45\x75\x5F\xEB\x3A\xED\x96\xD4\x77\xFF\x96\x39\x0B"
+ "\xF9\xA6\x6D\x13\x68\xB2\x08\xE2\x1F\x7C\x10\xD0\x4A\x3D\xBD\x4E"
+ "\x36\x06\x33\xE5\xDB\x4B\x60\x26\x01\xC1\x4C\xEA\x73\x7D\xB3\xDC"
+ "\xF7\x22\x63\x2C\xC7\x78\x51\xCB\xDD\xE2\xAA\xF0\xA3\x3A\x07\xB3"
+ "\x73\x44\x5D\xF4\x90\xCC\x8F\xC1\xE4\x16\x0F\xF1\x18\x37\x8F\x11"
+ "\xF0\x47\x7D\xE0\x55\xA8\x1A\x9E\xDA\x57\xA4\xA2\xCF\xB0\xC8\x39"
+ "\x29\xD3\x10\x91\x2F\x72\x9E\xC6\xCF\xA3\x6C\x6A\xC6\xA7\x58\x37"
+ "\x14\x30\x45\xD7\x91\xCC\x85\xEF\xF5\xB2\x19\x32\xF2\x38\x61\xBC"
+ "\xF2\x3A\x52\xB5\xDA\x67\xEA\xF7\xBA\xAE\x0F\x5F\xB1\x36\x9D\xB7"
+ "\x8F\x3A\xC4\x5F\x8C\x4A\xC5\x67\x1D\x85\x73\x5C\xDD\xDB\x09\xD2"
+ "\xB1\xE3\x4A\x1F\xC0\x66\xFF\x4A\x16\x2C\xB2\x63\xD6\x54\x12\x74"
+ "\xAE\x2F\xCC\x86\x5F\x61\x8A\xBE\x27\xC1\x24\xCD\x8B\x07\x4C\xCD"
+ "\x51\x63\x01\xB9\x18\x75\x82\x4D\x09\x95\x8F\x34\x1E\xF2\x74\xBD"
+ "\xAB\x0B\xAE\x31\x63\x39\x89\x43\x04\xE3\x58\x77\xB0\xC2\x8A\x9B"
+ "\x1F\xD1\x66\xC7\x96\xB9\xCC\x25\x8A\x06\x4A\x8F\x57\xE2\x7F\x2A",
+ 0, 512, },
+ { GCRY_MD_SHAKE256,
+ "\xB3\x2D\x95\xB0\xB9\xAA\xD2\xA8\x81\x6D\xE6\xD0\x6D\x1F\x86\x00"
+ "\x85\x05\xBD\x8C\x14\x12\x4F\x6E\x9A\x16\x3B\x5A\x2A\xDE\x55\xF8"
+ "\x35\xD0\xEC\x38\x80\xEF\x50\x70\x0D\x3B\x25\xE4\x2C\xC0\xAF\x05"
+ "\x0C\xCD\x1B\xE5\xE5\x55\xB2\x30\x87\xE0\x4D\x7B\xF9\x81\x36\x22"
+ "\x78\x0C\x73\x13\xA1\x95\x4F\x87\x40\xB6\xEE\x2D\x3F\x71\xF7\x68"
+ "\xDD\x41\x7F\x52\x04\x82\xBD\x3A\x08\xD4\xF2\x22\xB4\xEE\x9D\xBD"
+ "\x01\x54\x47\xB3\x35\x07\xDD\x50\xF3\xAB\x42\x47\xC5\xDE\x9A\x8A"
+ "\xBD\x62\xA8\xDE\xCE\xA0\x1E\x3B\x87\xC8\xB9\x27\xF5\xB0\x8B\xEB"
+ "\x37\x67\x4C\x6F\x8E\x38\x0C\x04",
+ "\xCC\x2E\xAA\x04\xEE\xF8\x47\x9C\xDA\xE8\x56\x6E\xB8\xFF\xA1\x10"
+ "\x0A\x40\x79\x95\xBF\x99\x9A\xE9\x7E\xDE\x52\x66\x81\xDC\x34\x90"
+ "\x61\x6F\x28\x44\x2D\x20\xDA\x92\x12\x4C\xE0\x81\x58\x8B\x81\x49"
+ "\x1A\xED\xF6\x5C\xAA\xF0\xD2\x7E\x82\xA4\xB0\xE1\xD1\xCA\xB2\x38"
+ "\x33\x32\x8F\x1B\x8D\xA4\x30\xC8\xA0\x87\x66\xA8\x63\x70\xFA\x84"
+ "\x8A\x79\xB5\x99\x8D\xB3\xCF\xFD\x05\x7B\x96\xE1\xE2\xEE\x0E\xF2"
+ "\x29\xEC\xA1\x33\xC1\x55\x48\xF9\x83\x99\x02\x04\x37\x30\xE4\x4B"
+ "\xC5\x2C\x39\xFA\xDC\x1D\xDE\xEA\xD9\x5F\x99\x39\xF2\x20\xCA\x30"
+ "\x06\x61\x54\x0D\xF7\xED\xD9\xAF\x37\x8A\x5D\x4A\x19\xB2\xB9\x3E"
+ "\x6C\x78\xF4\x9C\x35\x33\x43\xA0\xB5\xF1\x19\x13\x2B\x53\x12\xD0"
+ "\x04\x83\x1D\x01\x76\x9A\x31\x6D\x2F\x51\xBF\x64\xCC\xB2\x0A\x21"
+ "\xC2\xCF\x7A\xC8\xFB\x6F\x6E\x90\x70\x61\x26\xBD\xAE\x06\x11\xDD"
+ "\x13\x96\x2E\x8B\x53\xD6\xEA\xE2\x6C\x7B\x0D\x25\x51\xDA\xF6\x24"
+ "\x8E\x9D\x65\x81\x73\x82\xB0\x4D\x23\x39\x2D\x10\x8E\x4D\x34\x43"
+ "\xDE\x5A\xDC\x72\x73\xC7\x21\xA8\xF8\x32\x0E\xCF\xE8\x17\x7A\xC0"
+ "\x67\xCA\x8A\x50\x16\x9A\x6E\x73\x00\x0E\xBC\xDC\x1E\x4E\xE6\x33"
+ "\x9F\xC8\x67\xC3\xD7\xAE\xAB\x84\x14\x63\x98\xD7\xBA\xDE\x12\x1D"
+ "\x19\x89\xFA\x45\x73\x35\x56\x4E\x97\x57\x70\xA3\xA0\x02\x59\xCA"
+ "\x08\x70\x61\x08\x26\x1A\xA2\xD3\x4D\xE0\x0F\x8C\xAC\x7D\x45\xD3"
+ "\x5E\x5A\xA6\x3E\xA6\x9E\x1D\x1A\x2F\x7D\xAB\x39\x00\xD5\x1E\x0B"
+ "\xC6\x53\x48\xA2\x55\x54\x00\x70\x39\xA5\x2C\x3C\x30\x99\x80\xD1"
+ "\x7C\xAD\x20\xF1\x15\x63\x10\xA3\x9C\xD3\x93\x76\x0C\xFE\x58\xF6"
+ "\xF8\xAD\xE4\x21\x31\x28\x82\x80\xA3\x5E\x1D\xB8\x70\x81\x83\xB9"
+ "\x1C\xFA\xF5\x82\x7E\x96\xB0\xF7\x74\xC4\x50\x93\xB4\x17\xAF\xF9"
+ "\xDD\x64\x17\xE5\x99\x64\xA0\x1B\xD2\xA6\x12\xFF\xCF\xBA\x18\xA0"
+ "\xF1\x93\xDB\x29\x7B\x9A\x6C\xC1\xD2\x70\xD9\x7A\xAE\x8F\x8A\x3A"
+ "\x6B\x26\x69\x5A\xB6\x64\x31\xC2\x02\xE1\x39\xD6\x3D\xD3\xA2\x47"
+ "\x78\x67\x6C\xEF\xE3\xE2\x1B\x02\xEC\x4E\x8F\x5C\xFD\x66\x58\x7A"
+ "\x12\xB4\x40\x78\xFC\xD3\x9E\xEE\x44\xBB\xEF\x4A\x94\x9A\x63\xC0"
+ "\xDF\xD5\x8C\xF2\xFB\x2C\xD5\xF0\x02\xE2\xB0\x21\x92\x66\xCF\xC0"
+ "\x31\x81\x74\x86\xDE\x70\xB4\x28\x5A\x8A\x70\xF3\xD3\x8A\x61\xD3"
+ "\x15\x5D\x99\xAA\xF4\xC2\x53\x90\xD7\x36\x45\xAB\x3E\x8D\x80\xF0",
+ 136, 512, },
+ { GCRY_MD_SHAKE256,
+ "!",
+ "\x35\x78\xa7\xa4\xca\x91\x37\x56\x9c\xdf\x76\xed\x61\x7d\x31\xbb"
+ "\x99\x4f\xca\x9c\x1b\xbf\x8b\x18\x40\x13\xde\x82\x34\xdf\xd1\x3a"
+ "\x3f\xd1\x24\xd4\xdf\x76\xc0\xa5\x39\xee\x7d\xd2\xf6\xe1\xec\x34"
+ "\x61\x24\xc8\x15\xd9\x41\x0e\x14\x5e\xb5\x61\xbc\xd9\x7b\x18\xab"
+ "\x6c\xe8\xd5\x55\x3e\x0e\xab\x3d\x1f\x7d\xfb\x8f\x9d\xee\xfe\x16"
+ "\x84\x7e\x21\x92\xf6\xf6\x1f\xb8\x2f\xb9\x0d\xde\x60\xb1\x90\x63"
+ "\xc5\x6a\x4c\x55\xcd\xd7\xb6\x72\xb7\x5b\xf5\x15\xad\xbf\xe2\x04"
+ "\x90\x3c\x8c\x00\x36\xde\x54\xa2\x99\x9a\x92\x0d\xe9\x0f\x66\xd7"
+ "\xff\x6e\xc8\xe4\xc9\x3d\x24\xae\x34\x6f\xdc\xb3\xa5\xa5\xbd\x57"
+ "\x39\xec\x15\xa6\xed\xdb\x5c\xe5\xb0\x2d\xa5\x30\x39\xfa\xc6\x3e"
+ "\x19\x55\x5f\xaa\x2e\xdd\xc6\x93\xb1\xf0\xc2\xa6\xfc\xbe\x7c\x0a"
+ "\x0a\x09\x1d\x0e\xe7\x00\xd7\x32\x2e\x4b\x0f\xf0\x95\x90\xde\x16"
+ "\x64\x22\xf9\xea\xd5\xda\x4c\x99\x3d\x60\x5f\xe4\xd9\xc6\x34\x84"
+ "\x3a\xa1\x78\xb1\x76\x72\xc6\x56\x8c\x8a\x2e\x62\xab\xeb\xea\x2c"
+ "\x21\xc3\x02\xbd\x36\x6a\xd6\x98\x95\x9e\x1f\x6e\x43\x4a\xf1\x55"
+ "\x56\x8b\x27\x34\xd8\x37\x9f\xcd\x3f\xfe\x64\x89\xba\xff\xa6\xd7"
+ "\x11\x09\x44\x2e\x1b\x34\x4f\x13\x8a\x09\xca\xe3\xe2\xd3\x94\x2e"
+ "\xee\x82\x8f\xc4\x7e\x64\xde\xb5\xe0\x0a\x02\x4a\xe1\xf2\xc0\x77"
+ "\xe6\xb7\xb1\x33\xf6\xc1\xde\x91\x30\x92\xd4\xe8\x29\xec\xd2\xb2"
+ "\xef\x28\xca\x80\x20\x82\x1e\x2b\x8b\xe5\x17\xd9\x3e\xd0\x88\x36"
+ "\xf6\xf0\x66\xcc\x3d\x03\xb6\x25\xd8\x49\x7f\x29\xdb\xc1\xc3\x9e"
+ "\x6f\xe4\x63\x22\x6f\x85\xc1\x28\xa2\xc2\x98\x88\x11\x2e\x06\xa9"
+ "\x9c\x5d\x17\xb2\x5e\x90\x0d\x20\x4f\x39\x72\x31\xcd\xf7\x9c\x31"
+ "\x34\x46\x53\x2d\xad\x07\xf4\xc0\xbd\x9f\xba\x1d\xd4\x13\xd8\xa7"
+ "\xe6\xcb\xc0\xa0\x86\x2c\xc7\x69\x23\x9a\x89\xf9\xdb\x08\x5b\x78"
+ "\xa0\x54\x59\x6a\xd7\x08\x0d\xdf\x96\x01\x9b\x73\x99\xb5\x03\x48"
+ "\x0e\x5a\x65\xa2\x20\x8d\x74\x72\x4c\x98\x7d\x32\x5e\x9b\x0e\x82"
+ "\xfe\xcd\x4f\x27\xf3\x13\x5b\x1d\x9e\x27\xb4\x8e\x69\xdd\x6f\x59"
+ "\x62\xb8\xa6\x3b\x48\x92\x1e\xc8\xee\x53\x86\x9f\x1a\xc1\xc8\x18"
+ "\x23\x87\xee\x0d\x6c\xfe\xf6\x53\xff\x8b\xf6\x05\xf1\x47\x04\xb7"
+ "\x1b\xeb\x65\x53\xf2\x81\xfa\x75\x69\x48\xc4\x38\x49\x4b\x19\xb4"
+ "\xee\x69\xa5\x43\x6b\x22\x2b\xc9\x88\xed\xa4\xac\x60\x00\x24\xc9",
+ 0, 512, },
+ { 0 }
};
gcry_error_t err;
int i;
@@ -5950,7 +6343,7 @@ check_digests (void)
check_one_md (algos[i].md, algos[i].data,
algos[i].datalen > 0 ? algos[i].datalen
: strlen (algos[i].data),
- algos[i].expect);
+ algos[i].expect, algos[i].expectlen);
check_one_md_multi (algos[i].md, algos[i].data,
algos[i].datalen > 0 ? algos[i].datalen
: strlen (algos[i].data),
diff --git a/tests/bench-slope.c b/tests/bench-slope.c
index 2679556..3a2aa38 100644
--- a/tests/bench-slope.c
+++ b/tests/bench-slope.c
@@ -1651,6 +1651,12 @@ kdf_bench_one (int algo, int subalgo)
return;
}
+ if (gcry_md_get_algo_dlen (subalgo) == 0)
+ {
+ /* Skip XOFs */
+ return;
+ }
+
*algo_name = 0;
if (algo == GCRY_KDF_PBKDF2)
More information about the Gcrypt-devel
mailing list