Closed falko-strenzke closed 1 year ago
We are currently working on the integration of PQC algorithms in Libgcrypt based on draft-wussler-openpgp-pqc and will also add KMAC to Libgcrypt since this algorithm is used for the key derivation inside the key combiner.
KMAC is based on cSHAKE, which is variant of SHAKE that requires a different final bit padding than SHAKE and is currently not implemented in Libgcrypt. cSHAKE is defined as
cSHAKE(X, L, N, S):
1. If N = "" and S = "":
return SHAKE256(X, L);
2. Else:
return KECCAK[256](bytepad(encode_string(N) || encode_string(S), 168) || X || 00, L)
In order to support the additional arguments N and S, I propose the following approach:
For the purpose of providing the additional arguments N and S we add
typedef enum
{
GCRY_MD_ADDIN_CSHAKE_N = 1,
GCRY_MD_ADDIN_CSHAKE_S = 2
} gcry_md_add_input_t;
gcry_error_t
gcry_md_set_add_input (gcry_md_hd_t *h,
gcry_md_add_input_t addin_type,
const void* v, size_t v_len)
In order to invoke cSHAKE with non-empty N and S parameters, after the call to _gcry_md_open()
, two calls to gcry_md_set_add_input()
have to be made to set N and S in that order. If data is added without having made these calls,
then it will behave as normal SHAKE as required by the specification.
Does anyone have any thoughts on this?
Answer from Jussi Kivilinna jussi.kivilinna@iki.fi
I checked cSHAKE spec and think that interface is good way for passing these parameters. I first thought about having user to pass encoded N and S to gcry_md_write but that would mean that user needs to implement encode_string function from cSHAKE spec which would not work.
One additional thing to consider is the _gcry_md_hash_buffers_extract internal interface. There cSHAKE could take first two IO buffers as N and S strings and following buffers as actual data. This would be similar to how HMAC work through this interface, where first IO buffer is used as HMAC key and remaining buffers as data.
-Jussi