// // FIPS202 (SHA-3) implementation. // #include // true, false #include // uint64_t #include // memcpy() #include "sha3.h" // 64-bit rotate left #define ROL(v, n) (((v) << (n)) | ((v) >> (64-(n)))) // minimum of two values #define MIN(a, b) (((a) < (b)) ? (a) : (b)) static inline void theta(uint64_t a[static 25]) { const uint64_t c[5] = { a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20], a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21], a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22], a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23], a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24], }; const uint64_t d[5] = { c[4] ^ ROL(c[1], 1), c[0] ^ ROL(c[2], 1), c[1] ^ ROL(c[3], 1), c[2] ^ ROL(c[4], 1), c[3] ^ ROL(c[0], 1), }; a[ 0] ^= d[0]; a[ 1] ^= d[1]; a[ 2] ^= d[2]; a[ 3] ^= d[3]; a[ 4] ^= d[4]; a[ 5] ^= d[0]; a[ 6] ^= d[1]; a[ 7] ^= d[2]; a[ 8] ^= d[3]; a[ 9] ^= d[4]; a[10] ^= d[0]; a[11] ^= d[1]; a[12] ^= d[2]; a[13] ^= d[3]; a[14] ^= d[4]; a[15] ^= d[0]; a[16] ^= d[1]; a[17] ^= d[2]; a[18] ^= d[3]; a[19] ^= d[4]; a[20] ^= d[0]; a[21] ^= d[1]; a[22] ^= d[2]; a[23] ^= d[3]; a[24] ^= d[4]; } static inline void rho(uint64_t a[static 25]) { a[1] = ROL(a[1], 1); // 1 % 64 = 1 a[2] = ROL(a[2], 62); // 190 % 64 = 62 a[3] = ROL(a[3], 28); // 28 % 64 = 28 a[4] = ROL(a[4], 27); // 91 % 64 = 27 a[5] = ROL(a[5], 36); // 36 % 64 = 36 a[6] = ROL(a[6], 44); // 300 % 64 = 44 a[7] = ROL(a[7], 6); // 6 % 64 = 6 a[8] = ROL(a[8], 55); // 55 % 64 = 55 a[9] = ROL(a[9], 20); // 276 % 64 = 20 a[10] = ROL(a[10], 3); // 3 % 64 = 3 a[11] = ROL(a[11], 10); // 10 % 64 = 10 a[12] = ROL(a[12], 43); // 171 % 64 = 43 a[13] = ROL(a[13], 25); // 153 % 64 = 25 a[14] = ROL(a[14], 39); // 231 % 64 = 39 a[15] = ROL(a[15], 41); // 105 % 64 = 41 a[16] = ROL(a[16], 45); // 45 % 64 = 45 a[17] = ROL(a[17], 15); // 15 % 64 = 15 a[18] = ROL(a[18], 21); // 21 % 64 = 21 a[19] = ROL(a[19], 8); // 136 % 64 = 8 a[20] = ROL(a[20], 18); // 210 % 64 = 18 a[21] = ROL(a[21], 2); // 66 % 64 = 2 a[22] = ROL(a[22], 61); // 253 % 64 = 61 a[23] = ROL(a[23], 56); // 120 % 64 = 56 a[24] = ROL(a[24], 14); // 78 % 64 = 14 } static inline void pi(uint64_t a[static 25]) { uint64_t t[25] = { 0 }; memcpy(t, a, sizeof(t)); a[1] = t[6]; a[2] = t[12]; a[3] = t[18]; a[4] = t[24]; a[5] = t[3]; a[6] = t[9]; a[7] = t[10]; a[8] = t[16]; a[9] = t[22]; a[10] = t[1]; a[11] = t[7]; a[12] = t[13]; a[13] = t[19]; a[14] = t[20]; a[15] = t[4]; a[16] = t[5]; a[17] = t[11]; a[18] = t[17]; a[19] = t[23]; a[20] = t[2]; a[21] = t[8]; a[22] = t[14]; a[23] = t[15]; a[24] = t[21]; } static inline void chi(uint64_t a[static 25]) { uint64_t t[25] = { 0 }; memcpy(t, a, sizeof(t)); a[0] = t[0] ^ (~t[1] & t[2]); a[1] = t[1] ^ (~t[2] & t[3]); a[2] = t[2] ^ (~t[3] & t[4]); a[3] = t[3] ^ (~t[4] & t[0]); a[4] = t[4] ^ (~t[0] & t[1]); a[5] = t[5] ^ (~t[6] & t[7]); a[6] = t[6] ^ (~t[7] & t[8]); a[7] = t[7] ^ (~t[8] & t[9]); a[8] = t[8] ^ (~t[9] & t[5]); a[9] = t[9] ^ (~t[5] & t[6]); a[10] = t[10] ^ (~t[11] & t[12]); a[11] = t[11] ^ (~t[12] & t[13]); a[12] = t[12] ^ (~t[13] & t[14]); a[13] = t[13] ^ (~t[14] & t[10]); a[14] = t[14] ^ (~t[10] & t[11]); a[15] = t[15] ^ (~t[16] & t[17]); a[16] = t[16] ^ (~t[17] & t[18]); a[17] = t[17] ^ (~t[18] & t[19]); a[18] = t[18] ^ (~t[19] & t[15]); a[19] = t[19] ^ (~t[15] & t[16]); a[20] = t[20] ^ (~t[21] & t[22]); a[21] = t[21] ^ (~t[22] & t[23]); a[22] = t[22] ^ (~t[23] & t[24]); a[23] = t[23] ^ (~t[24] & t[20]); a[24] = t[24] ^ (~t[20] & t[21]); } static inline void iota(uint64_t a[static 25], const int i) { // round constants (ambiguous in spec) static const uint64_t RCS[] = { 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL, 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL, }; a[0] ^= RCS[i]; } static inline void permute(uint64_t a[static 25]) { for (int i = 0; i < 24; i++) { theta(a); rho(a); pi(a); chi(a); iota(a, i); } } static inline size_t keccak(sha3_state_t * const a, const uint8_t *m, size_t m_len, const size_t rate) { while (m_len >= rate) { // absorb u64-sized chunks for (size_t i = 0; i < rate / sizeof(uint64_t); i++) { a->u64[i] ^= ((uint64_t*) m)[i]; } // permute permute(a->u64); m += rate; m_len -= rate; } // absorb u64-sized chunks for (size_t i = 0; i < m_len / sizeof(uint64_t); i++) { a->u64[i] ^= ((uint64_t*) m)[i]; } // absorb final bytes for (size_t i = m_len & ~(sizeof(uint64_t) - 1); i < m_len; i++) { a->u8[i] ^= m[i]; } // return final chunk size return m_len; } static inline void sha3(const uint8_t *m, size_t m_len, uint8_t * const dst, const size_t dst_len) { // in the sha3 hash functions, the capacity is always 2 times the // destination length, and the rate is the total state size minus the // capacity const size_t rate = 200 - 2 * dst_len; sha3_state_t a = { .u64 = { 0 } }; const size_t len = keccak(&a, m, m_len, rate); // append suffix and padding // (note: suffix and padding are ambiguous in spec) a.u8[len] ^= 0x06; a.u8[rate-1] ^= 0x80; // permute permute(a.u64); // copy to destination memcpy(dst, a.u8, dst_len); } void sha3_224(const uint8_t *m, size_t m_len, uint8_t dst[static 28]) { sha3(m, m_len, dst, 28); } void sha3_256(const uint8_t *m, size_t m_len, uint8_t dst[static 32]) { sha3(m, m_len, dst, 32); } void sha3_384(const uint8_t *m, size_t m_len, uint8_t dst[static 48]) { sha3(m, m_len, dst, 48); } void sha3_512(const uint8_t *m, size_t m_len, uint8_t dst[static 64]) { sha3(m, m_len, dst, 64); } static inline void shake(const uint8_t *m, size_t m_len, uint8_t * const dst, const size_t dst_len) { // in the sha3 xof functions, the capacity is always 2 times the // destination length, and the rate is the total state size minus the // capacity const size_t rate = 200 - 2 * dst_len; sha3_state_t a = { .u64 = { 0 } }; const size_t len = keccak(&a, m, m_len, rate); // append suffix (s6.2) and padding // (note: suffix and padding are ambiguous in spec) a.u8[len] ^= 0x1f; a.u8[rate-1] ^= 0x80; // permute permute(a.u64); // copy to destination memcpy(dst, a.u8, dst_len); } void shake128(const uint8_t *m, size_t m_len, uint8_t dst[static 16]) { shake(m, m_len, dst, 16); } void shake256(const uint8_t *m, size_t m_len, uint8_t dst[static 32]) { shake(m, m_len, dst, 32); } static inline void xof_init(sha3_xof_t * const xof) { memset(xof, 0, sizeof(sha3_xof_t)); } static inline _Bool xof_absorb(sha3_xof_t * const xof, const size_t rate, const uint8_t * const m, size_t m_len) { // check state if (xof->squeezing) { return false; } // absorb bytes // (TODO: absorb larger chunks) for (size_t i = 0; i < m_len; i++) { xof->a.u8[xof->num_bytes++] ^= m[i]; if (xof->num_bytes == rate) { permute(xof->a.u64); xof->num_bytes = 0; } } // return success return true; } static inline void xof_absorb_done(sha3_xof_t * const xof, const size_t rate, const uint8_t pad) { // append suffix (s6.2) and padding // (note: suffix and padding are ambiguous in spec) xof->a.u8[xof->num_bytes] ^= pad; xof->a.u8[rate - 1] ^= 0x80; // permute permute(xof->a.u64); // switch to squeeze mode xof->num_bytes = 0; xof->squeezing = true; } static inline void xof_squeeze(sha3_xof_t * const xof, const size_t rate, const uint8_t pad, uint8_t * const dst, const size_t dst_len) { // check state if (!xof->squeezing) { // finalize absorb xof_absorb_done(xof, rate, pad); } for (size_t i = 0; i < dst_len; i++) { dst[i] = xof->a.u8[xof->num_bytes++]; if (xof->num_bytes == rate) { permute(xof->a.u64); xof->num_bytes = 0; } } } static inline void xof_once(const size_t rate, const uint8_t pad, const uint8_t * const src, const size_t src_len, uint8_t * const dst, const size_t dst_len) { // init sha3_xof_t xof; xof_init(&xof); // absorb (ignore error) (void) xof_absorb(&xof, rate, src, src_len); // squeeze xof_squeeze(&xof, rate, pad, dst, dst_len); } #define SHAKE128_XOF_RATE (200 - 2 * 16) #define SHAKE128_XOF_PAD 0x1f void shake128_xof_init(sha3_xof_t * const xof) { xof_init(xof); } _Bool shake128_xof_absorb(sha3_xof_t * const xof, const uint8_t * const m, const size_t len) { return xof_absorb(xof, SHAKE128_XOF_RATE, m, len); } void shake128_xof_squeeze(sha3_xof_t * const xof, uint8_t * const dst, const size_t dst_len) { xof_squeeze(xof, SHAKE128_XOF_RATE, SHAKE128_XOF_PAD, dst, dst_len); } void shake128_xof_once(const uint8_t * const src, const size_t src_len, uint8_t * const dst, const size_t dst_len) { xof_once(SHAKE128_XOF_RATE, SHAKE128_XOF_PAD, src, src_len, dst, dst_len); } #define SHAKE256_XOF_RATE (200 - 2 * 32) #define SHAKE256_XOF_PAD 0x1f void shake256_xof_init(sha3_xof_t * const xof) { xof_init(xof); } _Bool shake256_xof_absorb(sha3_xof_t * const xof, const uint8_t * const m, const size_t len) { return xof_absorb(xof, SHAKE256_XOF_RATE, m, len); } void shake256_xof_squeeze(sha3_xof_t * const xof, uint8_t * const dst, const size_t dst_len) { xof_squeeze(xof, SHAKE256_XOF_RATE, SHAKE256_XOF_PAD, dst, dst_len); } void shake256_xof_once(const uint8_t * const src, const size_t src_len, uint8_t * const dst, const size_t dst_len) { xof_once(SHAKE256_XOF_RATE, SHAKE256_XOF_PAD, src, src_len, dst, dst_len); } // NIST SP 800-105 utility function. static inline size_t left_encode(uint8_t buf[static 9], const uint64_t n) { if (n > 0x00ffffffffffffffULL) { buf[0] = 8; buf[1] = (n >> 56) & 0xff; buf[2] = (n >> 40) & 0xff; buf[3] = (n >> 32) & 0xff; buf[4] = (n >> 24) & 0xff; buf[5] = (n >> 16) & 0xff; buf[6] = (n >> 8) & 0xff; buf[7] = n & 0xff; return 9; } else if (n > 0x0000ffffffffffffULL) { buf[0] = 7; buf[1] = (n >> 56) & 0xff; buf[2] = (n >> 40) & 0xff; buf[3] = (n >> 32) & 0xff; buf[4] = (n >> 24) & 0xff; buf[5] = (n >> 16) & 0xff; buf[6] = (n >> 8) & 0xff; buf[7] = n & 0xff; return 8; } else if (n > 0x000000ffffffffffULL) { buf[0] = 6; buf[1] = (n >> 40) & 0xff; buf[2] = (n >> 32) & 0xff; buf[3] = (n >> 24) & 0xff; buf[4] = (n >> 16) & 0xff; buf[5] = (n >> 8) & 0xff; buf[6] = n & 0xff; return 7; } else if (n > 0x00000000ffffffffULL) { buf[0] = 5; buf[1] = (n >> 32) & 0xff; buf[2] = (n >> 24) & 0xff; buf[3] = (n >> 16) & 0xff; buf[4] = (n >> 8) & 0xff; buf[5] = n & 0xff; return 6; } else if (n > 0x0000000000ffffffULL) { buf[0] = 4; buf[1] = (n >> 24) & 0xff; buf[2] = (n >> 16) & 0xff; buf[3] = (n >> 8) & 0xff; buf[4] = n & 0xff; return 5; } else if (n > 0x000000000000ffffULL) { buf[0] = 3; buf[1] = (n >> 16) & 0xff; buf[2] = (n >> 8) & 0xff; buf[3] = n & 0xff; return 4; } else if (n > 0x00000000000000ffULL) { buf[0] = 2; buf[1] = (n >> 8) & 0xff; buf[2] = n & 0xff; return 3; } else { buf[0] = 1; buf[1] = n & 0xff; return 2; } } // NIST SP 800-105 utility function. static inline size_t right_encode(uint8_t buf[static 9], const uint64_t n) { if (n > 0x00ffffffffffffffULL) { buf[0] = (n >> 56) & 0xff; buf[1] = (n >> 40) & 0xff; buf[2] = (n >> 32) & 0xff; buf[3] = (n >> 24) & 0xff; buf[4] = (n >> 16) & 0xff; buf[5] = (n >> 8) & 0xff; buf[6] = n & 0xff; buf[7] = 8; return 9; } else if (n > 0x0000ffffffffffffULL) { buf[0] = (n >> 56) & 0xff; buf[1] = (n >> 40) & 0xff; buf[2] = (n >> 32) & 0xff; buf[3] = (n >> 24) & 0xff; buf[4] = (n >> 16) & 0xff; buf[5] = (n >> 8) & 0xff; buf[6] = n & 0xff; buf[7] = 7; return 8; } else if (n > 0x000000ffffffffffULL) { buf[0] = (n >> 40) & 0xff; buf[1] = (n >> 32) & 0xff; buf[2] = (n >> 24) & 0xff; buf[3] = (n >> 16) & 0xff; buf[4] = (n >> 8) & 0xff; buf[5] = n & 0xff; buf[6] = 6; return 7; } else if (n > 0x00000000ffffffffULL) { buf[0] = (n >> 32) & 0xff; buf[1] = (n >> 24) & 0xff; buf[2] = (n >> 16) & 0xff; buf[3] = (n >> 8) & 0xff; buf[4] = n & 0xff; buf[5] = 5; return 6; } else if (n > 0x0000000000ffffffULL) { buf[0] = (n >> 24) & 0xff; buf[1] = (n >> 16) & 0xff; buf[2] = (n >> 8) & 0xff; buf[3] = n & 0xff; buf[4] = 4; return 5; } else if (n > 0x000000000000ffffULL) { buf[0] = (n >> 16) & 0xff; buf[1] = (n >> 8) & 0xff; buf[2] = n & 0xff; buf[3] = 3; return 4; } else if (n > 0x00000000000000ffULL) { buf[0] = (n >> 8) & 0xff; buf[1] = n & 0xff; buf[2] = 2; return 3; } else { buf[0] = n & 0xff; buf[1] = 1; return 2; } } // Write prefix for encode_string() to the given buffer. Accepts the // length of the string, in bytes. // // Returns the length of the prefix, in bytes. static inline size_t encode_string_prefix(uint8_t buf[static 9], const size_t num_bytes) { return left_encode(buf, (uint64_t) num_bytes << 3); } typedef struct { uint8_t prefix[9]; // bytepad prefix size_t prefix_len; // length of bytepad prefix, in bytes size_t pad_len; // number of padding bytes after prefix and data } bytepad_t; // write bytepad() prefix to buffer, then return structure containing // the length of the prefix, in bytes, and the total number of static inline bytepad_t bytepad(const size_t data_len, const size_t width) { bytepad_t r = { { 0 }, 0, 0 }; const size_t prefix_len = left_encode(r.prefix, width); const size_t total_len = prefix_len + data_len; const size_t padded_len = (total_len / width + ((total_len % width) ? 1 : 0)) * width; r.prefix_len = prefix_len; r.pad_len = padded_len - total_len; return r; } #define CSHAKE128_XOF_RATE (200 - 2 * 16) #define CSHAKE128_XOF_PAD 0x04 _Bool cshake128_xof_absorb(sha3_xof_t * const xof, const uint8_t * const msg, const size_t len) { return xof_absorb(xof, CSHAKE128_XOF_RATE, msg, len); } void cshake128_xof_squeeze(sha3_xof_t * const xof, uint8_t * const dst, const size_t len) { xof_squeeze(xof, CSHAKE128_XOF_RATE, CSHAKE128_XOF_PAD, dst, len); } void cshake128_xof_init(sha3_xof_t * const xof, const cshake_params_t params) { static const uint8_t PAD[CSHAKE128_XOF_RATE] = { 0 }; if (!params.name_len && !params.custom_len) { // cshake w/o nist prefix and domain is shake shake128_xof_init(xof); // FIXME: padding will be wrong on subsequent cshake128_xof_absorb() // calls return; } // build nist function name prefix uint8_t name_buf[9] = { 0 }; const size_t name_len = encode_string_prefix(name_buf, params.name_len); // build custom string prefix uint8_t custom_buf[9] = { 0 }; const size_t custom_len = encode_string_prefix(custom_buf, params.custom_len); const size_t raw_len = name_len + params.name_len + custom_len + params.custom_len; // build bytepad prefix const bytepad_t bp = bytepad(raw_len, CSHAKE128_XOF_RATE); // init xof xof_init(xof); // absorb bytepad prefix (void) cshake128_xof_absorb(xof, bp.prefix, bp.prefix_len); // absorb name string (void) cshake128_xof_absorb(xof, name_buf, name_len); if (params.name_len > 0) { (void) cshake128_xof_absorb(xof, params.name, params.name_len); } // absorb custom string (void) cshake128_xof_absorb(xof, custom_buf, custom_len); if (params.custom_len > 0) { (void) cshake128_xof_absorb(xof, params.custom, params.custom_len); } // absorb padding for (size_t ofs = 0; ofs < bp.pad_len; ofs += sizeof(PAD)) { const size_t len = MIN(bp.pad_len - ofs, sizeof(PAD)); (void) cshake128_xof_absorb(xof, PAD, len); } } void cshake128( const cshake_params_t params, const uint8_t * const msg, const size_t msg_len, uint8_t * const dst, const size_t dst_len ) { if (!params.name_len && !params.custom_len) { // cshake w/o nist prefix and domain is shake shake128_xof_once(msg, msg_len, dst, dst_len); return; } // init sha3_xof_t xof; cshake128_xof_init(&xof, params); // absorb (void) cshake128_xof_absorb(&xof, msg, msg_len); // squeeze cshake128_xof_squeeze(&xof, dst, dst_len); } #define CSHAKE256_XOF_RATE (200 - 2 * 32) #define CSHAKE256_XOF_PAD 0x04 _Bool cshake256_xof_absorb(sha3_xof_t * const xof, const uint8_t * const msg, const size_t len) { return xof_absorb(xof, CSHAKE256_XOF_RATE, msg, len); } void cshake256_xof_squeeze(sha3_xof_t * const xof, uint8_t * const dst, const size_t len) { xof_squeeze(xof, CSHAKE256_XOF_RATE, CSHAKE256_XOF_PAD, dst, len); } void cshake256_xof_init(sha3_xof_t * const xof, const cshake_params_t params) { static const uint8_t PAD[CSHAKE256_XOF_RATE] = { 0 }; if (!params.name_len && !params.custom_len) { // cshake w/o nist prefix and domain is shake shake256_xof_init(xof); // FIXME: padding will be wrong on subsequent cshake256_xof_absorb() // calls return; } // build nist function name prefix uint8_t name_buf[9] = { 0 }; const size_t name_len = encode_string_prefix(name_buf, params.name_len); // build custom string prefix uint8_t custom_buf[9] = { 0 }; const size_t custom_len = encode_string_prefix(custom_buf, params.custom_len); const size_t raw_len = name_len + params.name_len + custom_len + params.custom_len; // build bytepad prefix const bytepad_t bp = bytepad(raw_len, CSHAKE256_XOF_RATE); // init xof xof_init(xof); // absorb bytepad prefix (void) cshake256_xof_absorb(xof, bp.prefix, bp.prefix_len); // absorb name string (void) cshake256_xof_absorb(xof, name_buf, name_len); if (params.name_len > 0) { (void) cshake256_xof_absorb(xof, params.name, params.name_len); } // absorb custom string (void) cshake256_xof_absorb(xof, custom_buf, custom_len); if (params.custom_len > 0) { (void) cshake256_xof_absorb(xof, params.custom, params.custom_len); } // absorb padding for (size_t ofs = 0; ofs < bp.pad_len; ofs += sizeof(PAD)) { const size_t len = MIN(bp.pad_len - ofs, sizeof(PAD)); (void) cshake256_xof_absorb(xof, PAD, len); } } void cshake256( const cshake_params_t params, const uint8_t * const msg, const size_t msg_len, uint8_t * const dst, const size_t dst_len ) { if (!params.name_len && !params.custom_len) { // cshake w/o nist prefix and domain is shake shake256_xof_once(msg, msg_len, dst, dst_len); return; } // init sha3_xof_t xof; cshake256_xof_init(&xof, params); // absorb (void) cshake256_xof_absorb(&xof, msg, msg_len); // squeeze cshake256_xof_squeeze(&xof, dst, dst_len); } void kmac128( const kmac_params_t params, const uint8_t * const msg, const size_t msg_len, uint8_t * const dst, const size_t dst_len ) { static const uint8_t PAD[CSHAKE128_XOF_RATE] = { 0 }; static const uint8_t NAME[4] = { 'K', 'M', 'A', 'C' }; // build cshake128 params const cshake_params_t cshake_params = { .name = NAME, .name_len = sizeof(NAME), .custom = params.custom, .custom_len = params.custom_len, }; // build key prefix uint8_t key_buf[9] = { 0 }; const size_t key_buf_len = encode_string_prefix(key_buf, params.key_len); // build bytepad prefix const bytepad_t bp = bytepad(key_buf_len + params.key_len, CSHAKE128_XOF_RATE); // init xof sha3_xof_t xof; cshake128_xof_init(&xof, cshake_params); // absorb bytepad prefix (void) cshake128_xof_absorb(&xof, bp.prefix, bp.prefix_len); // absorb key (void) cshake128_xof_absorb(&xof, key_buf, key_buf_len); if (params.key_len > 0) { (void) cshake128_xof_absorb(&xof, params.key, params.key_len); } // absorb padding for (size_t ofs = 0; ofs < bp.pad_len; ofs += sizeof(PAD)) { const size_t len = MIN(bp.pad_len - ofs, sizeof(PAD)); (void) cshake128_xof_absorb(&xof, PAD, len); } // absorb message (void) cshake128_xof_absorb(&xof, msg, msg_len); // build output length suffix uint8_t suffix_buf[9] = { 0 }; const size_t suffix_buf_len = right_encode(suffix_buf, dst_len << 3); // absorb output length suffix (void) cshake128_xof_absorb(&xof, suffix_buf, suffix_buf_len); // squeeze cshake128_xof_squeeze(&xof, dst, dst_len); } void kmac256( const kmac_params_t params, const uint8_t * const msg, const size_t msg_len, uint8_t * const dst, const size_t dst_len ) { static const uint8_t PAD[CSHAKE256_XOF_RATE] = { 0 }; static const uint8_t NAME[4] = { 'K', 'M', 'A', 'C' }; // build cshake256 params const cshake_params_t cshake_params = { .name = NAME, .name_len = sizeof(NAME), .custom = params.custom, .custom_len = params.custom_len, }; // build key prefix uint8_t key_buf[9] = { 0 }; const size_t key_buf_len = encode_string_prefix(key_buf, params.key_len); // build bytepad prefix const bytepad_t bp = bytepad(key_buf_len + params.key_len, CSHAKE256_XOF_RATE); // init xof sha3_xof_t xof; cshake256_xof_init(&xof, cshake_params); // absorb bytepad prefix (void) cshake256_xof_absorb(&xof, bp.prefix, bp.prefix_len); // absorb key (void) cshake256_xof_absorb(&xof, key_buf, key_buf_len); if (params.key_len > 0) { (void) cshake256_xof_absorb(&xof, params.key, params.key_len); } // absorb padding for (size_t ofs = 0; ofs < bp.pad_len; ofs += sizeof(PAD)) { const size_t len = MIN(bp.pad_len - ofs, sizeof(PAD)); (void) cshake256_xof_absorb(&xof, PAD, len); } // absorb message (void) cshake256_xof_absorb(&xof, msg, msg_len); // build output length suffix uint8_t suffix_buf[9] = { 0 }; const size_t suffix_buf_len = right_encode(suffix_buf, dst_len << 3); // absorb output length suffix (void) cshake256_xof_absorb(&xof, suffix_buf, suffix_buf_len); // squeeze cshake256_xof_squeeze(&xof, dst, dst_len); } #ifdef SHA3_TEST #include // printf() static void dump_hex(FILE *f, const uint8_t * const a, const size_t len) { fprintf(f, " "); for (size_t i = 0; i < len; i++) { fprintf(f, "%02x ", a[i]); if ((i + 1) % 16 == 0) { fprintf(f, "\n "); } } fprintf(f, "\n"); } static void dump_state(FILE *f, const uint64_t a[static 25]) { dump_hex(f, (const uint8_t *) a, 25 * 8); } static void test_theta(void) { // src: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-256_Msg30.pdf uint64_t a[25] = { [0] = 0x00000001997b5853ULL, [16] = 0x8000000000000000ULL }; const uint8_t exp[] = { 0x52, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, }; theta(a); if (memcmp(exp, a, sizeof(exp))) { fprintf(stderr, "test_theta() failed, got:\n"); dump_state(stderr, a); fprintf(stderr, "exp:\n"); dump_state(stderr, (uint64_t*) exp); } } static void test_rho(void) { uint8_t a[] = { 0x52, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, }; const uint8_t exp[] = { 0x52, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x85, 0xB5, 0x97, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x97, 0x19, 0x00, 0x00, 0x00, 0x30, 0x85, 0xB5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0A, 0x6B, 0x2F, 0x33, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x01, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x2F, 0x33, 0x00, 0x00, 0x00, 0x70, 0x0A, 0x6B, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x29, 0xAC, 0xBD, 0xCC, 0x00, 0x00, }; rho((uint64_t*) a); if (memcmp(exp, a, sizeof(exp))) { fprintf(stderr, "test_rho() failed, got:\n"); dump_state(stderr, (uint64_t*) a); fprintf(stderr, "exp:\n"); dump_state(stderr, (uint64_t*) exp); } } static void test_pi(void) { uint8_t a[] = { 0x52, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x85, 0xB5, 0x97, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x97, 0x19, 0x00, 0x00, 0x00, 0x30, 0x85, 0xB5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0A, 0x6B, 0x2F, 0x33, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x01, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x2F, 0x33, 0x00, 0x00, 0x00, 0x70, 0x0A, 0x6B, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x29, 0xAC, 0xBD, 0xCC, 0x00, 0x00, }; const uint8_t exp[] = { 0x52, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0x97, 0x19, 0x00, 0x00, 0x00, 0x30, 0x85, 0xB5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x29, 0xAC, 0xBD, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0A, 0x6B, 0x2F, 0x33, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x33, 0x00, 0x00, 0x00, 0x70, 0x0A, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x85, 0xB5, 0x97, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x01, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, }; pi((uint64_t*) a); if (memcmp(exp, a, sizeof(exp))) { fprintf(stderr, "test_pi() failed, got:\n"); dump_state(stderr, (uint64_t*) a); fprintf(stderr, "exp:\n"); dump_state(stderr, (uint64_t*) exp); } } static void test_chi(void) { uint8_t a[] = { 0x52, 0x58, 0x7B, 0x99, 0x01, 0x00, 0x00, 0x00, 0x97, 0x19, 0x00, 0x00, 0x00, 0x30, 0x85, 0xB5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x29, 0xAC, 0xBD, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0A, 0x6B, 0x2F, 0x33, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x33, 0x00, 0x00, 0x00, 0x70, 0x0A, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x85, 0xB5, 0x97, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x01, 0x00, 0x00, 0x00, 0x53, 0x58, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, }; const uint8_t exp[] = { 0x52, 0x58, 0x7B, 0x99, 0x01, 0x04, 0x00, 0x00, 0x97, 0x19, 0x00, 0x00, 0x00, 0x30, 0x85, 0xB5, 0x00, 0x80, 0x29, 0xAC, 0xBD, 0xC8, 0x00, 0x00, 0x52, 0x58, 0x52, 0x11, 0x00, 0x00, 0x00, 0x00, 0x85, 0x81, 0x29, 0xAC, 0xBD, 0xFC, 0x85, 0xB5, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x33, 0x60, 0x0A, 0x6B, 0x5F, 0x39, 0x6B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x2F, 0x33, 0x00, 0x00, 0x00, 0x70, 0x0A, 0x6B, 0x00, 0x00, 0x60, 0x0A, 0x6B, 0x2F, 0x33, 0x10, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x20, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x16, 0x42, 0xC4, 0x31, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x61, 0xDD, 0xE0, 0xB3, 0x97, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x30, 0x85, 0xB5, 0x97, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x99, 0x01, 0x00, 0x00, 0x00, 0x53, 0x58, 0x5B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5, 0x60, 0xED, 0x65, 0x06, 0x53, 0x58, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, }; chi((uint64_t*) a); if (memcmp(exp, a, sizeof(exp))) { fprintf(stderr, "test_chi() failed, got:\n"); dump_state(stderr, (uint64_t*) a); fprintf(stderr, "exp:\n"); dump_state(stderr, (uint64_t*) exp); } } static void test_iota(void) { uint8_t a[] = { 0x52, 0x58, 0x7B, 0x99, 0x01, 0x04, 0x00, 0x00, 0x97, 0x19, 0x00, 0x00, 0x00, 0x30, 0x85, 0xB5, 0x00, 0x80, 0x29, 0xAC, 0xBD, 0xC8, 0x00, 0x00, 0x52, 0x58, 0x52, 0x11, 0x00, 0x00, 0x00, 0x00, 0x85, 0x81, 0x29, 0xAC, 0xBD, 0xFC, 0x85, 0xB5, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x33, 0x60, 0x0A, 0x6B, 0x5F, 0x39, 0x6B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x2F, 0x33, 0x00, 0x00, 0x00, 0x70, 0x0A, 0x6B, 0x00, 0x00, 0x60, 0x0A, 0x6B, 0x2F, 0x33, 0x10, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x20, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x16, 0x42, 0xC4, 0x31, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x61, 0xDD, 0xE0, 0xB3, 0x97, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x30, 0x85, 0xB5, 0x97, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x99, 0x01, 0x00, 0x00, 0x00, 0x53, 0x58, 0x5B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5, 0x60, 0xED, 0x65, 0x06, 0x53, 0x58, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, }; const uint8_t exp[] = { 0x53, 0x58, 0x7B, 0x99, 0x01, 0x04, 0x00, 0x00, 0x97, 0x19, 0x00, 0x00, 0x00, 0x30, 0x85, 0xB5, 0x00, 0x80, 0x29, 0xAC, 0xBD, 0xC8, 0x00, 0x00, 0x52, 0x58, 0x52, 0x11, 0x00, 0x00, 0x00, 0x00, 0x85, 0x81, 0x29, 0xAC, 0xBD, 0xFC, 0x85, 0xB5, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x33, 0x60, 0x0A, 0x6B, 0x5F, 0x39, 0x6B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x2F, 0x33, 0x00, 0x00, 0x00, 0x70, 0x0A, 0x6B, 0x00, 0x00, 0x60, 0x0A, 0x6B, 0x2F, 0x33, 0x10, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x20, 0xA6, 0xB0, 0xF6, 0x32, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x16, 0x42, 0xC4, 0x31, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x61, 0xDD, 0xE0, 0xB3, 0x97, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x30, 0x85, 0xB5, 0x97, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x99, 0x01, 0x00, 0x00, 0x00, 0x53, 0x58, 0x5B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5, 0x60, 0xED, 0x65, 0x06, 0x53, 0x58, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x4C, 0x61, 0xED, 0x65, 0x06, 0x00, 0x00, 0x00, }; iota((uint64_t*) a, 0); if (memcmp(exp, a, sizeof(exp))) { fprintf(stderr, "test_iota() failed, got:\n"); dump_state(stderr, (uint64_t*) a); fprintf(stderr, "exp:\n"); dump_state(stderr, (uint64_t*) exp); } } static void test_permute(void) { uint64_t a[25] = { [0] = 0x00000001997b5853ULL, [16] = 0x8000000000000000ULL }; const uint64_t exp[] = { 0xE95A9E40EF2F24C8ULL, 0x24C64DAE57C8F1D1ULL, 0x8CAA629F80192BB9ULL, 0xD0B178A0541C4107ULL, }; permute(a); if (memcmp(exp, a, sizeof(exp))) { fprintf(stderr, "test_permute() failed, got:\n"); dump_hex(stderr, (uint8_t*) a, 32); fprintf(stderr, "exp:\n"); dump_hex(stderr, (uint8_t*) exp, 32); } } static void test_sha3_224(void) { static const struct { const char *name; // test name const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[28]; // expected hash } tests[] = {{ .name = "empty", .msg = "", .len = 0, .exp = { 0x6b, 0x4e, 0x03, 0x42, 0x36, 0x67, 0xdb, 0xb7, 0x3b, 0x6e, 0x15, 0x45, 0x4f, 0x0e, 0xb1, 0xab, 0xd4, 0x59, 0x7f, 0x9a, 0x1b, 0x07, 0x8e, 0x3f, 0x5b, 0x5a, 0x6b, 0xc7, }, }, { .name = "asdf", .msg = "asdf", .len = 4, .exp = { 0x47, 0xcc, 0xa2, 0x03, 0xee, 0xfc, 0xa3, 0x49, 0xde, 0xaa, 0x41, 0x8d, 0xa7, 0xfe, 0x05, 0x38, 0x9e, 0xf6, 0x49, 0x98, 0x5c, 0x87, 0xa9, 0xb6, 0x55, 0xad, 0x12, 0x8c, }, }, { .name = "a-134", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 134, .exp = { 0x5d, 0x1d, 0xb4, 0xe4, 0x7c, 0x0c, 0x4a, 0x42, 0x45, 0xb9, 0x0d, 0x18, 0x55, 0xb0, 0x7c, 0xb1, 0x6f, 0xb9, 0x40, 0xc5, 0x00, 0x76, 0xc1, 0xfd, 0x2a, 0xc2, 0x17, 0xfe, }, }, { .name = "a-135", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 135, .exp = { 0xf9, 0xf2, 0x8c, 0x21, 0xa2, 0xb0, 0x88, 0x4b, 0xbd, 0x35, 0x94, 0xca, 0xe8, 0x2b, 0xf8, 0x11, 0xc0, 0xc1, 0xed, 0xe4, 0x27, 0xe0, 0x83, 0xd5, 0x57, 0x6e, 0x90, 0x9d, }, }, { .name = "a-136", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 136, .exp = { 0x96, 0x13, 0x6a, 0x6a, 0x09, 0x44, 0x33, 0xb4, 0xaa, 0x85, 0x5f, 0x16, 0x38, 0x29, 0xa2, 0xce, 0x6b, 0xca, 0x7d, 0x56, 0xcf, 0xd2, 0x16, 0x3b, 0x47, 0xf1, 0xf1, 0xc4, }, }, { .name = "ff-256", .msg = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, .len = 256, .exp = { 0xb6, 0x53, 0x4d, 0x8b, 0xee, 0xdf, 0xb5, 0xed, 0x3f, 0x95, 0x3b, 0x09, 0xd1, 0x2f, 0xc3, 0x8f, 0x3d, 0x8b, 0x0b, 0xea, 0x9d, 0x80, 0xbd, 0x1e, 0x25, 0xc9, 0xfc, 0x35, }, }, { .name = "a-210", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 210, .exp = { 0x03, 0x05, 0x4a, 0xb0, 0xa3, 0x37, 0x99, 0xbe, 0x2b, 0x17, 0xc8, 0x2b, 0x3a, 0x13, 0x90, 0x05, 0x2e, 0x49, 0xdf, 0x31, 0x6d, 0x85, 0x15, 0x2d, 0x74, 0x66, 0xab, 0x57, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { uint8_t got[28] = { 0 }; sha3_224(tests[i].msg, tests[i].len, got); if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_sha3_224(\"%s\") failed, got:\n", tests[i].name); dump_hex(stderr, got, 28); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 28); } } } static void test_sha3_256(void) { static const struct { const char *name; // test name const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[32]; // expected hash } tests[] = {{ .name = "empty", .msg = "", .len = 0, .exp = { 0xa7, 0xff, 0xc6, 0xf8, 0xbf, 0x1e, 0xd7, 0x66, 0x51, 0xc1, 0x47, 0x56, 0xa0, 0x61, 0xd6, 0x62, 0xf5, 0x80, 0xff, 0x4d, 0xe4, 0x3b, 0x49, 0xfa, 0x82, 0xd8, 0x0a, 0x4b, 0x80, 0xf8, 0x43, 0x4a, }, }, { .name = "asdf", .msg = "asdf", .len = 4, .exp = { 0xdd, 0x27, 0x81, 0xf4, 0xc5, 0x1b, 0xcc, 0xdb, 0xe2, 0x3e, 0x4d, 0x39, 0x8b, 0x8a, 0x82, 0x26, 0x1f, 0x58, 0x5c, 0x27, 0x8d, 0xbb, 0x4b, 0x84, 0x98, 0x9f, 0xea, 0x70, 0xe7, 0x67, 0x23, 0xa9, }, }, { .name = "a-134", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 134, .exp = { 0x58, 0xb9, 0x70, 0xc3, 0x7a, 0xc2, 0xd6, 0x5b, 0x59, 0x9b, 0x69, 0x18, 0x68, 0xa6, 0x14, 0x01, 0xa5, 0x01, 0xc4, 0x0f, 0x23, 0x5d, 0x55, 0xf0, 0x59, 0xd3, 0x9a, 0x94, 0x2f, 0x41, 0xdc, 0xee, }, }, { .name = "a-135", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 135, .exp = { 0x80, 0x94, 0xbb, 0x53, 0xc4, 0x4c, 0xfb, 0x1e, 0x67, 0xb7, 0xc3, 0x04, 0x47, 0xf9, 0xa1, 0xc3, 0x36, 0x96, 0xd2, 0x46, 0x3e, 0xcc, 0x1d, 0x9c, 0x92, 0x53, 0x89, 0x13, 0x39, 0x28, 0x43, 0xc9, }, }, { .name = "a-136", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 136, .exp = { 0x3f, 0xc5, 0x55, 0x9f, 0x14, 0xdb, 0x8e, 0x45, 0x3a, 0x0a, 0x30, 0x91, 0xed, 0xbd, 0x2b, 0xc2, 0x5e, 0x11, 0x52, 0x8d, 0x81, 0xc6, 0x6f, 0xa5, 0x70, 0xa4, 0xef, 0xdc, 0xc2, 0x69, 0x5e, 0xe1, }, }, { .name = "ff-256", .msg = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, .len = 256, .exp = { 0xea, 0xa5, 0x7c, 0x69, 0x9a, 0x7a, 0x61, 0x4f, 0x9d, 0x96, 0x1e, 0x42, 0xd8, 0xb1, 0x2a, 0x93, 0x54, 0x6e, 0x8e, 0x80, 0xd3, 0x1f, 0x5c, 0xfc, 0xc4, 0x3f, 0x95, 0x39, 0xed, 0x06, 0x30, 0x7a, }, }, { .name = "a-210", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 210, .exp = { 0xb4, 0x12, 0xbd, 0x70, 0xce, 0x67, 0xeb, 0x59, 0x0b, 0xb2, 0x25, 0x09, 0xef, 0x4e, 0x68, 0x7e, 0x02, 0xb4, 0x8e, 0x07, 0xd2, 0xbb, 0xd7, 0xbb, 0x9a, 0xfb, 0x58, 0x70, 0xfd, 0x14, 0xc1, 0x13, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { uint8_t got[32] = { 0 }; sha3_256(tests[i].msg, tests[i].len, got); if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_sha3_256(\"%s\") failed, got:\n", tests[i].name); dump_hex(stderr, got, 32); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 32); } } } static void test_sha3_384(void) { static const struct { const char *name; // test name const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[48]; // expected hash } tests[] = {{ .name = "empty", .msg = "", .len = 0, .exp = { 0x0c, 0x63, 0xa7, 0x5b, 0x84, 0x5e, 0x4f, 0x7d, 0x01, 0x10, 0x7d, 0x85, 0x2e, 0x4c, 0x24, 0x85, 0xc5, 0x1a, 0x50, 0xaa, 0xaa, 0x94, 0xfc, 0x61, 0x99, 0x5e, 0x71, 0xbb, 0xee, 0x98, 0x3a, 0x2a, 0xc3, 0x71, 0x38, 0x31, 0x26, 0x4a, 0xdb, 0x47, 0xfb, 0x6b, 0xd1, 0xe0, 0x58, 0xd5, 0xf0, 0x04, }, }, { .name = "asdf", .msg = "asdf", .len = 4, .exp = { 0xcc, 0x8c, 0x24, 0x61, 0xa8, 0xac, 0xb5, 0x8c, 0x9e, 0x7b, 0x78, 0x95, 0x8e, 0xa3, 0x6d, 0x5f, 0xd3, 0x20, 0x38, 0xf9, 0x58, 0xcd, 0xbb, 0x59, 0xf2, 0x6b, 0x0f, 0xfd, 0x1c, 0x36, 0x57, 0x61, 0x83, 0xe1, 0xc2, 0xca, 0x33, 0x57, 0xca, 0x1e, 0x33, 0x3a, 0x11, 0xaf, 0xac, 0x8a, 0xed, 0xe6, }, }, { .name = "a-134", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 134, .exp = { 0xac, 0x8b, 0xca, 0x5d, 0x14, 0xed, 0xb5, 0xfc, 0x82, 0xe2, 0x2e, 0x45, 0x33, 0x34, 0xcb, 0x39, 0xef, 0x43, 0x14, 0xa5, 0x9a, 0xd7, 0xba, 0x6f, 0xb1, 0x0f, 0x0b, 0x11, 0xbe, 0x7b, 0x4a, 0xf3, 0xfd, 0xe3, 0xe9, 0x54, 0x07, 0x81, 0xc2, 0x39, 0xfa, 0x4c, 0x1f, 0x60, 0x44, 0xf3, 0x1d, 0xa9, }, }, { .name = "a-135", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 135, .exp = { 0xa2, 0xd5, 0x19, 0x07, 0xc0, 0x61, 0x1e, 0x25, 0xc0, 0x58, 0xf0, 0x67, 0x50, 0x42, 0xe8, 0xf5, 0x3c, 0xc4, 0x73, 0xdc, 0x34, 0x7c, 0x5e, 0xa8, 0xa8, 0x13, 0xd8, 0x86, 0xb3, 0xaa, 0x8f, 0x8d, 0xca, 0xb6, 0x1a, 0x23, 0x62, 0x37, 0xd9, 0x4d, 0xe4, 0x04, 0xcd, 0x66, 0x60, 0x62, 0x43, 0xf9, }, }, { .name = "a-136", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 136, .exp = { 0xcb, 0xbc, 0xb4, 0x66, 0x41, 0x7a, 0x2f, 0x6d, 0x46, 0x64, 0x79, 0xbb, 0x6d, 0xc6, 0x59, 0x43, 0x4d, 0x95, 0x89, 0xde, 0x3a, 0x53, 0xac, 0xc9, 0xb4, 0x27, 0x58, 0x04, 0x82, 0xe3, 0x05, 0x94, 0x88, 0x88, 0xc8, 0xfa, 0x6d, 0x06, 0x9c, 0x5e, 0x6a, 0x89, 0x9a, 0xa3, 0x4a, 0x9a, 0xf1, 0x5a, }, }, { .name = "ff-256", .msg = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, .len = 256, .exp = { 0x91, 0xb2, 0xc0, 0xab, 0x2c, 0xe3, 0x31, 0xcd, 0x59, 0xab, 0x98, 0x3b, 0x87, 0xaf, 0xc9, 0xe5, 0x45, 0x66, 0x33, 0xb1, 0x30, 0x49, 0xac, 0x84, 0x36, 0x04, 0xc9, 0xb6, 0xc3, 0xab, 0x09, 0xc3, 0x5c, 0xf8, 0x8c, 0xcb, 0xf7, 0x61, 0xc5, 0x64, 0x7c, 0x92, 0x2b, 0xcc, 0x9b, 0x37, 0x5a, 0x6b, }, }, { .name = "a-210", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 210, .exp = { 0x23, 0x2f, 0xba, 0x5c, 0x81, 0x59, 0x36, 0xc7, 0x7b, 0x37, 0x3a, 0x5e, 0x5d, 0xa0, 0xd2, 0xca, 0x3b, 0x15, 0xcd, 0x28, 0x58, 0x92, 0x66, 0x14, 0x5a, 0x92, 0xd6, 0x50, 0xfa, 0x58, 0xef, 0x4f, 0xdf, 0xa3, 0x4e, 0x9e, 0x2f, 0x0e, 0xa8, 0x7a, 0x67, 0x32, 0x8f, 0x68, 0x9a, 0x6b, 0x8f, 0x04, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { uint8_t got[48] = { 0 }; sha3_384(tests[i].msg, tests[i].len, got); if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_sha3_384(\"%s\") failed, got:\n", tests[i].name); dump_hex(stderr, got, 48); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 48); } } } static void test_sha3_512(void) { static const struct { const char *name; // test name const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[64]; // expected hash } tests[] = {{ .name = "empty", .msg = "", .len = 0, .exp = { 0xa6, 0x9f, 0x73, 0xcc, 0xa2, 0x3a, 0x9a, 0xc5, 0xc8, 0xb5, 0x67, 0xdc, 0x18, 0x5a, 0x75, 0x6e, 0x97, 0xc9, 0x82, 0x16, 0x4f, 0xe2, 0x58, 0x59, 0xe0, 0xd1, 0xdc, 0xc1, 0x47, 0x5c, 0x80, 0xa6, 0x15, 0xb2, 0x12, 0x3a, 0xf1, 0xf5, 0xf9, 0x4c, 0x11, 0xe3, 0xe9, 0x40, 0x2c, 0x3a, 0xc5, 0x58, 0xf5, 0x00, 0x19, 0x9d, 0x95, 0xb6, 0xd3, 0xe3, 0x01, 0x75, 0x85, 0x86, 0x28, 0x1d, 0xcd, 0x26, }, }, { .name = "asdf", .msg = "asdf", .len = 4, .exp = { 0x8d, 0x88, 0xcf, 0x5b, 0x20, 0xf5, 0x3a, 0xcd, 0x7a, 0xe1, 0x47, 0x9b, 0x5b, 0x36, 0xdc, 0x20, 0x21, 0x75, 0x3b, 0x04, 0x99, 0x02, 0xc7, 0x72, 0x47, 0xbb, 0x27, 0xb1, 0x31, 0xb3, 0x00, 0xbd, 0x3c, 0xa8, 0xbe, 0xef, 0x28, 0x75, 0x6d, 0xce, 0x27, 0xb8, 0x99, 0x08, 0x67, 0xc4, 0x57, 0x7a, 0x25, 0x35, 0xe7, 0xe3, 0xb7, 0x51, 0x41, 0x39, 0x9c, 0xa1, 0xa9, 0x4c, 0xc8, 0x4b, 0x0e, 0xb9, }, }, { .name = "a-134", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 134, .exp = { 0x4e, 0x72, 0xa4, 0xf6, 0x55, 0x99, 0xa2, 0x47, 0x2a, 0x66, 0xf8, 0xa8, 0xd6, 0xcf, 0xb3, 0x84, 0xb7, 0xd3, 0x4f, 0x52, 0xec, 0xaa, 0x00, 0xe9, 0xf0, 0x66, 0x82, 0x0b, 0x0e, 0xdc, 0x1f, 0xcc, 0x9c, 0xf3, 0x12, 0x0b, 0x81, 0x46, 0x89, 0xbc, 0x62, 0xb7, 0x72, 0x0f, 0x4e, 0x4c, 0x99, 0x3d, 0xa0, 0x84, 0x08, 0x27, 0xf6, 0x95, 0x03, 0x8a, 0x82, 0x18, 0x69, 0xe8, 0xa6, 0x27, 0x60, 0xe8, }, }, { .name = "a-135", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 135, .exp = { 0x4b, 0xe1, 0xe7, 0x02, 0x76, 0xf9, 0x12, 0x2f, 0x47, 0x0a, 0x54, 0xc2, 0x72, 0x40, 0xc7, 0xd0, 0x70, 0x9d, 0xab, 0x74, 0x69, 0x95, 0x8b, 0x48, 0xa9, 0x50, 0xd6, 0x9d, 0xa6, 0xdd, 0x07, 0xca, 0x13, 0x58, 0x26, 0xd9, 0xd2, 0x3e, 0x97, 0x5c, 0xb9, 0x28, 0x3e, 0x7d, 0x23, 0x6e, 0xf9, 0x8a, 0x80, 0x45, 0x1d, 0xca, 0x8e, 0x31, 0x1f, 0x52, 0x09, 0x63, 0x08, 0xb2, 0xc8, 0xd7, 0x0c, 0xc7, }, }, { .name = "a-136", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 136, .exp = { 0xe5, 0x03, 0x92, 0xc9, 0x1e, 0xd9, 0x57, 0x68, 0xc8, 0xdc, 0xf5, 0x2a, 0x12, 0xe5, 0xdb, 0x1e, 0xcd, 0x03, 0x47, 0xfb, 0x99, 0x5f, 0x7f, 0xf4, 0xea, 0x06, 0x99, 0x46, 0x49, 0xbb, 0xd1, 0xa0, 0xde, 0x7a, 0xe3, 0x6a, 0x62, 0xaa, 0xdc, 0x00, 0xa7, 0x04, 0xd7, 0x30, 0xb5, 0x2b, 0xda, 0x19, 0x1b, 0x72, 0x95, 0x1e, 0x2a, 0xfc, 0x9b, 0x6f, 0xb6, 0x82, 0x47, 0x87, 0xb2, 0x08, 0x62, 0x57, }, }, { .name = "ff-256", .msg = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, .len = 256, .exp = { 0x02, 0x3a, 0x91, 0x27, 0xcf, 0x29, 0x6d, 0x01, 0x12, 0x0e, 0x3d, 0xaa, 0x92, 0x76, 0x15, 0x23, 0x8e, 0x97, 0xdd, 0xb6, 0x33, 0x26, 0xe2, 0x89, 0xb3, 0x31, 0xe2, 0x25, 0xbe, 0x41, 0xea, 0xd5, 0x90, 0xf1, 0xdd, 0x5c, 0x80, 0x1d, 0x91, 0x03, 0xfe, 0x65, 0x7d, 0x23, 0x63, 0xbd, 0xb2, 0x66, 0xe7, 0x90, 0xb1, 0x89, 0x0b, 0x3d, 0xd5, 0x79, 0xdc, 0xa7, 0xf9, 0x1f, 0x5f, 0x4d, 0x98, 0x49, }, }, { .name = "a-210", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 210, .exp = { 0x47, 0xfa, 0xd7, 0x8d, 0x72, 0x35, 0xe5, 0xcd, 0xb9, 0xd7, 0x23, 0x6c, 0xfc, 0xf2, 0x79, 0xdb, 0x0f, 0x8a, 0xcd, 0x5b, 0xf1, 0x7b, 0xdc, 0x74, 0x18, 0xe4, 0x29, 0xb7, 0x1a, 0x0a, 0x21, 0xb7, 0xed, 0xe8, 0x54, 0x64, 0xcf, 0x69, 0x44, 0x63, 0xff, 0x0e, 0x56, 0xf2, 0x8f, 0x04, 0xbf, 0x85, 0xc0, 0x85, 0xe1, 0x17, 0x6a, 0x47, 0xd7, 0x3b, 0xf2, 0x8b, 0xdb, 0xa0, 0x4f, 0x4a, 0xe7, 0x61, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { uint8_t got[64] = { 0 }; sha3_512(tests[i].msg, tests[i].len, got); if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_sha3_512(\"%s\") failed, got:\n", tests[i].name); dump_hex(stderr, got, 64); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 64); } } } static void test_shake128(void) { static const struct { const char *name; // test name const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[16]; // expected hash } tests[] = {{ .name = "empty", .msg = "", .len = 0, .exp = { 0x7f, 0x9c, 0x2b, 0xa4, 0xe8, 0x8f, 0x82, 0x7d, 0x61, 0x60, 0x45, 0x50, 0x76, 0x05, 0x85, 0x3e, }, }, { .name = "asdf", .msg = "asdf", .len = 4, .exp = { 0xef, 0x02, 0x2c, 0xc5, 0x3c, 0x74, 0xb3, 0x28, 0x43, 0xf9, 0xc1, 0xf1, 0x14, 0x13, 0xd5, 0x9c, }, }, { .name = "a-134", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 134, .exp = { 0xc8, 0x73, 0x5e, 0x5f, 0x6f, 0x15, 0xaf, 0xe5, 0x1a, 0x8c, 0x3b, 0x07, 0xc4, 0xc6, 0x8d, 0x86, }, }, { .name = "a-135", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 135, .exp = { 0xa5, 0xe2, 0xb2, 0x27, 0x8d, 0x1b, 0x75, 0x86, 0x6c, 0x78, 0x77, 0xa0, 0xff, 0xa2, 0x47, 0x37, }, }, { .name = "a-136", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 136, .exp = { 0x0d, 0x01, 0x58, 0xd4, 0x46, 0x78, 0x3a, 0x9b, 0x18, 0xa6, 0x90, 0x8c, 0x08, 0xbb, 0x5d, 0xe6, }, }, { .name = "ff-256", .msg = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, .len = 256, .exp = { 0xf3, 0x06, 0x93, 0x04, 0x16, 0x5c, 0x0e, 0xad, 0x13, 0x25, 0xb5, 0x26, 0x76, 0x05, 0x95, 0xed, }, }, { .name = "a-210", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 210, .exp = { 0xb1, 0xb4, 0xf3, 0xad, 0x3a, 0x1f, 0x67, 0x60, 0xe3, 0x08, 0x67, 0xdd, 0x71, 0xb3, 0x49, 0xfa, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { uint8_t got[16] = { 0 }; shake128(tests[i].msg, tests[i].len, got); if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_shake128(\"%s\") failed, got:\n", tests[i].name); dump_hex(stderr, got, 16); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 16); } } } static void test_shake256(void) { static const struct { const char *name; // test name const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[32]; // expected hash } tests[] = {{ .name = "empty", .msg = "", .len = 0, .exp = { 0x46, 0xb9, 0xdd, 0x2b, 0x0b, 0xa8, 0x8d, 0x13, 0x23, 0x3b, 0x3f, 0xeb, 0x74, 0x3e, 0xeb, 0x24, 0x3f, 0xcd, 0x52, 0xea, 0x62, 0xb8, 0x1b, 0x82, 0xb5, 0x0c, 0x27, 0x64, 0x6e, 0xd5, 0x76, 0x2f, }, }, { .name = "asdf", .msg = "asdf", .len = 4, .exp = { 0xf0, 0x0c, 0x15, 0x64, 0x33, 0x96, 0x61, 0x6a, 0x89, 0xa0, 0xcb, 0x79, 0x03, 0x9f, 0x74, 0x05, 0x75, 0xde, 0xfe, 0x9d, 0xbe, 0x30, 0x7c, 0xcc, 0xda, 0xf8, 0xae, 0x21, 0x0e, 0x1c, 0x9c, 0xc6, }, }, { .name = "a-134", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 134, .exp = { 0xf1, 0xe0, 0x3f, 0x37, 0x8e, 0xb7, 0x79, 0x04, 0xba, 0x15, 0xbb, 0x64, 0x2a, 0x84, 0xb9, 0x0d, 0xe5, 0x2e, 0x29, 0x3e, 0xaf, 0xc2, 0x7c, 0xef, 0x05, 0x88, 0x3b, 0x16, 0x56, 0xae, 0xc3, 0x41, }, }, { .name = "a-135", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 135, .exp = { 0x55, 0xb9, 0x91, 0xec, 0xe1, 0xe5, 0x67, 0xb6, 0xe7, 0xc2, 0xc7, 0x14, 0x44, 0x4d, 0xd2, 0x01, 0xcd, 0x51, 0xf4, 0xf3, 0x83, 0x2d, 0x08, 0xe1, 0xd2, 0x6b, 0xeb, 0xc6, 0x3e, 0x07, 0xa3, 0xd7, }, }, { .name = "a-136", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 136, .exp = { 0x8f, 0xcc, 0x5a, 0x08, 0xf0, 0xa1, 0xf6, 0x82, 0x7c, 0x9c, 0xf6, 0x4e, 0xe8, 0xd1, 0x6e, 0x04, 0x43, 0x10, 0x63, 0x59, 0xca, 0x6c, 0x8e, 0xfd, 0x23, 0x07, 0x59, 0x25, 0x6f, 0x44, 0x99, 0x6a, }, }, { .name = "ff-256", .msg = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, .len = 256, .exp = { 0x3f, 0x25, 0xdf, 0x0e, 0x37, 0x17, 0x14, 0xdf, 0xb0, 0xcc, 0x3d, 0x96, 0x17, 0xe1, 0xa0, 0x71, 0x75, 0xa0, 0xf0, 0x84, 0xc7, 0x00, 0x29, 0x23, 0x5c, 0x72, 0x7c, 0x5a, 0x68, 0x5e, 0xf0, 0x14, }, }, { .name = "a-210", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 210, .exp = { 0xc9, 0xe2, 0xd9, 0x58, 0xf2, 0xdd, 0x3d, 0x97, 0x53, 0x8a, 0x1b, 0xac, 0x1b, 0x4e, 0xb3, 0x2e, 0x28, 0x23, 0x6b, 0x5d, 0xfc, 0xe0, 0x29, 0xfc, 0xc8, 0x73, 0xc0, 0xf2, 0x70, 0xe1, 0x3e, 0x9f, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { uint8_t got[32] = { 0 }; shake256(tests[i].msg, tests[i].len, got); if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_shake256(\"%s\") failed, got:\n", tests[i].name); dump_hex(stderr, got, 32); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 32); } } } static void test_shake128_xof(void) { static const struct { const char *name; // test name const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[16]; // expected hash } tests[] = {{ .name = "empty", .msg = "", .len = 0, .exp = { 0x7f, 0x9c, 0x2b, 0xa4, 0xe8, 0x8f, 0x82, 0x7d, 0x61, 0x60, 0x45, 0x50, 0x76, 0x05, 0x85, 0x3e, }, }, { .name = "asdf", .msg = "asdf", .len = 4, .exp = { 0xef, 0x02, 0x2c, 0xc5, 0x3c, 0x74, 0xb3, 0x28, 0x43, 0xf9, 0xc1, 0xf1, 0x14, 0x13, 0xd5, 0x9c, }, }, { .name = "a-134", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 134, .exp = { 0xc8, 0x73, 0x5e, 0x5f, 0x6f, 0x15, 0xaf, 0xe5, 0x1a, 0x8c, 0x3b, 0x07, 0xc4, 0xc6, 0x8d, 0x86, }, }, { .name = "a-135", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 135, .exp = { 0xa5, 0xe2, 0xb2, 0x27, 0x8d, 0x1b, 0x75, 0x86, 0x6c, 0x78, 0x77, 0xa0, 0xff, 0xa2, 0x47, 0x37, }, }, { .name = "a-136", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 136, .exp = { 0x0d, 0x01, 0x58, 0xd4, 0x46, 0x78, 0x3a, 0x9b, 0x18, 0xa6, 0x90, 0x8c, 0x08, 0xbb, 0x5d, 0xe6, }, }, { .name = "ff-256", .msg = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, .len = 256, .exp = { 0xf3, 0x06, 0x93, 0x04, 0x16, 0x5c, 0x0e, 0xad, 0x13, 0x25, 0xb5, 0x26, 0x76, 0x05, 0x95, 0xed, }, }, { .name = "a-210", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 210, .exp = { 0xb1, 0xb4, 0xf3, 0xad, 0x3a, 0x1f, 0x67, 0x60, 0xe3, 0x08, 0x67, 0xdd, 0x71, 0xb3, 0x49, 0xfa, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { for (size_t len = 1; len < tests[i].len; len++) { // init xof sha3_xof_t xof; shake128_xof_init(&xof); // absorb for (size_t ofs = 0; ofs < tests[i].len; ofs += len) { const size_t absorb_len = MIN(tests[i].len - ofs, len); if (!shake128_xof_absorb(&xof, tests[i].msg + ofs, absorb_len)) { fprintf(stderr, "test_shake128_xof(\"%s\", %zu) failed: shake128_xof_absorb()\n", tests[i].name, len); return; } } // squeeze uint8_t got[16] = { 0 }; shake128_xof_squeeze(&xof, got, sizeof(got)); // check if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_shake128_xof(\"%s\", %zu) failed, got:\n", tests[i].name, len); dump_hex(stderr, got, 16); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 16); } } } } static void test_shake128_xof_once(void) { static const struct { const char *name; // test name const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[16]; // expected hash } tests[] = {{ .name = "empty", .msg = "", .len = 0, .exp = { 0x7f, 0x9c, 0x2b, 0xa4, 0xe8, 0x8f, 0x82, 0x7d, 0x61, 0x60, 0x45, 0x50, 0x76, 0x05, 0x85, 0x3e, }, }, { .name = "asdf", .msg = "asdf", .len = 4, .exp = { 0xef, 0x02, 0x2c, 0xc5, 0x3c, 0x74, 0xb3, 0x28, 0x43, 0xf9, 0xc1, 0xf1, 0x14, 0x13, 0xd5, 0x9c, }, }, { .name = "a-134", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 134, .exp = { 0xc8, 0x73, 0x5e, 0x5f, 0x6f, 0x15, 0xaf, 0xe5, 0x1a, 0x8c, 0x3b, 0x07, 0xc4, 0xc6, 0x8d, 0x86, }, }, { .name = "a-135", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 135, .exp = { 0xa5, 0xe2, 0xb2, 0x27, 0x8d, 0x1b, 0x75, 0x86, 0x6c, 0x78, 0x77, 0xa0, 0xff, 0xa2, 0x47, 0x37, }, }, { .name = "a-136", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 136, .exp = { 0x0d, 0x01, 0x58, 0xd4, 0x46, 0x78, 0x3a, 0x9b, 0x18, 0xa6, 0x90, 0x8c, 0x08, 0xbb, 0x5d, 0xe6, }, }, { .name = "ff-256", .msg = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, .len = 256, .exp = { 0xf3, 0x06, 0x93, 0x04, 0x16, 0x5c, 0x0e, 0xad, 0x13, 0x25, 0xb5, 0x26, 0x76, 0x05, 0x95, 0xed, }, }, { .name = "a-210", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 210, .exp = { 0xb1, 0xb4, 0xf3, 0xad, 0x3a, 0x1f, 0x67, 0x60, 0xe3, 0x08, 0x67, 0xdd, 0x71, 0xb3, 0x49, 0xfa, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { for (size_t len = 1; len < tests[i].len; len++) { // run uint8_t got[16]; shake128_xof_once(tests[i].msg, tests[i].len, got, sizeof(got)); // check if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_shake128_xof_once(\"%s\", %zu) failed, got:\n", tests[i].name, len); dump_hex(stderr, got, 16); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 16); } } } } static void test_shake256_xof(void) { static const struct { const char *name; // test name const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[32]; // expected hash } tests[] = {{ .name = "empty", .msg = "", .len = 0, .exp = { 0x46, 0xb9, 0xdd, 0x2b, 0x0b, 0xa8, 0x8d, 0x13, 0x23, 0x3b, 0x3f, 0xeb, 0x74, 0x3e, 0xeb, 0x24, 0x3f, 0xcd, 0x52, 0xea, 0x62, 0xb8, 0x1b, 0x82, 0xb5, 0x0c, 0x27, 0x64, 0x6e, 0xd5, 0x76, 0x2f, }, }, { .name = "asdf", .msg = "asdf", .len = 4, .exp = { 0xf0, 0x0c, 0x15, 0x64, 0x33, 0x96, 0x61, 0x6a, 0x89, 0xa0, 0xcb, 0x79, 0x03, 0x9f, 0x74, 0x05, 0x75, 0xde, 0xfe, 0x9d, 0xbe, 0x30, 0x7c, 0xcc, 0xda, 0xf8, 0xae, 0x21, 0x0e, 0x1c, 0x9c, 0xc6, }, }, { .name = "a-134", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 134, .exp = { 0xf1, 0xe0, 0x3f, 0x37, 0x8e, 0xb7, 0x79, 0x04, 0xba, 0x15, 0xbb, 0x64, 0x2a, 0x84, 0xb9, 0x0d, 0xe5, 0x2e, 0x29, 0x3e, 0xaf, 0xc2, 0x7c, 0xef, 0x05, 0x88, 0x3b, 0x16, 0x56, 0xae, 0xc3, 0x41, }, }, { .name = "a-135", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 135, .exp = { 0x55, 0xb9, 0x91, 0xec, 0xe1, 0xe5, 0x67, 0xb6, 0xe7, 0xc2, 0xc7, 0x14, 0x44, 0x4d, 0xd2, 0x01, 0xcd, 0x51, 0xf4, 0xf3, 0x83, 0x2d, 0x08, 0xe1, 0xd2, 0x6b, 0xeb, 0xc6, 0x3e, 0x07, 0xa3, 0xd7, }, }, { .name = "a-136", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 136, .exp = { 0x8f, 0xcc, 0x5a, 0x08, 0xf0, 0xa1, 0xf6, 0x82, 0x7c, 0x9c, 0xf6, 0x4e, 0xe8, 0xd1, 0x6e, 0x04, 0x43, 0x10, 0x63, 0x59, 0xca, 0x6c, 0x8e, 0xfd, 0x23, 0x07, 0x59, 0x25, 0x6f, 0x44, 0x99, 0x6a, }, }, { .name = "ff-256", .msg = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, .len = 256, .exp = { 0x3f, 0x25, 0xdf, 0x0e, 0x37, 0x17, 0x14, 0xdf, 0xb0, 0xcc, 0x3d, 0x96, 0x17, 0xe1, 0xa0, 0x71, 0x75, 0xa0, 0xf0, 0x84, 0xc7, 0x00, 0x29, 0x23, 0x5c, 0x72, 0x7c, 0x5a, 0x68, 0x5e, 0xf0, 0x14, }, }, { .name = "a-210", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 210, .exp = { 0xc9, 0xe2, 0xd9, 0x58, 0xf2, 0xdd, 0x3d, 0x97, 0x53, 0x8a, 0x1b, 0xac, 0x1b, 0x4e, 0xb3, 0x2e, 0x28, 0x23, 0x6b, 0x5d, 0xfc, 0xe0, 0x29, 0xfc, 0xc8, 0x73, 0xc0, 0xf2, 0x70, 0xe1, 0x3e, 0x9f, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { for (size_t len = 1; len < tests[i].len; len++) { // init xof sha3_xof_t xof; shake256_xof_init(&xof); // absorb for (size_t ofs = 0; ofs < tests[i].len; ofs += len) { const size_t absorb_len = MIN(tests[i].len - ofs, len); if (!shake256_xof_absorb(&xof, tests[i].msg + ofs, absorb_len)) { fprintf(stderr, "test_shake256_xof(\"%s\", %zu) failed: shake256_xof_absorb()\n", tests[i].name, len); return; } } // squeeze uint8_t got[32] = { 0 }; shake256_xof_squeeze(&xof, got, sizeof(got)); // check if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_shake256_xof(\"%s\", %zu) failed, got:\n", tests[i].name, len); dump_hex(stderr, got, 16); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 16); } } } } static void test_shake256_xof_once(void) { static const struct { const char *name; // test name const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[32]; // expected hash } tests[] = {{ .name = "empty", .msg = "", .len = 0, .exp = { 0x46, 0xb9, 0xdd, 0x2b, 0x0b, 0xa8, 0x8d, 0x13, 0x23, 0x3b, 0x3f, 0xeb, 0x74, 0x3e, 0xeb, 0x24, 0x3f, 0xcd, 0x52, 0xea, 0x62, 0xb8, 0x1b, 0x82, 0xb5, 0x0c, 0x27, 0x64, 0x6e, 0xd5, 0x76, 0x2f, }, }, { .name = "asdf", .msg = "asdf", .len = 4, .exp = { 0xf0, 0x0c, 0x15, 0x64, 0x33, 0x96, 0x61, 0x6a, 0x89, 0xa0, 0xcb, 0x79, 0x03, 0x9f, 0x74, 0x05, 0x75, 0xde, 0xfe, 0x9d, 0xbe, 0x30, 0x7c, 0xcc, 0xda, 0xf8, 0xae, 0x21, 0x0e, 0x1c, 0x9c, 0xc6, }, }, { .name = "a-134", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 134, .exp = { 0xf1, 0xe0, 0x3f, 0x37, 0x8e, 0xb7, 0x79, 0x04, 0xba, 0x15, 0xbb, 0x64, 0x2a, 0x84, 0xb9, 0x0d, 0xe5, 0x2e, 0x29, 0x3e, 0xaf, 0xc2, 0x7c, 0xef, 0x05, 0x88, 0x3b, 0x16, 0x56, 0xae, 0xc3, 0x41, }, }, { .name = "a-135", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 135, .exp = { 0x55, 0xb9, 0x91, 0xec, 0xe1, 0xe5, 0x67, 0xb6, 0xe7, 0xc2, 0xc7, 0x14, 0x44, 0x4d, 0xd2, 0x01, 0xcd, 0x51, 0xf4, 0xf3, 0x83, 0x2d, 0x08, 0xe1, 0xd2, 0x6b, 0xeb, 0xc6, 0x3e, 0x07, 0xa3, 0xd7, }, }, { .name = "a-136", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 136, .exp = { 0x8f, 0xcc, 0x5a, 0x08, 0xf0, 0xa1, 0xf6, 0x82, 0x7c, 0x9c, 0xf6, 0x4e, 0xe8, 0xd1, 0x6e, 0x04, 0x43, 0x10, 0x63, 0x59, 0xca, 0x6c, 0x8e, 0xfd, 0x23, 0x07, 0x59, 0x25, 0x6f, 0x44, 0x99, 0x6a, }, }, { .name = "ff-256", .msg = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, .len = 256, .exp = { 0x3f, 0x25, 0xdf, 0x0e, 0x37, 0x17, 0x14, 0xdf, 0xb0, 0xcc, 0x3d, 0x96, 0x17, 0xe1, 0xa0, 0x71, 0x75, 0xa0, 0xf0, 0x84, 0xc7, 0x00, 0x29, 0x23, 0x5c, 0x72, 0x7c, 0x5a, 0x68, 0x5e, 0xf0, 0x14, }, }, { .name = "a-210", .msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", .len = 210, .exp = { 0xc9, 0xe2, 0xd9, 0x58, 0xf2, 0xdd, 0x3d, 0x97, 0x53, 0x8a, 0x1b, 0xac, 0x1b, 0x4e, 0xb3, 0x2e, 0x28, 0x23, 0x6b, 0x5d, 0xfc, 0xe0, 0x29, 0xfc, 0xc8, 0x73, 0xc0, 0xf2, 0x70, 0xe1, 0x3e, 0x9f, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { for (size_t len = 1; len < tests[i].len; len++) { // run shake256 uint8_t got[32]; shake256_xof_once(tests[i].msg, tests[i].len, got, sizeof(got)); // check if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_shake256_xof_once(\"%s\", %zu) failed, got:\n", tests[i].name, len); dump_hex(stderr, got, 16); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 16); } } } } static void test_left_encode(void) { static const struct { const char *name; uint64_t val; uint8_t exp[9]; size_t exp_len; } tests[] = {{ .name = "zero", .val = 0, .exp = { 0x01, 0x00 }, .exp_len = 2, }, { .name = "120", .val = 120, .exp = { 0x01, 0x78 }, .exp_len = 2, }, { .name = "256", .val = 256, .exp = { 0x02, 0x01, 0x00 }, .exp_len = 3, }, { .name = "65535", .val = 65535, .exp = { 0x02, 0xff, 0xff }, .exp_len = 3, }, { .name = "65536", .val = 65536, .exp = { 0x03, 0x01, 0x00, 0x00 }, .exp_len = 4, }, { .name = "0xff00ff", .val = 0xff00ff, .exp = { 0x03, 0xff, 0x00, 0xff }, .exp_len = 4, }, { .name = "0x01000000", .val = 0x01000000, .exp = { 0x04, 0x01, 0x00, 0x00, 0x00 }, .exp_len = 5, }, { .name = "0xffffffff", .val = 0xffffffff, .exp = { 0x04, 0xff, 0xff, 0xff, 0xff }, .exp_len = 5, }, { .name = "0x0100000000", .val = 0x0100000000, .exp = { 0x05, 0x01, 0x00, 0x00, 0x00, 0x00 }, .exp_len = 6, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { uint8_t got[9]; const size_t got_len = left_encode(got, tests[i].val); // check length and data if (got_len != tests[i].exp_len) { fprintf(stderr, "test_left_encode(\"%s\") length check failed: got %zu, exp %zu:\n", tests[i].name, got_len, tests[i].exp_len); } else if (memcmp(got, tests[i].exp, got_len)) { fprintf(stderr, "test_left_encode(\"%s\") failed, got:\n", tests[i].name); dump_hex(stderr, got, got_len); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, got_len); } } } static void test_right_encode(void) { static const struct { const char *name; uint64_t val; uint8_t exp[9]; size_t exp_len; } tests[] = {{ .name = "zero", .val = 0, .exp = { 0x00, 0x01 }, .exp_len = 2, }, { .name = "120", .val = 120, .exp = { 0x78, 0x01 }, .exp_len = 2, }, { .name = "256", .val = 256, .exp = { 0x01, 0x00, 0x02 }, .exp_len = 3, }, { .name = "65535", .val = 65535, .exp = { 0xff, 0xff, 0x02 }, .exp_len = 3, }, { .name = "65536", .val = 65536, .exp = { 0x01, 0x00, 0x00, 0x03 }, .exp_len = 4, }, { .name = "0xff00ff", .val = 0xff00ff, .exp = { 0xff, 0x00, 0xff, 0x03 }, .exp_len = 4, }, { .name = "0x01000000", .val = 0x01000000, .exp = { 0x01, 0x00, 0x00, 0x00, 0x04 }, .exp_len = 5, }, { .name = "0xffffffff", .val = 0xffffffff, .exp = { 0xff, 0xff, 0xff, 0xff, 0x04 }, .exp_len = 5, }, { .name = "0x0100000000", .val = 0x0100000000, .exp = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x05 }, .exp_len = 6, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { uint8_t got[9]; const size_t got_len = right_encode(got, tests[i].val); // check length and data if (got_len != tests[i].exp_len) { fprintf(stderr, "test_right_encode(\"%s\") length check failed: got %zu, exp %zu:\n", tests[i].name, got_len, tests[i].exp_len); } else if (memcmp(got, tests[i].exp, got_len)) { fprintf(stderr, "test_right_encode(\"%s\") failed, got:\n", tests[i].name); dump_hex(stderr, got, got_len); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, got_len); } } } static void test_encode_string_prefix(void) { static const struct { const char *name; uint8_t val[256]; size_t val_len; uint8_t exp[9]; size_t exp_len; } tests[] = {{ .name = "empty", .val = "", .val_len = 0, .exp = { 0x01, 0x00 }, .exp_len = 2, }, { .name = "4", .val = "asdf", .val_len = 4, .exp = { 0x01, 0x20 }, .exp_len = 2, }, { .name = "31", .val = "asdfasdfasdfasdfasdfasdfasdfasd", .val_len = 31, .exp = { 0x01, 0xf8 }, .exp_len = 2, }, { .name = "32", .val = "asdfasdfasdfasdfasdfasdfasdfasdf", .val_len = 32, .exp = { 0x02, 0x01, 0x00 }, .exp_len = 3, }, { .name = "33", .val = "asdfasdfasdfasdfasdfasdfasdfasdfa", .val_len = 33, .exp = { 0x02, 0x01, 0x08 }, .exp_len = 3, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { uint8_t got[9]; const size_t got_len = encode_string_prefix(got, tests[i].val_len); // check length and data if (got_len != tests[i].exp_len) { fprintf(stderr, "test_encode_string_prefix(\"%s\") length check failed: got %zu, exp %zu:\n", tests[i].name, got_len, tests[i].exp_len); } else if (memcmp(got, tests[i].exp, got_len)) { fprintf(stderr, "test_encode_string_prefix(\"%s\") failed, got:\n", tests[i].name); dump_hex(stderr, got, got_len); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, got_len); } } } static void test_bytepad(void) { static const struct { const char *name; size_t data_len, width; uint8_t exp_prefix[9]; size_t exp_prefix_len, exp_pad_len; } tests[] = {{ .name = "0-10", .data_len = 0, .width = 10, .exp_prefix = { 0x01, 0x0a }, .exp_prefix_len = 2, .exp_pad_len = 8, }, { .name = "8-10", .data_len = 8, .width = 10, .exp_prefix = { 0x01, 0x0a }, .exp_prefix_len = 2, .exp_pad_len = 0, }, { .name = "9-10", .data_len = 9, .width = 10, .exp_prefix = { 0x01, 0x0a }, .exp_prefix_len = 2, .exp_pad_len = 9, }, { .name = "10-10", .data_len = 10, .width = 10, .exp_prefix = { 0x01, 0x0a }, .exp_prefix_len = 2, .exp_pad_len = 8, }, { .name = "11-10", .data_len = 11, .width = 10, .exp_prefix = { 0x01, 0x0a }, .exp_prefix_len = 2, .exp_pad_len = 7, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { const bytepad_t got = bytepad(tests[i].data_len, tests[i].width); // check prefix length and data if (got.prefix_len != tests[i].exp_prefix_len || got.pad_len != tests[i].exp_pad_len) { fprintf(stderr, "test_bytepad(\"%s\") length check failed:\n got: { %zu, %zu }\n exp: { %zu, %zu }\n", tests[i].name, got.prefix_len, got.pad_len, tests[i].exp_prefix_len, tests[i].exp_pad_len); } else if (memcmp(got.prefix, tests[i].exp_prefix, got.prefix_len)) { fprintf(stderr, "test_bytepad(\"%s\") failed, got:\n", tests[i].name); dump_hex(stderr, got.prefix, got.prefix_len); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp_prefix, got.prefix_len); } } } static void test_cshake128(void) { static const struct { const char *test_name; // test name const uint8_t name[256]; // nist function name const size_t name_len; // nist function name length const uint8_t custom[256]; // custom name const size_t custom_len; // custom name length const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[32]; // expected hash } tests[] = {{ // src: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/cSHAKE_samples.pdf .test_name = "cSHAKE Sample #1", .custom = "Email Signature", .custom_len = 15, .msg = { 0, 1, 2, 3 }, .len = 4, .exp = { 0xC1, 0xC3, 0x69, 0x25, 0xB6, 0x40, 0x9A, 0x04, 0xF1, 0xB5, 0x04, 0xFC, 0xBC, 0xA9, 0xD8, 0x2B, 0x40, 0x17, 0x27, 0x7C, 0xB5, 0xED, 0x2B, 0x20, 0x65, 0xFC, 0x1D, 0x38, 0x14, 0xD5, 0xAA, 0xF5, }, }, { // src: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/cSHAKE_samples.pdf .test_name = "cSHAKE Sample #2", .custom = "Email Signature", .custom_len = 15, .msg = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, }, .len = 200, .exp = { 0xC5, 0x22, 0x1D, 0x50, 0xE4, 0xF8, 0x22, 0xD9, 0x6A, 0x2E, 0x88, 0x81, 0xA9, 0x61, 0x42, 0x0F, 0x29, 0x4B, 0x7B, 0x24, 0xFE, 0x3D, 0x20, 0x94, 0xBA, 0xED, 0x2C, 0x65, 0x24, 0xCC, 0x16, 0x6B, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { const cshake_params_t params = { .name = tests[i].name, .name_len = tests[i].name_len, .custom = tests[i].custom, .custom_len = tests[i].custom_len, }; // run uint8_t got[32]; cshake128(params, tests[i].msg, tests[i].len, got, sizeof(got)); // check if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_cshake128(\"%s\") failed, got:\n", tests[i].test_name); dump_hex(stderr, got, 32); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 32); } } } static void test_cshake256(void) { static const struct { const char *test_name; // test name const uint8_t name[256]; // nist function name const size_t name_len; // nist function name length const uint8_t custom[256]; // custom name const size_t custom_len; // custom name length const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[64]; // expected hash } tests[] = {{ // src: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/cSHAKE_samples.pdf .test_name = "cSHAKE Sample #3", .custom = "Email Signature", .custom_len = 15, .msg = { 0, 1, 2, 3 }, .len = 4, .exp = { 0xD0, 0x08, 0x82, 0x8E, 0x2B, 0x80, 0xAC, 0x9D, 0x22, 0x18, 0xFF, 0xEE, 0x1D, 0x07, 0x0C, 0x48, 0xB8, 0xE4, 0xC8, 0x7B, 0xFF, 0x32, 0xC9, 0x69, 0x9D, 0x5B, 0x68, 0x96, 0xEE, 0xE0, 0xED, 0xD1, 0x64, 0x02, 0x0E, 0x2B, 0xE0, 0x56, 0x08, 0x58, 0xD9, 0xC0, 0x0C, 0x03, 0x7E, 0x34, 0xA9, 0x69, 0x37, 0xC5, 0x61, 0xA7, 0x4C, 0x41, 0x2B, 0xB4, 0xC7, 0x46, 0x46, 0x95, 0x27, 0x28, 0x1C, 0x8C, }, }, { // src: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/cSHAKE_samples.pdf .test_name = "cSHAKE Sample #4", .custom = "Email Signature", .custom_len = 15, .msg = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, }, .len = 200, .exp = { 0x07, 0xDC, 0x27, 0xB1, 0x1E, 0x51, 0xFB, 0xAC, 0x75, 0xBC, 0x7B, 0x3C, 0x1D, 0x98, 0x3E, 0x8B, 0x4B, 0x85, 0xFB, 0x1D, 0xEF, 0xAF, 0x21, 0x89, 0x12, 0xAC, 0x86, 0x43, 0x02, 0x73, 0x09, 0x17, 0x27, 0xF4, 0x2B, 0x17, 0xED, 0x1D, 0xF6, 0x3E, 0x8E, 0xC1, 0x18, 0xF0, 0x4B, 0x23, 0x63, 0x3C, 0x1D, 0xFB, 0x15, 0x74, 0xC8, 0xFB, 0x55, 0xCB, 0x45, 0xDA, 0x8E, 0x25, 0xAF, 0xB0, 0x92, 0xBB, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { const cshake_params_t params = { .name = tests[i].name, .name_len = tests[i].name_len, .custom = tests[i].custom, .custom_len = tests[i].custom_len, }; // run uint8_t got[32]; cshake256(params, tests[i].msg, tests[i].len, got, sizeof(got)); // check if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_cshake256(\"%s\") failed, got:\n", tests[i].test_name); dump_hex(stderr, got, 32); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 32); } } } static void test_kmac128(void) { static const struct { const char *name; // test name const uint8_t key[256]; // key const size_t key_len; // key length const uint8_t custom[256]; // custom name const size_t custom_len; // custom name length const uint8_t msg[256]; // test message const size_t len; // test message length const size_t dst_len; // output length const uint8_t exp[32]; // expected hash } tests[] = {{ // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/KMAC_samples.pdf .name = "KMAC128 Sample #1", .key = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, }, .key_len = 32, .custom = "", .custom_len = 0, .msg = { 0, 1, 2, 3 }, .len = 4, .exp = { 0xE5, 0x78, 0x0B, 0x0D, 0x3E, 0xA6, 0xF7, 0xD3, 0xA4, 0x29, 0xC5, 0x70, 0x6A, 0xA4, 0x3A, 0x00, 0xFA, 0xDB, 0xD7, 0xD4, 0x96, 0x28, 0x83, 0x9E, 0x31, 0x87, 0x24, 0x3F, 0x45, 0x6E, 0xE1, 0x4E, }, }, { .name = "KMAC128 Sample #2", .key = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, }, .key_len = 32, .custom = "My Tagged Application", .custom_len = 21, .msg = { 0, 1, 2, 3 }, .len = 4, .exp = { 0x3B, 0x1F, 0xBA, 0x96, 0x3C, 0xD8, 0xB0, 0xB5, 0x9E, 0x8C, 0x1A, 0x6D, 0x71, 0x88, 0x8B, 0x71, 0x43, 0x65, 0x1A, 0xF8, 0xBA, 0x0A, 0x70, 0x70, 0xC0, 0x97, 0x9E, 0x28, 0x11, 0x32, 0x4A, 0xA5, }, }, { .name = "KMAC128 Sample #3", .key = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, }, .key_len = 32, .custom = "My Tagged Application", .custom_len = 21, .msg = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, }, .len = 200, .exp = { 0x1F, 0x5B, 0x4E, 0x6C, 0xCA, 0x02, 0x20, 0x9E, 0x0D, 0xCB, 0x5C, 0xA6, 0x35, 0xB8, 0x9A, 0x15, 0xE2, 0x71, 0xEC, 0xC7, 0x60, 0x07, 0x1D, 0xFD, 0x80, 0x5F, 0xAA, 0x38, 0xF9, 0x72, 0x92, 0x30, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { const kmac_params_t params = { .key = tests[i].key, .key_len = tests[i].key_len, .custom = tests[i].custom, .custom_len = tests[i].custom_len, }; // run uint8_t got[32]; kmac128(params, tests[i].msg, tests[i].len, got, sizeof(got)); // check if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_kmac128(\"%s\") failed, got:\n", tests[i].name); dump_hex(stderr, got, 32); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 32); } } } static void test_kmac256(void) { static const struct { const char *name; // test name const uint8_t key[256]; // key const size_t key_len; // key length const uint8_t custom[256]; // custom name const size_t custom_len; // custom name length const uint8_t msg[256]; // test message const size_t len; // test message length const uint8_t exp[64]; // expected hash } tests[] = {{ // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/KMAC_samples.pdf .name = "KMAC256 Sample #4", .key = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, }, .key_len = 32, .custom = "My Tagged Application", .custom_len = 21, .msg = { 0, 1, 2, 3 }, .len = 4, .exp = { 0x20, 0xC5, 0x70, 0xC3, 0x13, 0x46, 0xF7, 0x03, 0xC9, 0xAC, 0x36, 0xC6, 0x1C, 0x03, 0xCB, 0x64, 0xC3, 0x97, 0x0D, 0x0C, 0xFC, 0x78, 0x7E, 0x9B, 0x79, 0x59, 0x9D, 0x27, 0x3A, 0x68, 0xD2, 0xF7, 0xF6, 0x9D, 0x4C, 0xC3, 0xDE, 0x9D, 0x10, 0x4A, 0x35, 0x16, 0x89, 0xF2, 0x7C, 0xF6, 0xF5, 0x95, 0x1F, 0x01, 0x03, 0xF3, 0x3F, 0x4F, 0x24, 0x87, 0x10, 0x24, 0xD9, 0xC2, 0x77, 0x73, 0xA8, 0xDD, }, }, { .name = "KMAC256 Sample #5", .key = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, }, .key_len = 32, .custom = "", .custom_len = 0, .msg = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, }, .len = 200, .exp = { 0x75, 0x35, 0x8C, 0xF3, 0x9E, 0x41, 0x49, 0x4E, 0x94, 0x97, 0x07, 0x92, 0x7C, 0xEE, 0x0A, 0xF2, 0x0A, 0x3F, 0xF5, 0x53, 0x90, 0x4C, 0x86, 0xB0, 0x8F, 0x21, 0xCC, 0x41, 0x4B, 0xCF, 0xD6, 0x91, 0x58, 0x9D, 0x27, 0xCF, 0x5E, 0x15, 0x36, 0x9C, 0xBB, 0xFF, 0x8B, 0x9A, 0x4C, 0x2E, 0xB1, 0x78, 0x00, 0x85, 0x5D, 0x02, 0x35, 0xFF, 0x63, 0x5D, 0xA8, 0x25, 0x33, 0xEC, 0x6B, 0x75, 0x9B, 0x69, }, }, { .name = "KMAC256 Sample #6", .key = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, }, .key_len = 32, .custom = "My Tagged Application", .custom_len = 21, .msg = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, }, .len = 200, .exp = { 0xB5, 0x86, 0x18, 0xF7, 0x1F, 0x92, 0xE1, 0xD5, 0x6C, 0x1B, 0x8C, 0x55, 0xDD, 0xD7, 0xCD, 0x18, 0x8B, 0x97, 0xB4, 0xCA, 0x4D, 0x99, 0x83, 0x1E, 0xB2, 0x69, 0x9A, 0x83, 0x7D, 0xA2, 0xE4, 0xD9, 0x70, 0xFB, 0xAC, 0xFD, 0xE5, 0x00, 0x33, 0xAE, 0xA5, 0x85, 0xF1, 0xA2, 0x70, 0x85, 0x10, 0xC3, 0x2D, 0x07, 0x88, 0x08, 0x01, 0xBD, 0x18, 0x28, 0x98, 0xFE, 0x47, 0x68, 0x76, 0xFC, 0x89, 0x65, }, }}; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { const kmac_params_t params = { .key = tests[i].key, .key_len = tests[i].key_len, .custom = tests[i].custom, .custom_len = tests[i].custom_len, }; // run uint8_t got[64]; kmac256(params, tests[i].msg, tests[i].len, got, sizeof(got)); // check if (memcmp(got, tests[i].exp, sizeof(got))) { fprintf(stderr, "test_kmac256(\"%s\") failed, got:\n", tests[i].name); dump_hex(stderr, got, 32); fprintf(stderr, "exp:\n"); dump_hex(stderr, tests[i].exp, 32); } } } int main(void) { test_theta(); test_rho(); test_pi(); test_chi(); test_iota(); test_permute(); test_sha3_224(); test_sha3_256(); test_sha3_384(); test_sha3_512(); test_shake128(); test_shake256(); test_shake128_xof(); test_shake128_xof_once(); test_shake256_xof(); test_shake256_xof_once(); test_left_encode(); test_right_encode(); test_encode_string_prefix(); test_bytepad(); test_cshake128(); test_cshake256(); test_kmac128(); test_kmac256(); printf("ok\n"); } #endif /* SHA3_TEST */