24#ifndef PROTOCORE_FE25519_H
25#define PROTOCORE_FE25519_H
34#ifdef PC_RSA_MODMUL_HW
35#define PC_FE25519_MPI_HW 1
38#ifdef PC_FE25519_MPI_HW
41typedef uint32_t fe[8];
46static const uint32_t FE_MOD_MPRIME = 0x286bca1bu;
47static const uint32_t FE_MOD_P[8] = {0xffffffedu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
48 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x7fffffffu};
49static const uint32_t FE_MOD_R2[8] = {0x000005a4u, 0, 0, 0, 0, 0, 0, 0};
53static inline void pc_fe_hw_enable(
void)
57static inline void pc_fe_hw_disable(
void)
66static inline void fe_mul(fe z,
const fe x,
const fe y)
68 pc_rsa_modmul(z, x, y, FE_MOD_P, FE_MOD_MPRIME, FE_MOD_R2, 8);
70static inline void fe_sq(fe o,
const fe x)
75static inline void fe_copy(fe o,
const fe a)
77 for (
int i = 0; i < 8; i++)
82static inline void fe_0(fe o)
84 for (
int i = 0; i < 8; i++)
89static inline void fe_1(fe o)
92 for (
int i = 1; i < 8; i++)
98static inline void fe_reduce_once(fe o)
102 for (
int i = 0; i < 8; i++)
104 b += (int64_t)o[i] - (int64_t)FE_MOD_P[i];
108 uint32_t keep = (uint32_t)b;
109 for (
int i = 0; i < 8; i++)
111 o[i] = (o[i] & keep) | (t[i] & ~keep);
114static inline void fe_add(fe o,
const fe x,
const fe y)
117 for (
int i = 0; i < 8; i++)
119 c += (uint64_t)x[i] + y[i];
125static inline void fe_sub(fe o,
const fe x,
const fe y)
129 for (
int i = 0; i < 8; i++)
131 b += (int64_t)x[i] - (int64_t)y[i];
135 uint32_t borrow = (uint32_t)b;
137 for (
int i = 0; i < 8; i++)
139 c += (uint64_t)t[i] + (FE_MOD_P[i] & borrow);
144static inline void fe_cswap(fe x, fe y, uint32_t swap)
146 uint32_t
mask = (uint32_t)(-(int32_t)swap);
147 for (
int i = 0; i < 8; i++)
149 uint32_t t =
mask & (x[i] ^ y[i]);
154static inline void fe_frombytes(fe o,
const uint8_t b[32])
156 for (
int i = 0; i < 8; i++)
158 o[i] = (uint32_t)b[4 * i] | ((uint32_t)b[4 * i + 1] << 8) | ((uint32_t)b[4 * i + 2] << 16) |
159 ((uint32_t)b[4 * i + 3] << 24);
164static inline void fe_tobytes(uint8_t b[32],
const fe a)
169 for (
int i = 0; i < 8; i++)
171 b[4 * i] = (uint8_t)t[i];
172 b[4 * i + 1] = (uint8_t)(t[i] >> 8);
173 b[4 * i + 2] = (uint8_t)(t[i] >> 16);
174 b[4 * i + 3] = (uint8_t)(t[i] >> 24);
178static inline void fe_invert(fe o,
const fe a)
182 for (
int i = 253; i >= 0; i--)
185 if (i != 2 && i != 4)
193static inline void fe_pow2523(fe o,
const fe a)
197 for (
int i = 250; i >= 0; i--)
208static inline int fe_parity(
const fe a)
215static inline int fe_neq(
const fe a,
const fe b)
221 return pc_ct_eq(c, d, 32) ? 0 : -1;
Constant-time comparison for secret-dependent checks.
Single owner of the ESP32 RSA/MPI accelerator, by DIRECT register access - a self-contained HAL.
uint32_t mask(uint8_t width)
Mask of width low bits (width 32 handled without a 32-bit shift, which is UB).