Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion doc/crypt.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3047,10 +3047,20 @@ \subsection{SHA3 SHAKE}
int sha3_shake_init(hash_state *md, int num);
int sha3_shake_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen);

int sha3_shake128_init(hash_state *md);
int sha3_shake128_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int sha3_shake128_done(hash_state *md, unsigned char *out);

int sha3_shake256_init(hash_state *md);
int sha3_shake256_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int sha3_shake256_done(hash_state *md, unsigned char *out);
\end{verbatim}
\end{small}

The process function \code{sha3\_shake\_process()} is implemented as a macro which calls \code{sha3\_process()}.
The process functions \code{sha3\_shake\_process()}, \code{sha3\_shake128\_process()} and \code{sha3\_shake256\_process()}
are implemented as macros which call \code{sha3\_process()}. The new \code{shake128\_desc} and \code{shake256\_desc}
hash descriptors provide fixed-size outputs of 32 and 64 octets respectively, using the SHAKE digest lengths defined by RFC 8702.

For further information see \url{https://en.wikipedia.org/wiki/SHA-3}

Expand Down Expand Up @@ -4539,6 +4549,8 @@ \subsection{RSA Key Size}
in order to restrict the usage of the RSA key to the given set of parameters (the \code{rsa\_key.pss\_oaep} flag indicates whether
the key is constrained). Its second use is explained below and defines the parameters used for an RSA operation.
The hash algorithms are identified by their descriptor index (as returned by \code{find\_hash()}).
For RFC 8702 PSS-SHAKE, set \code{hash\_idx} and \code{mgf1\_hash\_idx} to the \code{shake128} or \code{shake256} descriptor index.
The mask generation function treats those two indexes as direct SHAKE mask generation functions, not as MGF1(SHAKE).

\index{ltc\_rsa\_op\_parameters}
\begin{small}
Expand Down
614 changes: 614 additions & 0 deletions notes/hash_tv.txt

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions notes/hashsum_tv.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ sha384: 7cc080c662524617e56d5a49f1c185909e9b1858a86684161ddd97fc5426f693b53f59d7
sha512: f90afe4d254716a9770fd2c4f29ca544f2975f961cbd7fa207117383e4e48f7a2e1ade4aac333a2cb8c227dd6af2fff4d87c31c2a3916ae24d507c7c94c21818 *tests/test.key
sha512-224: 64ec566b5c2de736eab1b4e8542dc110f736819ea7f8f48e3712fbad *tests/test.key
sha512-256: db880bce4beb7246510febb961c7595aab57a15de6f90cd079f145e476b5d773 *tests/test.key
shake128: 9acc6823e58083f1499718d478ea42f75656b4780800c3b105678c4985cdf3a9 *tests/test.key
shake256: 29d0d19db50cb5b90a7ce94883a04bb6a97b0dbb9a648f342d7032d64160dc7019262ed0e055ee209c5a0daa92f36004c9c51d70402145908b4b6e91ea15b5a1 *tests/test.key
tiger: 97d713850e7affac30a642572c1ee7b18793d5b9e0ef5932 *tests/test.key
tiger2: b2dfd53b3edba5b54e1f21a82cbf6a3475efbce33a8cae03 *tests/test.key
whirlpool: d7d41c755e0f28313f254cb198e0bfa42f56670595d97b80dceec754825d69938a9c11e5bf16e9a3809a62a09bddf021f3dbff4302ceec7ba46c88b41772b711 *tests/test.key
614 changes: 614 additions & 0 deletions notes/hmac_tv.txt

Large diffs are not rendered by default.

50 changes: 50 additions & 0 deletions src/hashes/sha3.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,36 @@ const struct ltc_hash_descriptor sha3_512_desc =
&sha3_512_test,
NULL
};

const struct ltc_hash_descriptor shake128_desc =
{
"shake128", /* name of hash */
34, /* internal ID */
32, /* Size of digest in octets */
168, /* Input block size in octets */
{ 2,16,840,1,101,3,4,2,11 }, /* ASN.1 OID */
9, /* Length OID */
&sha3_shake128_init,
&sha3_process,
&sha3_shake128_done,
&sha3_shake128_test,
NULL
};

