Mailing List Archive

KMAC / cSHAKE in Libgcrypt
We are currently working on the integration of PQC algorithms in
Libgcrypt based on draft-wussler-openpgp-pqc
<https://datatracker.ietf.org/doc/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
<https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf#page=16>
is based on cSHAKE
<https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf#page=13>,
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:

*

cSHAKE is added as an XOF message digest like SHAKE

*

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?

- Falko

--

*MTG AG*
Dr. Falko Strenzke
Executive System Architect

Phone: +49 6151 8000 24
E-Mail: falko.strenzke@mtg.de
Web: mtg.de <https://www.mtg.de>


*MTG Exhibitions – See you in 2023*

------------------------------------------------------------------------
<https://community.e-world-essen.com/institutions/allExhibitors?query=true&keywords=mtg>
<https://www.itsa365.de/de-de/companies/m/mtg-ag>

MTG AG - Dolivostr. 11 - 64293 Darmstadt, Germany
Commercial register: HRB 8901
Register Court: Amtsgericht Darmstadt
Management Board: Jürgen Ruf (CEO), Tamer Kemeröz
Chairman of the Supervisory Board: Dr. Thomas Milde

This email may contain confidential and/or privileged information. If
you are not the correct recipient or have received this email in error,
please inform the sender immediately and delete this email. Unauthorised
copying or distribution of this email is not permitted.

Data protection information: Privacy policy
<https://www.mtg.de/en/privacy-policy>
Re: KMAC / cSHAKE in Libgcrypt [ In reply to ]
Hello,

On 22.8.2023 14.49, Falko Strenzke wrote:
> We are currently working on the integration of PQC algorithms in Libgcrypt based on draft-wussler-openpgp-pqc <https://datatracker.ietf.org/doc/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 <https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf#page=16> is based on cSHAKE <https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf#page=13>, 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:
>
> *
>
> cSHAKE is added as an XOF message digest like SHAKE
>
> *
>
> 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?

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

>
> - Falko
>
> --
>
> *MTG AG*
> Dr. Falko Strenzke
> Executive System Architect
>
> Phone: +49 6151 8000 24
> E-Mail: falko.strenzke@mtg.de
> Web: mtg.de <https://www.mtg.de>
>
>
> *MTG Exhibitions – See you in 2023*
>
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> <https://community.e-world-essen.com/institutions/allExhibitors?query=true&keywords=mtg> <https://www.itsa365.de/de-de/companies/m/mtg-ag>
>
> MTG AG - Dolivostr. 11 - 64293 Darmstadt, Germany
> Commercial register: HRB 8901
> Register Court: Amtsgericht Darmstadt
> Management Board: Jürgen Ruf (CEO), Tamer Kemeröz
> Chairman of the Supervisory Board: Dr. Thomas Milde
>
> This email may contain confidential and/or privileged information. If you are not the correct recipient or have received this email in error,
> please inform the sender immediately and delete this email. Unauthorised copying or distribution of this email is not permitted.
>
> Data protection information: Privacy policy <https://www.mtg.de/en/privacy-policy>
>
>
> _______________________________________________
> Gcrypt-devel mailing list
> Gcrypt-devel@gnupg.org
> https://lists.gnupg.org/mailman/listinfo/gcrypt-devel

_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel@gnupg.org
https://lists.gnupg.org/mailman/listinfo/gcrypt-devel
Re: KMAC / cSHAKE in Libgcrypt [ In reply to ]
Hi!

Do you have a special reason why you don't use the existing MAC
framework? For additional parameters the gcry_mac_ctl function can be
used.


Shalom-Salam,

Werner


p.s.
This is a copy of mail mail from August 22, which didn't made it
to the list (we migrated mail systems at that time).

--
The pioneers of a warless world are the youth that
refuse military service. - A. Einstein
Re: KMAC / cSHAKE in Libgcrypt [ In reply to ]
I agree, for the implementation of KMAC itself we should use the MAC
API. But my question was about the integration of cSHAKE, which is an
XOF hash function, not a MAC.

- Falko

Am 05.09.23 um 11:15 schrieb Werner Koch:
> Hi!
>
> Do you have a special reason why you don't use the existing MAC
> framework? For additional parameters the gcry_mac_ctl function can be
> used.
>
>
> Shalom-Salam,
>
> Werner
>
>
> p.s.
> This is a copy of mail mail from August 22, which didn't made it
> to the list (we migrated mail systems at that time).
>
--

*MTG AG*
Dr. Falko Strenzke
Executive System Architect

Phone: +49 6151 8000 24
E-Mail: falko.strenzke@mtg.de
Web: mtg.de <https://www.mtg.de>


*MTG Exhibitions – See you in 2023*

