36 bool initialized =
false;
42static void bn_sub_inplace(uint32_t *a,
const uint32_t *b,
int n)
45 for (
int i = 0; i < n; i++)
47 uint64_t v = (uint64_t)a[i] - b[i] - borrow;
49 borrow = (v >> 32) & 1u;
54static uint32_t bn_shl1(uint32_t *a,
int n)
57 for (
int i = 0; i < n; i++)
59 uint32_t nc = a[i] >> 31;
60 a[i] = (a[i] << 1) | carry;
70static void bn_init(
void)
84 uint64_t v = (uint64_t)0 -
group14_p.
d[i] - borrow;
85 s_g14.
r1.
d[i] = (uint32_t)v;
86 borrow = (v >> 32) & 1u;
95 for (
int i = 0; i < 2048; i++)
134 "BnExpmodWork outgrew PC_WORK_BIGNUM_SW - raise it; PC_SECURE_ARENA_SIZE derives from it");
146 memset(t, 0, 129 *
sizeof(uint32_t));
154 uint64_t uv = (uint64_t)t[i + j] + (uint64_t)a->
d[i] * (uint64_t)b->
d[j] + carry;
155 t[i + j] = (uint32_t)uv;
165 uint64_t uv = (uint64_t)t[i + j] + (uint64_t)m * (uint64_t)
group14_p.
d[j] + carry;
166 t[i + j] = (uint32_t)uv;
170 uint64_t hi = (uint64_t)t[i +
PC_BN_LIMBS] + carry;
201 SecureBorrow ws_b(
sizeof(BnExpmodWork),
alignof(BnExpmodWork));
205 memset(out, 0,
sizeof(*out));
208 BnExpmodWork *w =
reinterpret_cast<BnExpmodWork *
>(ws.
buf);
215 bn_monpro(base_mont, base, &s_g14.
r2, w->t);
223 for (
int b = 31; b >= 0; b--)
226 bn_monpro(tmp, result, result, w->t);
229 if ((exp->
d[i] >> b) & 1u)
232 bn_monpro(tmp, result, base_mont, w->t);
243 bn_monpro(out, result, &one, w->t);
PC_CRYPTO_HOT const pc_bignum group14_p
The RFC 3526 MODP group-14 prime (2048-bit).
int bn_cmp_raw(const uint32_t *a, const uint32_t *b, int n)
Compute out = base^exp mod group14_p.
2048-bit big-integer arithmetic for DH-group14 and RSA-2048.
#define PC_BN_LIMBS
Number of 32-bit limbs in a 2048-bit integer.
A secure borrow whose acquire and release are one call each.
const pc_span & span() const
The borrowed region; empty if the pool could not satisfy it.
Per-translation-unit optimization override for hot, pure-integer crypto.
void bn_expmod_group14(pc_bignum *out, const pc_bignum *base, const pc_bignum *exp)
#define PC_WORK_BIGNUM_SW
Secure pool accessor - borrows that hold key material.
bool pc_span_ok(const pc_span &s)
True when the span refers to real storage and every write so far has fit.
A 2048-bit unsigned integer stored as 64 little-endian 32-bit limbs.
uint32_t d[PC_BN_LIMBS]
256 bytes of magnitude, little-endian limbs.
A writable byte region: the storage, the capacity that belongs to it, and what has been produced into...
uint8_t * buf
first byte, or nullptr when the region could not be obtained