upstream: Fill entropy in a single operation instead of hundreds.

The sntrup761 code we use from SUPERCOP fills entropy arrays 4 bytes at
a time.  On some platforms each of these operations has a significant
overhead, so instead fill it in a single operation and as a precaution
zero that array after it's used.

Analysis and code change is from Mike Frysinger via Github PR#621 with
feedback from djm@ and sed-ification from me.  ok djm@ beck@.

This change was submitted by Mike to SUPERCOP upstream so hopefully
future versions will already have it.

OpenBSD-Commit-ID: 0e85c82f79b1b396facac59e05b288c08048f15c
This commit is contained in:
dtucker@openbsd.org
2026-01-20 22:56:11 +00:00
committed by Darren Tucker
parent a6f8f793d4
commit 1cc936b2fa
2 changed files with 30 additions and 16 deletions

View File

@@ -1,5 +1,4 @@
/* $OpenBSD: sntrup761.c,v 1.8 2024/09/16 05:37:05 djm Exp $ */
/* $OpenBSD: sntrup761.c,v 1.9 2026/01/20 22:56:11 dtucker Exp $ */
/*
* Public Domain, Authors:
@@ -1961,27 +1960,20 @@ static void Hash_prefix(unsigned char *out, int b, const unsigned char *in, int
for (i = 0; i < 32; ++i) out[i] = h[i];
}
static uint32_t urandom32(void) {
unsigned char c[4];
uint32_t result = 0;
int i;
randombytes(c, 4);
for (i = 0; i < 4; ++i) result += ((uint32_t)c[i]) << (8 * i);
return result;
}
static void Short_random(small *out) {
uint32_t L[p];
int i;
for (i = 0; i < p; ++i) L[i] = urandom32();
randombytes(L, sizeof(L));
Short_fromlist(out, L);
explicit_bzero(L, sizeof(L));
}
static void Small_random(small *out) {
int i;
for (i = 0; i < p; ++i) out[i] = (((urandom32() & 0x3fffffff) * 3) >> 30) - 1;
uint32_t L[p];
randombytes(L, sizeof(L));
for (i = 0; i < p; ++i) out[i] = (((L[i] & 0x3fffffff) * 3) >> 30) - 1;
explicit_bzero(L, sizeof(L));
}
static void KeyGen(Fq *h, small *f, small *ginv) {
small g[p];
Fq finv[p];

View File

@@ -1,5 +1,5 @@
#!/bin/sh
# $OpenBSD: sntrup761.sh,v 1.9 2024/09/16 05:37:05 djm Exp $
# $OpenBSD: sntrup761.sh,v 1.10 2026/01/20 22:56:11 dtucker Exp $
# Placed in the Public Domain.
#
AUTHOR="supercop-20240808/crypto_kem/sntrup761/ref/implementors"
@@ -87,6 +87,28 @@ for i in $FILES; do
*/uint32/useint32/sort.c)
sed -e "s/void crypto_sort/void crypto_sort_uint32/g"
;;
# Replace Short_random and Small_random with versions that fetch
# entropy in a single operation, then delete urandom32 as unused.
*/crypto_kem/sntrup761/compact/kem.c)
sed -e '/ uint32_t urandom32/,/^}$/d' \
-e '/ void Short_random/i\
static void Short_random(small *out) {\
uint32_t L[p];\
randombytes(L, sizeof(L));\
Short_fromlist(out, L);\
explicit_bzero(L, sizeof(L));\
}' \
-e '/ void Short_random(/,/^}$/d' \
-e '/ void Small_random/i\
static void Small_random(small *out) {\
int i;\
uint32_t L[p];\
randombytes(L, sizeof(L));\
for (i = 0; i < p; ++i) out[i] = (((L[i] & 0x3fffffff) * 3) >> 30) - 1;\
explicit_bzero(L, sizeof(L));\
}' \
-e '/ void Small_random(/,/^}$/d'
;;
# Remove unused function to prevent warning.
*/crypto_kem/sntrup761/ref/int32.c)
sed -e '/ int32_div_uint14/,/^}$/d'