------------------------------------------------------------------------
<https://community.e-world-essen.com/institutions/allExhibitors?query=true&keywords=mtg>
<https://www.itsa365.de/de-de/companies/m/mtg-ag>

MTG AG - Dolivostr. 11 - 64293 Darmstadt, Germany
Commercial register: HRB 8901
Register Court: Amtsgericht Darmstadt
Management Board: Jürgen Ruf (CEO), Tamer Kemeröz
Chairman of the Supervisory Board: Dr. Thomas Milde

This email may contain confidential and/or privileged information. If
you are not the correct recipient or have received this email in error,
please inform the sender immediately and delete this email. Unauthorised
copying or distribution of this email is not permitted.

Data protection information: Privacy policy
<https://www.mtg.de/en/privacy-policy>
Re: KMAC / cSHAKE in Libgcrypt [ In reply to ]
On Tue, 12 Sep 2023 13:50, Falko Strenzke said:
> I agree, for the implementation of KMAC itself we should use the MAC API. But
> my question was about the integration of cSHAKE, which is an XOF hash
> function, not a MAC.

I see. Now for your suggested API.

> * cSHAKE is added as an XOF message digest like SHAKE

That is easy

> * For the purpose of providing the additional arguments N and S we add
[..]
> gcry_md_set_add_input (gcry_md_hd_t *h,
> gcry_md_add_input_t addin_type,
> const void* v, size_t v_len);

Adding another API call is not a good idea, though. We should use
gcry_md_ctl with two new control values.

> 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()

Insted we use:

gcry_md_ctl (hd, GCRYCTL_CSHAKE_N, n, nlen);
gcry_md_ctl (hd, GCRYCTL_CSHAKE_S, n, nlen)

(which should return an error if the parmeters are not okay.

> 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.

Well, in that case we may not even need GCRY_MD_CSHAKE but could reuse
GCRY_MD_SHAKE256 and check that the parameters are only used for this
algo - a test which is anyway required. Below an unfinished example.


--8<---------------cut here---------------start------------->8---
commit 1b4bb2ee125a91084f0fe6fa74d57cd47d2164fe (HEAD -> refs/heads/master)
Author: Werner Koch <wk@gnupg.org>
Date: Thu Sep 14 14:43:13 2023 +0200

xxxxxxxxxxxxxxxxxxxxxxx

Modified cipher/md.c
diff --git a/cipher/md.c b/cipher/md.c
index a128dd82..4052bc90 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -1001,8 +1001,6 @@ _gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
{
gcry_err_code_t rc = 0;

- (void)buflen; /* Currently not used. */
-
switch (cmd)
{
case GCRYCTL_FINALIZE:
@@ -1014,6 +1012,12 @@ _gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
case GCRYCTL_STOP_DUMP:
md_stop_debug ( hd );
break;
+ case GCRYCTL_CSHAKE_N:
+ rc = _gcry_md_cshake_set_n (hd, buffer, buflen);
+ break;
+ case GCRYCTL_CSHAKE_S:
+ rc = _gcry_md_cshake_set_s (hd, buffer, buflen);
+ break;
default:
rc = GPG_ERR_INV_OP;
}
Modified src/gcrypt.h.in
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index 7dc1196b..a861a11e 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -333,7 +333,9 @@ enum gcry_ctl_cmds
GCRYCTL_FIPS_SERVICE_INDICATOR_FUNCTION = 84,
GCRYCTL_FIPS_SERVICE_INDICATOR_MAC = 85,
GCRYCTL_FIPS_SERVICE_INDICATOR_MD = 86,
- GCRYCTL_FIPS_SERVICE_INDICATOR_PK_FLAGS = 87
+ GCRYCTL_FIPS_SERVICE_INDICATOR_PK_FLAGS = 87,
+ GCRYCTL_CSHAKE_N = 88,
+ GCRYCTL_CSHAKE_S = 89
};

/* Perform various operations defined by CMD. */
@@ -1304,7 +1306,8 @@ enum gcry_md_algos
GCRY_MD_BLAKE2S_128 = 325,
GCRY_MD_SM3 = 326,
GCRY_MD_SHA512_256 = 327,
- GCRY_MD_SHA512_224 = 328
+ GCRY_MD_SHA512_224 = 328,
+ GCRY_MD_CSHAKE = 329
};

/* Flags used with the open function. */
--8<---------------cut here---------------end--------------->8---



--
The pioneers of a warless world are the youth that
refuse military service. - A. Einstein
Re: KMAC / cSHAKE in Libgcrypt [ In reply to ]
Hi Werner,

