@@ -28488,7 +28488,7 @@ FIO_IFUNC void fio___x25519_scalarmult(uint8_t out[32],
2848828488 const uint8_t scalar[32],
2848928489 const uint8_t point[32]) {
2849028490 uint8_t z[32];
28491- FIO_MEMCPY (z, scalar, 32 );
28491+ fio_memcpy32 (z, scalar);
2849228492 z[31] = (scalar[31] & 127) | 64;
2849328493 z[0] &= 248;
2849428494
@@ -28751,7 +28751,7 @@ FIO_IFUNC void fio___ge_p3_tobytes(uint8_t out[32], fio___ge_p3_s p) {
2875128751/* decode 32 bytes to point (returns 0 on success, -1 on failure) */
2875228752FIO_SFUNC int fio___ge_p3_frombytes(fio___ge_p3_s p, const uint8_t in[32]) {
2875328753 uint8_t s[32];
28754- FIO_MEMCPY (s, in, 32 );
28754+ fio_memcpy32 (s, in);
2875528755 int x_sign = s[31] >> 7;
2875628756 s[31] &= 0x7F;
2875728757
@@ -28858,10 +28858,11 @@ FIO_SFUNC void fio___sc_muladd(uint8_t s[32],
2885828858 for (j = 0; j < 32; ++j)
2885928859 x[i + j] += (unsigned long long)b[i] * (unsigned long long)c[j];
2886028860 uint8_t tmp[64];
28861- for (i = 0; i < 64 ; ++i) {
28861+ for (i = 0; i < 63 ; ++i) {
2886228862 x[i + 1] += x[i] >> 8;
2886328863 tmp[i] = x[i] & 255;
2886428864 }
28865+ tmp[63] = x[63] & 255;
2886528866 fio___sc_reduce(s, tmp);
2886628867}
2886728868
@@ -28941,17 +28942,29 @@ SFUNC int fio_ed25519_verify(const uint8_t signature[64],
2894128942 return -1;
2894228943
2894328944 /* check s < l */
28944- static const uint8_t l[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
28945- 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
28946- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28947- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
28948- const uint8_t *s = signature + 32;
28949- uint8_t c = 0;
28950- for (int i = 31; i >= 0; --i) {
28951- c = (s[i] > l[i]) | ((s[i] == l[i]) & c);
28952- }
28953- if (c)
28954- return -1;
28945+ { /* check s < l */
28946+ static const uint64_t l_u64[4] FIO_ALIGN(16) = {
28947+ 0x5812631a5cf5d3edULL, /* l[0..7] */
28948+ 0x14def9dea2f79cd6ULL, /* l[8..15] */
28949+ 0x0000000000000000ULL, /* l[16..23] */
28950+ 0x1000000000000000ULL, /* l[24..31] */
28951+ };
28952+ /* Load s as little-endian uint64_t (handles endianness) */
28953+ uint64_t s_u64[4] FIO_ALIGN(16);
28954+ s_u64[0] = fio_buf2u64_le(signature + 32 + 0);
28955+ s_u64[1] = fio_buf2u64_le(signature + 32 + 8);
28956+ s_u64[2] = fio_buf2u64_le(signature + 32 + 16);
28957+ s_u64[3] = fio_buf2u64_le(signature + 32 + 24);
28958+ /* Constant-time comparison */
28959+ uint8_t c = 0;
28960+ for (int i = 0; i < 4; i++) {
28961+ uint8_t gt = s_u64[i] > l_u64[i];
28962+ uint8_t eq = s_u64[i] == l_u64[i];
28963+ c = gt | (eq & c);
28964+ }
28965+ if (c)
28966+ return -1;
28967+ }
2895528968
2895628969 /* k = h(r || public_key || message) mod l */
2895728970 fio_sha512_s sha = fio_sha512_init();
@@ -28999,7 +29012,7 @@ SFUNC void fio_ed25519_sk_to_x25519(uint8_t x_secret_key[32],
2899929012 const uint8_t ed_secret_key[32]) {
2900029013 /* hash ed25519 secret key and use first 32 bytes */
2900129014 fio_u512 h = fio_sha512(ed_secret_key, 32);
29002- FIO_MEMCPY (x_secret_key, h.u8, 32 );
29015+ fio_memcpy32 (x_secret_key, h.u8);
2900329016 /* x25519 clamping is done in the scalar multiplication */
2900429017}
2900529018
@@ -29059,7 +29072,7 @@ SFUNC int fio_x25519_encrypt(uint8_t *ciphertext,
2905929072 fio_secure_zero(shared, 32);
2906029073
2906129074 /* copy ephemeral public key to output */
29062- FIO_MEMCPY (ciphertext, eph_pk, 32 );
29075+ fio_memcpy32 (ciphertext, eph_pk);
2906329076
2906429077 /* copy plaintext to ciphertext buffer (after eph_pk and mac space) */
2906529078 if (message_len > 0)
@@ -29112,7 +29125,7 @@ SFUNC int fio_x25519_decrypt(uint8_t *plaintext,
2911229125
2911329126 /* copy mac for in-place verification (chacha20_poly1305_dec modifies it) */
2911429127 uint8_t mac_copy[16];
29115- FIO_MEMCPY (mac_copy, mac, 16 );
29128+ fio_memcpy16 (mac_copy, mac);
2911629129
2911729130 /* decrypt and verify with chacha20-poly1305 */
2911829131 int result = fio_chacha20_poly1305_dec(mac_copy, /* mac to verify */
0 commit comments