[PATCH 06/10] sntrup761: read random values with single call
Jussi Kivilinna <[email protected]> Sun, 2 Aug 2026 12:55:11 +0300
| Newsgroups | gmane.comp.encryption.gpg.libgcrypt.devel |
|---|---|
| Message-ID | <[email protected]> |
* cipher/sntrup761.c: Include "bithelp.h".
(urandom32): Remove.
(Short_random, Small_random): Fill 32-bit array with one call to random
function instead of reading four bytes at a time.
--
'urandom32' requested four bytes per call and both callers looped over
all p coefficients, so generating one polynomial made 761 separate calls
to the random function. With libgcrypt CSPRNG each of those takes pool
lock, pool mix and hash operation, which dominated encapsulation time.
Benchmark on AMD Ryzen 9 9950X3D, SNTRUP761 usec/operation, quick
random disabled ('base' being state before this patch series):
| base before after speedup total
keygen | 37971.9 9480.2 2900.4 3.27x 13.09x
encap | 7355.8 4468.2 1184.7 3.77x 6.21x
decap | 12207.1 3325.4 3322.4 1.00x 3.67x
Signed-off-by: Jussi Kivilinna <[email protected]>
---
cipher/sntrup761.c | 22 ++++++----------------
1 file changed, 6 insertions(+), 16 deletions(-)
diff --git a/cipher/sntrup761.c b/cipher/sntrup761.c
index 11366f8f..94229d79 100644
--- a/cipher/sntrup761.c
+++ b/cipher/sntrup761.c
@@ -34,6 +34,7 @@
#endif
#include "sntrup761.h"
+#include "bithelp.h"
#include "const-time.h"
/* from supercop-20201130/crypto_sort/int32/portable4/int32_minmax.inc */
@@ -698,38 +699,27 @@ Hash_prefix (unsigned char *out, int b, const unsigned char *in, int inlen)
/* ----- higher-level randomness */
-static uint32_t
-urandom32 (void *random_ctx, sntrup761_random_func * random)
-{
- unsigned char c[4];
- uint32_t out[4];
-
- random (random_ctx, 4, c);
- out[0] = (uint32_t) c[0];
- out[1] = ((uint32_t) c[1]) << 8;
- out[2] = ((uint32_t) c[2]) << 16;
- out[3] = ((uint32_t) c[3]) << 24;
- return out[0] + out[1] + out[2] + out[3];
-}
-
static void
Short_random (small * out, void *random_ctx, sntrup761_random_func * random)
{
uint32_t L[p];
int i;
+ random (random_ctx, sizeof (L), (uint8_t *)L);
for (i = 0; i < p; ++i)
- L[i] = urandom32 (random_ctx, random);
+ L[i] = le_bswap32 (L[i]);
Short_fromlist (out, L);
}
static void
Small_random (small * out, void *random_ctx, sntrup761_random_func * random)
{
+ uint32_t L[p];
int i;
+ random (random_ctx, sizeof (L), (uint8_t *)L);
for (i = 0; i < p; ++i)
- out[i] = (((urandom32 (random_ctx, random) & 0x3fffffff) * 3) >> 30) - 1;
+ out[i] = (((le_bswap32 (L[i]) & 0x3fffffff) * 3) >> 30) - 1;
}
/* ----- Streamlined NTRU Prime Core */
--
2.53.0