From jussi.kivilinna at iki.fi Sat Jul 4 07:37:32 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sat, 4 Jul 2026 08:37:32 +0300 Subject: [PATCH 1/2] sm4: tail-call ARM and PPC crypt_blk1_x helpers Message-ID: <20260704053733.3618370-1-jussi.kivilinna@iki.fi> * cipher/sm4-aarch64.S (sm4_aarch64_crypt_blk1_4) (_gcry_sm4_aarch64_crypt_blk1_8): Return zero stack burn size. * cipher/sm4-armv8-aarch64-ce.S (sm4_armv8_ce_crypt_blk1_4) (_gcry_sm4_armv8_ce_crypt_blk1_8): Likewise. * cipher/sm4-armv9-aarch64-sve-ce.S (_gcry_sm4_armv9_sve_ce_crypt): Likewise. * cipher/sm4-ppc.c (sm4_ppc_crypt_blk1_16, _gcry_sm4_ppc8le_crypt_blk1_16) (_gcry_sm4_ppc9le_crypt_blk1_16): Likewise. * cipher/sm4.c (_gcry_sm4_aarch64_crypt_blk1_8) (_gcry_sm4_armv8_ce_crypt_blk1_8, _gcry_sm4_armv9_sve_ce_crypt) (_gcry_sm4_ppc8le_crypt_blk1_16, _gcry_sm4_ppc9le_crypt_blk1_16): Likewise. (sm4_aarch64_crypt_blk1_16, sm4_armv8_ce_crypt_blk1_16) (sm4_armv9_sve_ce_crypt_blk1_16, sm4_ppc8le_crypt_blk1_16) (sm4_ppc9le_crypt_blk1_16): Tail-call the underlying blk1_x helper. -- These wrappers called the helper and then returned a constant zero, which prevents the compiler from emitting a tail call. Signed-off-by: Jussi Kivilinna --- cipher/sm4-aarch64.S | 2 ++ cipher/sm4-armv8-aarch64-ce.S | 2 ++ cipher/sm4-armv9-aarch64-sve-ce.S | 1 + cipher/sm4-ppc.c | 14 +++++----- cipher/sm4.c | 43 ++++++++++++++----------------- 5 files changed, 33 insertions(+), 29 deletions(-) diff --git a/cipher/sm4-aarch64.S b/cipher/sm4-aarch64.S index bab4b4df..c71bf3ca 100644 --- a/cipher/sm4-aarch64.S +++ b/cipher/sm4-aarch64.S @@ -222,6 +222,7 @@ sm4_aarch64_crypt_blk1_4: .Lblk4_store_output_done: VPOP_ABI; + mov x0, #0; ret_spec_stop; CFI_ENDPROC(); ELF(.size sm4_aarch64_crypt_blk1_4,.-sm4_aarch64_crypt_blk1_4;) @@ -396,6 +397,7 @@ _gcry_sm4_aarch64_crypt_blk1_8: CFI_ADJUST_CFA_OFFSET(-16); CFI_RESTORE(x29); CFI_RESTORE(x30); + mov x0, #0; ret_spec_stop; CFI_ENDPROC(); ELF(.size _gcry_sm4_aarch64_crypt_blk1_8,.-_gcry_sm4_aarch64_crypt_blk1_8;) diff --git a/cipher/sm4-armv8-aarch64-ce.S b/cipher/sm4-armv8-aarch64-ce.S index 01f3df92..5917ad5b 100644 --- a/cipher/sm4-armv8-aarch64-ce.S +++ b/cipher/sm4-armv8-aarch64-ce.S @@ -335,6 +335,7 @@ sm4_armv8_ce_crypt_blk1_4: st1 {v3.16b}, [x1]; .Lblk4_store_output_done: + mov x0, #0; ret_spec_stop; CFI_ENDPROC(); ELF(.size sm4_armv8_ce_crypt_blk1_4,.-sm4_armv8_ce_crypt_blk1_4;) @@ -385,6 +386,7 @@ _gcry_sm4_armv8_ce_crypt_blk1_8: .Lblk8_store_output_done: CLEAR_ALL_REGS(); + mov x0, #0; ret_spec_stop; CFI_ENDPROC(); ELF(.size _gcry_sm4_armv8_ce_crypt_blk1_8,.-_gcry_sm4_armv8_ce_crypt_blk1_8;) diff --git a/cipher/sm4-armv9-aarch64-sve-ce.S b/cipher/sm4-armv9-aarch64-sve-ce.S index 7367cd28..ba9bde84 100644 --- a/cipher/sm4-armv9-aarch64-sve-ce.S +++ b/cipher/sm4-armv9-aarch64-sve-ce.S @@ -444,6 +444,7 @@ _gcry_sm4_armv9_sve_ce_crypt: cbnz x3, .Lcrypt_tail; .Lcrypt_end: + mov x0, #0; ret_spec_stop; CFI_ENDPROC(); ELF(.size _gcry_sm4_armv9_sve_ce_crypt,.-_gcry_sm4_armv9_sve_ce_crypt;) diff --git a/cipher/sm4-ppc.c b/cipher/sm4-ppc.c index 2b26c39d..9d9227c0 100644 --- a/cipher/sm4-ppc.c +++ b/cipher/sm4-ppc.c @@ -293,7 +293,7 @@ sm4_ppc_crypt_blk1_4(u32 *rk, byte *out, const byte *in, size_t nblks) vec_xst((vector16x_u8)vec_revb(ra0), 0, out + 3 * 16); } -static ASM_FUNC_ATTR_INLINE void +static ASM_FUNC_ATTR_INLINE unsigned int sm4_ppc_crypt_blk1_16(u32 *rk, byte *out, const byte *in, size_t nblks) { if (nblks >= 16) @@ -321,25 +321,27 @@ sm4_ppc_crypt_blk1_16(u32 *rk, byte *out, const byte *in, size_t nblks) } clear_vec_regs(); + + return 0; } -ASM_FUNC_ATTR_NOINLINE FUNC_ATTR_TARGET_P8 void +ASM_FUNC_ATTR_NOINLINE FUNC_ATTR_TARGET_P8 unsigned int _gcry_sm4_ppc8le_crypt_blk1_16(u32 *rk, byte *out, const byte *in, size_t nblks) { - sm4_ppc_crypt_blk1_16(rk, out, in, nblks); + return sm4_ppc_crypt_blk1_16(rk, out, in, nblks); } -ASM_FUNC_ATTR_NOINLINE FUNC_ATTR_TARGET_P9 void +ASM_FUNC_ATTR_NOINLINE FUNC_ATTR_TARGET_P9 unsigned int _gcry_sm4_ppc9le_crypt_blk1_16(u32 *rk, byte *out, const byte *in, size_t nblks) { #ifdef HAVE_FUNC_ATTR_TARGET /* Inline for POWER9 target optimization. */ - sm4_ppc_crypt_blk1_16(rk, out, in, nblks); + return sm4_ppc_crypt_blk1_16(rk, out, in, nblks); #else /* Target selecting not working, just call the other noinline function. */ - _gcry_sm4_ppc8le_crypt_blk1_16(rk, out, in, nblks); + return _gcry_sm4_ppc8le_crypt_blk1_16(rk, out, in, nblks); #endif } diff --git a/cipher/sm4.c b/cipher/sm4.c index 165a66b2..cc98b676 100644 --- a/cipher/sm4.c +++ b/cipher/sm4.c @@ -635,9 +635,9 @@ extern void _gcry_sm4_aarch64_cfb_dec(const u32 *rk_enc, byte *out, byte *iv, size_t nblocks); -extern void _gcry_sm4_aarch64_crypt_blk1_8(u32 *rk, byte *out, - const byte *in, - size_t num_blocks); +extern unsigned int _gcry_sm4_aarch64_crypt_blk1_8(u32 *rk, byte *out, + const byte *in, + size_t num_blocks); static inline unsigned int sm4_aarch64_crypt_blk1_16(void *rk, byte *out, const byte *in, @@ -651,8 +651,7 @@ sm4_aarch64_crypt_blk1_16(void *rk, byte *out, const byte *in, num_blks -= 8; } - _gcry_sm4_aarch64_crypt_blk1_8(rk, out, in, num_blks); - return 0; + return _gcry_sm4_aarch64_crypt_blk1_8(rk, out, in, num_blks); } #endif /* USE_AARCH64_SIMD */ @@ -686,9 +685,9 @@ extern void _gcry_sm4_armv8_ce_xts_crypt(const u32 *rk, byte *out, byte *tweak, size_t nblocks); -extern void _gcry_sm4_armv8_ce_crypt_blk1_8(u32 *rk, byte *out, - const byte *in, - size_t num_blocks); +extern unsigned int _gcry_sm4_armv8_ce_crypt_blk1_8(u32 *rk, byte *out, + const byte *in, + size_t num_blocks); static inline unsigned int sm4_armv8_ce_crypt_blk1_16(void *rk, byte *out, const byte *in, @@ -702,16 +701,15 @@ sm4_armv8_ce_crypt_blk1_16(void *rk, byte *out, const byte *in, num_blks -= 8; } - _gcry_sm4_armv8_ce_crypt_blk1_8(rk, out, in, num_blks); - return 0; + return _gcry_sm4_armv8_ce_crypt_blk1_8(rk, out, in, num_blks); } #endif /* USE_ARM_CE */ #ifdef USE_ARM_SVE_CE -extern void _gcry_sm4_armv9_sve_ce_crypt(u32 *rk, byte *out, - const byte *in, - size_t nblocks); +extern unsigned int _gcry_sm4_armv9_sve_ce_crypt(u32 *rk, byte *out, + const byte *in, + size_t nblocks); extern void _gcry_sm4_armv9_sve_ce_ctr_enc(const u32 *rk_enc, byte *out, const byte *in, @@ -732,32 +730,31 @@ static inline unsigned int sm4_armv9_sve_ce_crypt_blk1_16(void *rk, byte *out, const byte *in, size_t num_blks) { - _gcry_sm4_armv9_sve_ce_crypt(rk, out, in, num_blks); - return 0; + return _gcry_sm4_armv9_sve_ce_crypt(rk, out, in, num_blks); } extern unsigned int _gcry_sm4_armv9_sve_get_vl(void); #endif /* USE_ARM_SVE_CE */ #ifdef USE_PPC_CRYPTO -extern void _gcry_sm4_ppc8le_crypt_blk1_16(u32 *rk, byte *out, const byte *in, - size_t num_blks); +extern unsigned int _gcry_sm4_ppc8le_crypt_blk1_16(u32 *rk, byte *out, + const byte *in, + size_t num_blks); -extern void _gcry_sm4_ppc9le_crypt_blk1_16(u32 *rk, byte *out, const byte *in, - size_t num_blks); +extern unsigned int _gcry_sm4_ppc9le_crypt_blk1_16(u32 *rk, byte *out, + const byte *in, + size_t num_blks); static inline unsigned int sm4_ppc8le_crypt_blk1_16(void *rk, byte *out, const byte *in, size_t num_blks) { - _gcry_sm4_ppc8le_crypt_blk1_16(rk, out, in, num_blks); - return 0; + return _gcry_sm4_ppc8le_crypt_blk1_16(rk, out, in, num_blks); } static inline unsigned int sm4_ppc9le_crypt_blk1_16(void *rk, byte *out, const byte *in, size_t num_blks) { - _gcry_sm4_ppc9le_crypt_blk1_16(rk, out, in, num_blks); - return 0; + return _gcry_sm4_ppc9le_crypt_blk1_16(rk, out, in, num_blks); } #endif /* USE_PPC_CRYPTO */ -- 2.53.0 From jussi.kivilinna at iki.fi Sat Jul 4 07:37:33 2026 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sat, 4 Jul 2026 08:37:33 +0300 Subject: [PATCH 2/2] cipher: limit table prefetch to the look-up table arrays In-Reply-To: <20260704053733.3618370-1-jussi.kivilinna@iki.fi> References: <20260704053733.3618370-1-jussi.kivilinna@iki.fi> Message-ID: <20260704053733.3618370-2-jussi.kivilinna@iki.fi> * cipher/aria.c (prefetch_sboxes): Compute unshare counter once and prefetch only look-up arrays. * cipher/cipher-gcm.c (do_prefetch_tables): Likewise. * cipher/rijndael.c (prefetch_enc, prefetch_dec): Likewise. * cipher/sm4.c (prefetch_sbox_table): Likewise. * cipher/rijndael-tables.h (dec_tables): Rename 'inv_sbox' field to 'inv_sboxT'. -- Signed-off-by: Jussi Kivilinna --- cipher/aria.c | 7 ++++--- cipher/cipher-gcm.c | 7 ++++--- cipher/rijndael-tables.h | 4 ++-- cipher/rijndael.c | 15 +++++++++------ cipher/sm4.c | 7 ++++--- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/cipher/aria.c b/cipher/aria.c index 26546a63..bb67ed03 100644 --- a/cipher/aria.c +++ b/cipher/aria.c @@ -627,11 +627,12 @@ prefetch_sboxes(void) * of look-up table are shared between processes. Modifying counters also * causes checksums for pages to change and hint same-page merging algorithm * that these pages are frequently changing. */ - sboxes.counter_head++; - sboxes.counter_tail++; + u32 counter = sboxes.counter_head + 1; + sboxes.counter_head = counter; + sboxes.counter_tail = counter; /* Prefetch look-up tables to cache. */ - prefetch_table((const void *)&sboxes, sizeof(sboxes)); + prefetch_table((const void *)&sboxes.s1[0], sizeof(sboxes.s1) * 4); } diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c index 2db371b8..1627cd1c 100644 --- a/cipher/cipher-gcm.c +++ b/cipher/cipher-gcm.c @@ -255,12 +255,13 @@ do_prefetch_tables (const void *gcmM, size_t gcmM_size) * of look-up table are shared between processes. Modifying counters also * causes checksums for pages to change and hint same-page merging algorithm * that these pages are frequently changing. */ - gcm_table.counter_head++; - gcm_table.counter_tail++; + u32 counter = gcm_table.counter_head + 1; + gcm_table.counter_head = counter; + gcm_table.counter_tail = counter; /* Prefetch look-up tables to cache. */ prefetch_table(gcmM, gcmM_size); - prefetch_table(&gcm_table, sizeof(gcm_table)); + prefetch_table(&gcm_table.R, sizeof(gcm_table.R)); } #ifdef GCM_TABLES_USE_U64 diff --git a/cipher/rijndael-tables.h b/cipher/rijndael-tables.h index e46ce08c..52b9518f 100644 --- a/cipher/rijndael-tables.h +++ b/cipher/rijndael-tables.h @@ -107,7 +107,7 @@ static struct volatile u32 counter_head; u32 cacheline_align[64 / 4 - 1]; u32 T[256]; - byte inv_sbox[256]; + byte inv_sboxT[256]; volatile u32 counter_tail; } dec_tables ATTR_ALIGNED_64 = { @@ -217,4 +217,4 @@ static struct }; #define decT dec_tables.T -#define inv_sbox dec_tables.inv_sbox +#define inv_sbox dec_tables.inv_sboxT diff --git a/cipher/rijndael.c b/cipher/rijndael.c index f3daf35a..645c0e2f 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -597,11 +597,12 @@ static void prefetch_enc(void) * of look-up table are shared between processes. Modifying counters also * causes checksums for pages to change and hint same-page merging algorithm * that these pages are frequently changing. */ - enc_tables.counter_head++; - enc_tables.counter_tail++; + u32 counter = enc_tables.counter_head + 1; + enc_tables.counter_head = counter; + enc_tables.counter_tail = counter; /* Prefetch look-up tables to cache. */ - prefetch_table((const void *)&enc_tables, sizeof(enc_tables)); + prefetch_table((const void *)&enc_tables.T[0], sizeof(enc_tables.T)); } static void prefetch_dec(void) @@ -610,11 +611,13 @@ static void prefetch_dec(void) * of look-up table are shared between processes. Modifying counters also * causes checksums for pages to change and hint same-page merging algorithm * that these pages are frequently changing. */ - dec_tables.counter_head++; - dec_tables.counter_tail++; + u32 counter = dec_tables.counter_head + 1; + dec_tables.counter_head = counter; + dec_tables.counter_tail = counter; /* Prefetch look-up tables to cache. */ - prefetch_table((const void *)&dec_tables, sizeof(dec_tables)); + prefetch_table((const void *)&dec_tables.T[0], + sizeof(dec_tables.T) + sizeof(dec_tables.inv_sboxT)); } diff --git a/cipher/sm4.c b/cipher/sm4.c index cc98b676..70b4901c 100644 --- a/cipher/sm4.c +++ b/cipher/sm4.c @@ -760,14 +760,15 @@ sm4_ppc9le_crypt_blk1_16(void *rk, byte *out, const byte *in, size_t num_blks) static inline void prefetch_sbox_table(void) { - const volatile byte *vtab = (void *)&sbox_table; + const volatile byte *vtab = (void *)&sbox_table.S[0]; /* Modify counters to trigger copy-on-write and unsharing if physical pages * of look-up table are shared between processes. Modifying counters also * causes checksums for pages to change and hint same-page merging algorithm * that these pages are frequently changing. */ - sbox_table.counter_head++; - sbox_table.counter_tail++; + u32 counter = sbox_table.counter_head + 1; + sbox_table.counter_head = counter; + sbox_table.counter_tail = counter; /* Prefetch look-up table to cache. */ (void)vtab[0 * 32]; -- 2.53.0 From davegalos at google.com Fri Jul 10 01:11:18 2026 From: davegalos at google.com (David Galos) Date: Thu, 9 Jul 2026 19:11:18 -0400 Subject: [PATCH 2/2] Fix intermittent failure in rsa_decrypt when p>q. In-Reply-To: <20260709231752.1332171-1-davegalos@google.com> References: <20260709231752.1332171-1-davegalos@google.com> Message-ID: <20260709231752.1332171-3-davegalos@google.com> --- cipher/rsa.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cipher/rsa.c b/cipher/rsa.c index 58058d6a..ff679d95 100644 --- a/cipher/rsa.c +++ b/cipher/rsa.c @@ -1141,9 +1141,12 @@ secret_core_crt (gcry_mpi_t M, gcry_mpi_t C, mpi_free ( D_blind ); /* h = u * ( m2 - m1 ) mod q */ - mpi_sub ( h, m2, m1 ); - if ( mpi_has_sign ( h ) ) - mpi_add ( h, h, Q ); + /* NB: prior code used non-modular subtraction and a sign check, + * adding Q to the result when negative, which does not work if + * P > Q + 1. That is not technically a bug because RFC 4880 requires + * that P < Q, but there are non-compliant keys out there, and is + * a more direct rendition of the equation anyway. */ + mpi_subm ( h, m2, m1, Q ); mpi_mulm ( h, U, h, Q ); /* m = m1 + h * p */ -- 2.55.0.795.g602f6c329a-goog From davegalos at google.com Fri Jul 10 01:11:16 2026 From: davegalos at google.com (David Galos) Date: Thu, 9 Jul 2026 19:11:16 -0400 Subject: [PATCH 0/2] Changes to rsa_decrypt behavior on bad keys Message-ID: <20260709231752.1332171-1-davegalos@google.com> Apologies for the repost if you're subscribed to gnupg-devel as well as this list. When reading the HACKING file I didn't realize that I could've sent right to this list, so my bad. There are two following patches, and I think at least one of them is pretty important because the failure rate of a gcrypt-based crypto oracle could probably leak info about factor-proximity based on failure rate. Below is the same text I sent to gnupg-devel (which was the wrong list) but I think it still provides good explanation and context: What follows are two patches based on some surprising behavior I experienced dealing with some OpenPGP keys generated outside of GnuPG. I'll start with the second patch first, a key with p > q but a correctly calculated u will work for decryption about 80% of the time, but will overflow some percentage of the time, yielding an incorrect result, and a confusing error message from gpg -d. There are two better choices in this case: 1. error out. 2. always work. The patch attached choses the second option, because it would quietly make some things work, rather than breaking them. There is an argument for the first: broken things should break, and while from an RFC4880 point of view, the key is bad, RSA itself doesn't specify which key needs to be bigger. In the first patch I just validate the relationship between p, q, and u, because I have no idea how the code would behave if that relationship doesn't hold, but ERR_BAD_KEY seems like the right move. If Option 1 from above is chosen above, I will expand this patch to ensure p < q. David Galos (2): Validate CRT factors in rsa_decrypt Fix intermittent failure in rsa_decrypt when p>q. cipher/rsa.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) -- 2.55.0.795.g602f6c329a-goog From davegalos at google.com Fri Jul 10 01:11:17 2026 From: davegalos at google.com (David Galos) Date: Thu, 9 Jul 2026 19:11:17 -0400 Subject: [PATCH 1/2] Validate CRT factors in rsa_decrypt In-Reply-To: <20260709231752.1332171-1-davegalos@google.com> References: <20260709231752.1332171-1-davegalos@google.com> Message-ID: <20260709231752.1332171-2-davegalos@google.com> --- cipher/rsa.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cipher/rsa.c b/cipher/rsa.c index 44a44bdc..58058d6a 100644 --- a/cipher/rsa.c +++ b/cipher/rsa.c @@ -30,6 +30,7 @@ #include #include "g10lib.h" +#include "gcrypt.h" #include "mpi.h" #include "cipher.h" #include "pubkey-internal.h" @@ -1449,6 +1450,18 @@ rsa_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) } +static gcry_err_code_t +crt_validate_factors (RSA_secret_key *sk) +{ + int cmp; + gcry_mpi_t result = mpi_alloc_secure (0); + + mpi_mulm (result, sk->u, sk->p, sk->q); + cmp = mpi_cmp (result, GCRYMPI_CONST_ONE); + mpi_free (result); + return cmp == 0 ? 0 : GPG_ERR_BAD_SECKEY; +} + static gcry_err_code_t rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) @@ -1505,6 +1518,10 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) } } + rc = crt_validate_factors (&sk); + if (rc) + goto leave; + /* Better make sure that there are no superfluous leading zeroes in the input and it has not been "padded" using multiples of N. This mitigates side-channel attacks (CVE-2013-4576). */ -- 2.55.0.795.g602f6c329a-goog From dtsen at us.ibm.com Tue Jul 14 13:41:47 2026 From: dtsen at us.ibm.com (Danny Tsen) Date: Tue, 14 Jul 2026 11:41:47 +0000 Subject: [PATCH 0/5] dilithium-kyber: Optimized (i)NTT support for In-Reply-To: References: <20260224002753.151873-1-dtsen@us.ibm.com> <87tsu1bxn0.fsf@haruna.fsij.org> Message-ID: Hi NIIBE, It's been a while. Do you have any progress on the new setup? BTW, ZETA layout may be implementation or platform specific due to optimization approach. Thanks. -Danny ________________________________ From: Danny Tsen Sent: Monday, March 30, 2026 7:28 AM To: NIIBE Yutaka ; gcrypt-devel at gnupg.org Subject: Re: [EXTERNAL] Re: [PATCH 0/5] dilithium-kyber: Optimized (i)NTT support for Hi, That's seems like a good idea. Let me know when you have the framework available. I can follow that. Thanks. -Danny ________________________________ From: NIIBE Yutaka Sent: Friday, March 27, 2026 1:21 AM To: Danny Tsen ; gcrypt-devel at gnupg.org Subject: [EXTERNAL] Re: [PATCH 0/5] dilithium-kyber: Optimized (i)NTT support for Hello, Sorry for late reply. Danny Tsen wrote: > Added optimized (i)NTT algorithm support for ppc64le (Power 8 and > above). Defined ENABLE_PPC_DILITHIUM and ENABLE_PPC_KYBER for > dilithium (ML-DSA) and kyber (ML-KEM) NTT and inverse NTT. Thank you for your work. The approach of optimizing NTT functions looks good. Let me start a discussion about Kyber. Then, we can apply the result to Dilithium. I wonder if we can do a bit more, so that we can avoid the duplication of the ZETA constant among NTT implementation and kyber-common.c. I'm considering about factoring following five functions from kyber-common.c: void _gcry_poly_ntt(poly *r); void _gcry_poly_invntt_tomont(poly *r); void _gcry_poly_reduce(poly *r) void _gcry_poly_tomont(poly *r); void _gcry_poly_basemul_montgomery(poly *r, const poly *a, const poly *b); into, say, kyber-common-generic.c. And provide archtecture specific kyber-common--.S for optimized version(s). This way, NTT functions are covered and ZETA is placed inside kyber-common-*. How do you think? I'll try with the optimized implementation of AVX2 in the reference code. https://urldefense.proofpoint.com/v2/url?u=https-3A__www.pq-2Dcrystals.org_kyber_&d=DwIBAg&c=BSDicqBQBDjDI9RkVyTcHQ&r=zspFcGYEyUrRywX_TdjlLwwrCx0eBFnzcs6XZVVVMh0&m=cyhP1gGDXWh9JCIn4z5NrebvLkC7bN89aMGL_HFl26R2f9h7kqRDsaD6W5C2Q8tQ&s=guKkLMabJUVbm4bjm61GKleAAubKCEyFJJobD1MSghQ&e= -- -------------- next part -------------- An HTML attachment was scrubbed... URL: From tagrain at gmail.com Tue Jul 14 16:20:40 2026 From: tagrain at gmail.com (Thomas Grainger) Date: Tue, 14 Jul 2026 15:20:40 +0100 Subject: DCO declaration -- Thomas Grainger Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Libgcrypt Developer's Certificate of Origin. Version 1.0 ========================================================= By making a contribution to the Libgcrypt project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the free software license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate free software license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same free software license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the free software license(s) involved. Signed-off-by: Thomas Grainger -----BEGIN PGP SIGNATURE----- iHUEARYKAB0WIQTymEMfVHoEZC8HGEPdpItcR/vIyAUCalZEHAAKCRDdpItcR/vI yJpmAP9MT4pOFQZ6y8dcwmE/zmtrUZnkaZl3bx0MrH1hFZdUFgEAy2U2MgukpNtz uAzfLt34Jf5HfQsa3BxpKAeP4TjUOgE= =30xb -----END PGP SIGNATURE----- From tagrain at gmail.com Tue Jul 14 16:43:14 2026 From: tagrain at gmail.com (Thomas Grainger) Date: Tue, 14 Jul 2026 15:43:14 +0100 Subject: DCO declaration -- Thomas Grainger Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Libgcrypt Developer's Certificate of Origin. Version 1.0 ========================================================= By making a contribution to the Libgcrypt project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the free software license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate free software license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same free software license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the free software license(s) involved. Signed-off-by: Thomas Grainger -----BEGIN PGP SIGNATURE----- iHUEARYKAB0WIQTymEMfVHoEZC8HGEPdpItcR/vIyAUCalZEHAAKCRDdpItcR/vI yJpmAP9MT4pOFQZ6y8dcwmE/zmtrUZnkaZl3bx0MrH1hFZdUFgEAy2U2MgukpNtz uAzfLt34Jf5HfQsa3BxpKAeP4TjUOgE= =30xb -----END PGP SIGNATURE-----