const struct ltc_hash_descriptor shake256_desc =
{
"shake256", /* name of hash */
35, /* internal ID */
64, /* Size of digest in octets */
136, /* Input block size in octets */
{ 2,16,840,1,101,3,4,2,12 }, /* ASN.1 OID */
9, /* Length OID */
&sha3_shake256_init,
&sha3_process,
&sha3_shake256_done,
&sha3_shake256_test,
NULL
};
#endif

#ifdef LTC_KECCAK
Expand Down Expand Up @@ -272,6 +302,16 @@ static LTC_INLINE int s_sha3_shake_init(struct sha3_state *sha3, int num)
return CRYPT_OK;
}

int sha3_shake128_init(hash_state *md)
{
return s_sha3_shake_init(&md->sha3, 128);
}

int sha3_shake256_init(hash_state *md)
{
return s_sha3_shake_init(&md->sha3, 256);
}

int sha3_shake_init(hash_state *md, int num)
{
return s_sha3_shake_init(&md->sha3, num);
Expand Down Expand Up @@ -406,6 +446,16 @@ int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen)
return s_sha3_shake_done(&md->sha3, out, outlen, 0x1f, s_keccakf);
}

int sha3_shake128_done(hash_state *md, unsigned char *out)
{
return sha3_shake_done(md, out, 32);
}

int sha3_shake256_done(hash_state *md, unsigned char *out)
{
return sha3_shake_done(md, out, 64);
}

#if defined LTC_TURBO_SHAKE
static LTC_INLINE int s_turbo_shake_done(struct sha3_state *sha3, unsigned char *out, unsigned long outlen)
{
Expand Down
62 changes: 62 additions & 0 deletions src/hashes/sha3_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,68 @@ int sha3_512_test(void)
#endif
}

int sha3_shake256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
unsigned char hash[64];
int err;
hash_state c;
const unsigned char msg[] = "abc";

/* Fixed-size descriptor API: RFC 8702 uses SHAKE256 with 64-byte output. */
const unsigned char shake256_abc[64] = {
0x48, 0x33, 0x66, 0x60, 0x13, 0x60, 0xa8, 0x77,
0x1c, 0x68, 0x63, 0x08, 0x0c, 0xc4, 0x11, 0x4d,
0x8d, 0xb4, 0x45, 0x30, 0xf8, 0xf1, 0xe1, 0xee,
0x4f, 0x94, 0xea, 0x37, 0xe7, 0x8b, 0x57, 0x39,
0xd5, 0xa1, 0x5b, 0xef, 0x18, 0x6a, 0x53, 0x86,
0xc7, 0x57, 0x44, 0xc0, 0x52, 0x7e, 0x1f, 0xaa,
0x9f, 0x87, 0x26, 0xe4, 0x62, 0xa1, 0x2a, 0x4f,
0xeb, 0x06, 0xbd, 0x88, 0x01, 0xe7, 0x51, 0xe4
};

if ((err = sha3_shake256_init(&c)) != CRYPT_OK) return err;
if ((err = sha3_shake256_process(&c, msg, 3)) != CRYPT_OK) return err;
if ((err = sha3_shake256_done(&c, hash)) != CRYPT_OK) return err;
if (ltc_compare_testvector(hash, sizeof(hash), shake256_abc, sizeof(shake256_abc), "SHAKE256", 0)) {
return CRYPT_FAIL_TESTVECTOR;
}

return CRYPT_OK;
#endif
}

int sha3_shake128_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
unsigned char hash[32];
int err;
hash_state c;
const unsigned char msg[] = "abc";

/* Fixed-size descriptor API: RFC 8702 uses SHAKE128 with 32-byte output. */
const unsigned char shake128_abc[32] = {
0x58, 0x81, 0x09, 0x2d, 0xd8, 0x18, 0xbf, 0x5c,
0xf8, 0xa3, 0xdd, 0xb7, 0x93, 0xfb, 0xcb, 0xa7,
0x40, 0x97, 0xd5, 0xc5, 0x26, 0xa6, 0xd3, 0x5f,
0x97, 0xb8, 0x33, 0x51, 0x94, 0x0f, 0x2c, 0xc8
};