Am 14.09.23 um 14:50 schrieb Werner Koch:
> On Tue, 12 Sep 2023 13:50, Falko Strenzke said:
> Insted we use:
>
> gcry_md_ctl (hd, GCRYCTL_CSHAKE_N, n, nlen);
> gcry_md_ctl (hd, GCRYCTL_CSHAKE_S, n, nlen)
>
> (which should return an error if the parmeters are not okay.
Agreed, we will use gcry_md_ctl like you are proposing.
>
>> 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.
> Well, in that case we may not even need GCRY_MD_CSHAKE but could reuse
> GCRY_MD_SHAKE256 and check that the parameters are only used for this
> algo - a test which is anyway required. Below an unfinished example.
I don't understand what you mean exactly by "we may not even need
GCRY_MD_CSHAKE". Maybe it is with respect to how we implement it, in
that case see my comment below on reusing the SHAKE implementation.
>
>
> --8<---------------cut here---------------start------------->8---
> commit 1b4bb2ee125a91084f0fe6fa74d57cd47d2164fe (HEAD -> refs/heads/master)
> Author: Werner Koch<wk@gnupg.org>
> Date: Thu Sep 14 14:43:13 2023 +0200
>
> xxxxxxxxxxxxxxxxxxxxxxx
>
> Modified cipher/md.c
> diff --git a/cipher/md.c b/cipher/md.c
> index a128dd82..4052bc90 100644
> --- a/cipher/md.c
> +++ b/cipher/md.c
> @@ -1001,8 +1001,6 @@ _gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
> {
> gcry_err_code_t rc = 0;
>
> - (void)buflen; /* Currently not used. */
> -
> switch (cmd)
> {
> case GCRYCTL_FINALIZE:
> @@ -1014,6 +1012,12 @@ _gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
> case GCRYCTL_STOP_DUMP:
> md_stop_debug ( hd );
> break;
> + case GCRYCTL_CSHAKE_N:
> + rc = _gcry_md_cshake_set_n (hd, buffer, buflen);
> + break;
> + case GCRYCTL_CSHAKE_S:
> + rc = _gcry_md_cshake_set_s (hd, buffer, buflen);
> + break;
> default:
> rc = GPG_ERR_INV_OP;
> }
Makes sense to me.
> Modified src/gcrypt.h.in
> diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
> index 7dc1196b..a861a11e 100644
> --- a/src/gcrypt.h.in
> +++ b/src/gcrypt.h.in
> @@ -333,7 +333,9 @@ enum gcry_ctl_cmds
> GCRYCTL_FIPS_SERVICE_INDICATOR_FUNCTION = 84,
> GCRYCTL_FIPS_SERVICE_INDICATOR_MAC = 85,
> GCRYCTL_FIPS_SERVICE_INDICATOR_MD = 86,
> - GCRYCTL_FIPS_SERVICE_INDICATOR_PK_FLAGS = 87
> + GCRYCTL_FIPS_SERVICE_INDICATOR_PK_FLAGS = 87,
> + GCRYCTL_CSHAKE_N = 88,
> + GCRYCTL_CSHAKE_S = 89
OK.
> };
>
> /* Perform various operations defined by CMD. */
> @@ -1304,7 +1306,8 @@ enum gcry_md_algos
> GCRY_MD_BLAKE2S_128 = 325,
> GCRY_MD_SM3 = 326,
> GCRY_MD_SHA512_256 = 327,
> - GCRY_MD_SHA512_224 = 328
> + GCRY_MD_SHA512_224 = 328,
> + GCRY_MD_CSHAKE = 329

In my opinion we need to add GCRY_MD_CSHAKE128 and GCRY_MD_CSHAKE256,
the two algorithms defined by NIST and needed for KMAC128 and KMAC256,
respectively. The implementation that I have made is thin though, it
basically reuses the SHAKE implementation and its functions together
with the KECCAK_CONTEXT and only adds some state management for the
additional inputs N and S (and of course the corresponding encoding
functions). I will be able to provide it for review in the next weeks
after the corrections we are still discussing.

- Falko

>
>
--

*MTG AG*
Dr. Falko Strenzke
Executive System Architect

Phone: +49 6151 8000 24
E-Mail: falko.strenzke@mtg.de
Web: mtg.de <https://www.mtg.de>


*MTG Exhibitions – See you in 2023*

------------------------------------------------------------------------
<https://community.e-world-essen.com/institutions/allExhibitors?query=true&keywords=mtg>
<https://www.itsa365.de/de-de/companies/m/mtg-ag>

MTG AG - Dolivostr. 11 - 64293 Darmstadt, Germany
Commercial register: HRB 8901
Register Court: Amtsgericht Darmstadt
Management Board: Jürgen Ruf (CEO), Tamer Kemeröz
Chairman of the Supervisory Board: Dr. Thomas Milde

This email may contain confidential and/or privileged information. If
you are not the correct recipient or have received this email in error,
please inform the sender immediately and delete this email. Unauthorised
copying or distribution of this email is not permitted.

Data protection information: Privacy policy
<https://www.mtg.de/en/privacy-policy>
Re: KMAC / cSHAKE in Libgcrypt [ In reply to ]
On Thu, 14 Sep 2023 15:38, Falko Strenzke said:

> I don't understand what you mean exactly by "we may not even need
> GCRY_MD_CSHAKE". Maybe it is with respect to how we implement it, in that case
> see my comment below on reusing the SHAKE implementation.

That we can use the GCRY_MD_SHAKE256 identifier also for cSHAKE. The
use of the control codes would modify SHAKE256 to cSHAKE.

> In my opinion we need to add GCRY_MD_CSHAKE128 and  GCRY_MD_CSHAKE256, the two

As long as the resulting digest lengths are the same as the original SHAKE
versions, new identifier won't be needed. However, if cSHAKE and SHAKE
are used by a protocol in the same way, new identifiers are indeed
useful. What I mean is this:

switch (hash_algo) {
case GCRY_MD_SHAKE256: do_one_thing (); break,
case GCRY_MD_CSHAKE256: do_another_thing (); break,
....
}


Salam-Shalom,

Werner

--
The pioneers of a warless world are the youth that
refuse military service. - A. Einstein
Re: KMAC / cSHAKE in Libgcrypt [ In reply to ]
Am 15.09.23 um 10:08 schrieb Werner Koch:
> On Thu, 14 Sep 2023 15:38, Falko Strenzke said:
>
>> I don't understand what you mean exactly by "we may not even need
>> GCRY_MD_CSHAKE". Maybe it is with respect to how we implement it, in that case
>> see my comment below on reusing the SHAKE implementation.
> That we can use the GCRY_MD_SHAKE256 identifier also for cSHAKE. The
> use of the control codes would modify SHAKE256 to cSHAKE.

It is correct that this approach is technically possible. But I wonder
if in that case there might result ambiguities somewhere in applications
if they cannot make the  distinction between SHAKE and cSHAKE via the
algorithm identifier. Possibly there might be the case where I want to
allow only SHAKE and thus want to cause the call to |_gcry_md_ctl() |for
the setting of the values of N and S to fail.

Another aspect is that the cSHAKE context is a bit larger than the SHAKE
context:

typedef struct CSHAKE_CONTEXT_S
{
    KECCAK_CONTEXT keccak_ctx;
    unsigned int rate_in_bytes;
    size_t written_bytes_n_s;
    int n_set;
    int s_set;
} CSHAKE_CONTEXT;

That is, however, just a few bytes and thus shouldn't matter much in
practice.

I think for this decision it matters if one gives priority to the
clarity of the algorithm modelling in the API and thus distinguishes
between SHAKE and cSHAKE or to not increasing the number of hash
algorithms. Given that the list of hash algorithms is already long, I
think the addition of two further algorithms does not matter much. Also
for the reason of clearer API would clearly tend to model cSHAKE as a
different algorithm than SHAKE and thus would prefer to add the new
identifiers.

- Falko

>
>> In my opinion we need to add GCRY_MD_CSHAKE128 and  GCRY_MD_CSHAKE256, the two
> As long as the resulting digest lengths are the same as the original SHAKE
> versions, new identifier won't be needed. However, if cSHAKE and SHAKE
> are used by a protocol in the same way, new identifiers are indeed
> useful. What I mean is this:
>
> switch (hash_algo) {
> case GCRY_MD_SHAKE256: do_one_thing (); break,
> case GCRY_MD_CSHAKE256: do_another_thing (); break,
> ....
> }
>
>
> Salam-Shalom,
>
> Werner
>
--

*MTG AG*
Dr. Falko Strenzke
Executive System Architect

Phone: +49 6151 8000 24
E-Mail: falko.strenzke@mtg.de
Web: mtg.de <https://www.mtg.de>


*MTG Exhibitions – See you in 2023*

------------------------------------------------------------------------
<https://community.e-world-essen.com/institutions/allExhibitors?query=true&keywords=mtg>
<https://www.itsa365.de/de-de/companies/m/mtg-ag>

MTG AG - Dolivostr. 11 - 64293 Darmstadt, Germany
Commercial register: HRB 8901
Register Court: Amtsgericht Darmstadt
Management Board: Jürgen Ruf (CEO), Tamer Kemeröz
Chairman of the Supervisory Board: Dr. Thomas Milde

This email may contain confidential and/or privileged information. If
you are not the correct recipient or have received this email in error,
please inform the sender immediately and delete this email. Unauthorised
copying or distribution of this email is not permitted.

Data protection information: Privacy policy
<https://www.mtg.de/en/privacy-policy>