diff options
| -rw-r--r-- | sha3.c | 61 | ||||
| -rw-r--r-- | sha3.h | 11 | 
2 files changed, 70 insertions, 2 deletions
| @@ -669,6 +669,62 @@ void cshake256(    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); +} +  #ifdef SHA3_TEST  #include <stdio.h> // printf() @@ -2444,6 +2500,10 @@ static void test_cshake256(void) {    }  } +static void test_kmac128(void) { +  // TODO +} +  int main(void) {    test_theta();    test_rho(); @@ -2467,6 +2527,7 @@ int main(void) {    test_bytepad();    test_cshake128();    test_cshake256(); +  test_kmac128();    printf("ok\n");  } @@ -37,9 +37,9 @@ void shake256_xof_squeeze(sha3_xof_t * const xof, uint8_t * const dst, const siz  void shake256_xof_once(const uint8_t * const src, const size_t src_len, uint8_t * const dst, const size_t dst_len);  typedef struct { -  const uint8_t * const name; // NIST function name +  const uint8_t *name; // NIST function name    const size_t name_len; // length of NIST function name, in bytes -  const uint8_t * const custom; // customization string +  const uint8_t *custom; // customization string    const size_t custom_len; // length of customization string, in bytes  } cshake_params_t; @@ -54,6 +54,13 @@ void cshake256_xof_init(sha3_xof_t * const xof, const cshake_params_t params);  _Bool cshake256_xof_absorb(sha3_xof_t * const xof, const uint8_t * const msg, const size_t len);  void cshake256_xof_squeeze(sha3_xof_t * const xof, uint8_t * const dst, const size_t len); +typedef struct { +  const uint8_t *key; // key string +  const size_t key_len; // length of key string, in bytes +  const uint8_t *custom; // customization string +  const size_t custom_len; // length of customization string, in bytes +} kmac_params_t; +  #ifdef __cplusplus  }  #endif /* __cplusplus */ | 
