aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sha3.c61
-rw-r--r--sha3.h11
2 files changed, 70 insertions, 2 deletions
diff --git a/sha3.c b/sha3.c
index b77d5ce..eef281f 100644
--- a/sha3.c
+++ b/sha3.c
@@ -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");
}
diff --git a/sha3.h b/sha3.h
index 99e15b5..aa75cd6 100644
--- a/sha3.h
+++ b/sha3.h
@@ -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 */