if ((err = sha3_shake128_init(&c)) != CRYPT_OK) return err;
if ((err = sha3_shake128_process(&c, msg, 3)) != CRYPT_OK) return err;
if ((err = sha3_shake128_done(&c, hash)) != CRYPT_OK) return err;
if (ltc_compare_testvector(hash, sizeof(hash), shake128_abc, sizeof(shake128_abc), "SHAKE128", 0)) {
return CRYPT_FAIL_TESTVECTOR;
}

return CRYPT_OK;
#endif
}

int sha3_shake_test(void)
{
#ifndef LTC_TEST
Expand Down
2 changes: 1 addition & 1 deletion src/headers/tomcrypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ extern "C" {
#define SCRYPT "1.18.2-develop"

/* max size of either a cipher/hash block or symmetric key [largest of the two] */
#define MAXBLOCKSIZE 144
#define MAXBLOCKSIZE 168

#ifndef TAB_SIZE
/* descriptor table size */
Expand Down
12 changes: 12 additions & 0 deletions src/headers/tomcrypt_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,18 @@ extern const struct ltc_hash_descriptor sha3_256_desc;
int sha3_224_test(void);
extern const struct ltc_hash_descriptor sha3_224_desc;
int sha3_done(hash_state *md, unsigned char *out);
/* SHAKE128 with digest length according to RFC 8702 */
int sha3_shake128_init(hash_state *md);
#define sha3_shake128_process(a,b,c) sha3_process(a,b,c)
int sha3_shake128_done(hash_state *md, unsigned char *out);
int sha3_shake128_test(void);
extern const struct ltc_hash_descriptor shake128_desc;
/* SHAKE256 with digest length according to RFC 8702 */
int sha3_shake256_init(hash_state *md);
#define sha3_shake256_process(a,b,c) sha3_process(a,b,c)
int sha3_shake256_done(hash_state *md, unsigned char *out);
int sha3_shake256_test(void);
extern const struct ltc_hash_descriptor shake256_desc;
/* SHAKE128 + SHAKE256 */
int sha3_shake_init(hash_state *md, int num);
#define sha3_shake_process(a,b,c) sha3_process(a,b,c)
Expand Down
2 changes: 2 additions & 0 deletions src/misc/crypt/crypt_register_all_hashes.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ int register_all_hashes(void)
REGISTER_HASH(&sha3_384_desc);
REGISTER_HASH(&sha3_256_desc);
REGISTER_HASH(&sha3_224_desc);
REGISTER_HASH(&shake128_desc);
REGISTER_HASH(&shake256_desc);
#endif
#ifdef LTC_SHA512_256
REGISTER_HASH(&sha512_256_desc);
Expand Down
12 changes: 12 additions & 0 deletions src/pk/pkcs1/pkcs_1_mgf1.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
@param mask [out] The destination
@param masklen The length of the mask desired
@return CRYPT_OK if successful

BEWARE: When hash_idx selects shake128 or shake256, this uses
SHAKE directly instead of MGF1(SHAKE), as required by RFC 8702.
*/
int ltc_pkcs_1_mgf1(int hash_idx,
const unsigned char *seed, unsigned long seedlen,
Expand All @@ -36,6 +39,15 @@ int ltc_pkcs_1_mgf1(int hash_idx,
return err;
}

#ifdef LTC_SHA3
if (hash_descriptor[hash_idx].ID == shake128_desc.ID
|| hash_descriptor[hash_idx].ID == shake256_desc.ID) {
/* The output hashsize is double the announced SHAKE bitsize
* and given in octets, so only multiply by 4 to arrive at 128 resp. 256. */
return sha3_shake_memory(hash_descriptor[hash_idx].hashsize * 4, seed, seedlen, mask, &masklen);
}
#endif

/* get hash output size */
hLen = hash_descriptor[hash_idx].hashsize;

Expand Down
123 changes: 123 additions & 0 deletions tests/ecc_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,126 @@ static int s_ecc_issue446(void)
return CRYPT_OK;
}

#if defined(LTC_SHA3) && defined(LTC_DER)
static int s_ecc_shake_wycheproof_test(void)
{
const struct {
const char *hash, *curve;
struct {
int tc_id, valid;
const char *pub, *msg, *sig;
} tests[2];
} cases[] = {
{ /* Project Wycheproof: testvectors_v1/ecdsa_secp256r1_shake128_test.json */
"shake128", "SECP256R1",
{
{
3, 1, /* valid */
"0404aaec73635726f213fb8a9e64da3b8632e41495a944d0045b522eba7240fad587d9315798aaa3a5ba01775787ced05eaaf7b4e09fc81d6d1aa546e8365d525d",
"313233343030",
"304402202472b597920aaa98fdf7c7519531b46934df912d61a55d14970124dcdfd040870220049d0db50c18a8ce3a5f572863dfd1f809e2356c2f8ce8f8eef940cb8e40e82f"
},
{
6, 0, /* invalid */
"042927b10512bae3eddcfe467828128bad2903269919f7086069c8c4df6c732838c7787964eaac00e5921fb1498a60f4606766b3d9685001558d1a974e7341513e",
"313233343030",
"304402207182f26bc75cb9735fe63539b290ef8c4828f2eea083aabca058bc2fb23a67c80220c96ce04ecaf994eb481e506669930f8232e89bc45848e9822d166066986ae097"
}
}
},
{ /* Project Wycheproof: testvectors_v1/ecdsa_secp384r1_shake256_test.json */
"shake256", "SECP384R1",
{
{
3, 1, /* valid */
"0429bdb76d5fa741bfd70233cb3a66cc7d44beb3b0663d92a8136650478bcefb61ef182e155a54345a5e8e5e88f064e5bc9a525ab7f764dad3dae1468c2b419f3b62b9ba917d"
"5e8c4fb1ec47404a3fc76474b2713081be9db4c00e043ada9fc4a3",
"313233343030",
"3066023100ac1a2f58fa317f0cc20d6ca7c528da1270021429dd0989031d1efddd9fa5a2d63bd2f4b281707ceb66fa37f2d8344b9f0231009d984f3e6f6e5e114aaaaa91a2c8"
"c3e376b8304b8c2524e689008eb33048cebae4f98bf539550648f34be6eedeaa5182"
},
{
6, 0, /* invalid */
"042da57dda1089276a543f9ffdac0bff0d976cad71eb7280e7d9bfd9fee4bdb2f20f47ff888274389772d98cc5752138aa4b6d054d69dcf3e25ec49df870715e34883b183619"
"7d76f8ad962e78f6571bbc7407b0d6091f9e4d88f014274406174f",
"313233343030",
"306402300ecab5652755adfd5e804d1201ea4ce8a209bcdadb68c65fa049cc76adfc200f7fae56855cbdf25fd0d306ba15bef3450230d4a89a0f736e2fe79fad390b17f37d11"
"604b7091681c911ecb407d49f47be55f81d159e7ab23e34fff24c66f304397d8"
}
}
},
{ /* Project Wycheproof: testvectors_v1/ecdsa_secp521r1_shake256_test.json */
"shake256", "SECP521R1",
{
{
3, 1, /* valid */
"04012a908bfc5b70e17bdfae74294994808bf2a42dab59af8b0523a026d640a2a3d6d344520b62177e2cfa339ca42fb0883ec425904fbda2833a3b5b0a9a00811365d8012333"
"d532f8f8eb1a623c378a3694651192bbda833e3b8d7b8f90b2bfc9b045f8a55e1b6a5fe1512c400c4bc9c86fd7c699d642f5cee9bb827c8b0abc0da01cef1e",
"313233343030",
"308187024136c3e9fe2eb20fdce3fca2f1b7f3b67c08982605f42cbf562f8476cebae976efbd2c26bcc1eb3a3ed0c08a6611c6a118fca54411155de5b4a8c014a865df0da55d"
"0242013e41e59581e9f65812c9f84088fe4d4bd139895ce05936da1bd0410aa4f4493ed0911e07894aef3a0c10e67dd72a6540fe7f270f1fe086660def1df27f51027ca4"
},
{
6, 0, /* invalid */
"04005c6457ec088d532f482093965ae53ccd07e556ed59e2af945cd8c7a95c1c644f8a56a8a8a3cd77392ddd861e8a924dac99c69069093bd52a52fa6c56004a074508007878"
"d6d42e4b4dd1e9c0696cb3e19f63033c3db4e60d473259b3ebe079aaf0a986ee6177f8217a78c68b813f7e149a4e56fd9562c07fed3d895942d7d101cb83f6",
"313233343030",
"308187024201f33bd8d0d201495be274a61b92565b80369f519af858a15a468651eefa84e8e7ae9be1e4577eaaa925646bbf7dec1ae63798c5571123514daa8f5e555b530d72"
"6b0241eae9de13cbbfbdd7b1ffcfefdd0452248a8702b339d04f4bcf0451bb3cc1bd1e3079ca27e6147c7f8f302c8fd61d3978d4cfc38117168e0907f39e5965d51be5c5"
}
}
}
};
const ltc_ecc_curve *cu;
ltc_ecc_sig_opts sig_opts = { .type = LTC_ECCSIG_ANSIX962 };
ecc_key key;
unsigned char pub[140], msg[64], sig[160], hash[64];
unsigned long publen, msglen, siglen, hashlen;
unsigned int i, j;

for (i = 0; i < LTC_ARRAY_SIZE(cases); ++i) {
int hash_idx = find_hash(cases[i].hash);

DO(hash_is_valid(hash_idx));
DO(ecc_find_curve(cases[i].curve, &cu));

for (j = 0; j < LTC_ARRAY_SIZE(cases[i].tests); ++j) {
int err, stat;
char name[64];

snprintf(name, sizeof(name), "Wycheproof %s/%d tcId=%d", cases[i].hash, hash_idx, cases[i].tests[j].tc_id);
publen = sizeof(pub);
msglen = sizeof(msg);
siglen = sizeof(sig);
DOX(base16_decode(cases[i].tests[j].pub, XSTRLEN(cases[i].tests[j].pub), pub, &publen), name);
DOX(base16_decode(cases[i].tests[j].msg, XSTRLEN(cases[i].tests[j].msg), msg, &msglen), name);
DOX(base16_decode(cases[i].tests[j].sig, XSTRLEN(cases[i].tests[j].sig), sig, &siglen), name);

hashlen = sizeof(hash);
DOX(hash_memory(hash_idx, msg, msglen, hash, &hashlen), name);

DO(ecc_set_curve(cu, &key));
if ((err = ecc_set_key(pub, publen, PK_PUBLIC, &key)) != CRYPT_OK) {
ecc_free(&key);
DOX(err, name);
}
stat = 0;
err = ecc_verify_hash_v2(sig, siglen, hash, hashlen, &sig_opts, &stat, &key);
ecc_free(&key);
if (cases[i].tests[j].valid) {
DOX(err, name);
ENSUREX(stat == 1, name);
}
else {
ENSUREX(err != CRYPT_OK || stat == 0, name);
}
}
}

return CRYPT_OK;
}
#endif

static int s_ecc_test_mp(void)
{
void *a, *modulus, *order;
Expand Down Expand Up @@ -2442,6 +2562,9 @@ int ecc_test(void)
DO(s_ecc_wycheproof_bp224_wrong_curve());
#endif
DO(s_ecc_issue446());
#if defined(LTC_SHA3) && defined(LTC_DER)
DO(s_ecc_shake_wycheproof_test());
#endif
DO(s_ecc_rfc6979());
DO(s_ecc_old_api()); /* up to 1.18 */
DO(s_ecc_new_api());
Expand Down
Loading
Loading