31#ifndef PROTOCORE_FE25519_H
32#define PROTOCORE_FE25519_H
36#if PROTOCORE_ENABLE_FE25519
44#if PROTOCORE_RSA_MODMUL_HW
45#define PROTOCORE_FE25519_MPI_HW 1
48#if PROTOCORE_FE25519_MPI_HW
51typedef uint32_t fe[8];
56static const uint32_t FE_MOD_MPRIME = 0x286bca1bu;
57static const uint32_t FE_MOD_P[8] = {0xffffffedu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
58 0xffffffffu, 0xffffffffu, 0xffffffffu, 0x7fffffffu};
59static const uint32_t FE_MOD_R2[8] = {0x000005a4u, 0, 0, 0, 0, 0, 0, 0};
63static inline void protocore_fe_hw_enable(
void)
65 protocore_rsa_hw_acquire();
67static inline void protocore_fe_hw_disable(
void)
69 protocore_rsa_hw_release();
76static inline void fe_mul(fe z,
const fe x,
const fe y)
78 protocore_rsa_modmul(z, x, y, FE_MOD_P, FE_MOD_MPRIME, FE_MOD_R2, 8);
80static inline void fe_sq(fe o,
const fe x)
85static inline void fe_copy(fe o,
const fe a)
87 for (
int i = 0; i < 8; i++)
92static inline void fe_0(fe o)
94 for (
int i = 0; i < 8; i++)
99static inline void fe_1(fe o)
102 for (
int i = 1; i < 8; i++)
108static inline void fe_reduce_once(fe o)
112 for (
int i = 0; i < 8; i++)
114 b += (int64_t)o[i] - (int64_t)FE_MOD_P[i];
118 uint32_t keep = (uint32_t)b;
119 for (
int i = 0; i < 8; i++)
121 o[i] = (o[i] & keep) | (t[i] & ~keep);
124static inline void fe_add(fe o,
const fe x,
const fe y)
127 for (
int i = 0; i < 8; i++)
129 c += (uint64_t)x[i] + y[i];
135static inline void fe_sub(fe o,
const fe x,
const fe y)
139 for (
int i = 0; i < 8; i++)
141 b += (int64_t)x[i] - (int64_t)y[i];
145 uint32_t borrow = (uint32_t)b;
147 for (
int i = 0; i < 8; i++)
149 c += (uint64_t)t[i] + (FE_MOD_P[i] & borrow);
154static inline void fe_cswap(fe x, fe y, uint32_t swap)
156 uint32_t mask = (uint32_t)(-(int32_t)swap);
157 for (
int i = 0; i < 8; i++)
159 uint32_t t = mask & (x[i] ^ y[i]);
164static inline void fe_frombytes(fe o,
const uint8_t b[32])
166 for (
int i = 0; i < 8; i++)
168 o[i] = (uint32_t)b[4 * i] | ((uint32_t)b[4 * i + 1] << 8) | ((uint32_t)b[4 * i + 2] << 16) |
169 ((uint32_t)b[4 * i + 3] << 24);
174static inline void fe_tobytes(uint8_t b[32],
const fe a)
179 for (
int i = 0; i < 8; i++)
181 b[4 * i] = (uint8_t)t[i];
182 b[4 * i + 1] = (uint8_t)(t[i] >> 8);
183 b[4 * i + 2] = (uint8_t)(t[i] >> 16);
184 b[4 * i + 3] = (uint8_t)(t[i] >> 24);
188static inline void fe_invert(fe o,
const fe a)
192 for (
int i = 253; i >= 0; i--)
195 if (i != 2 && i != 4)
203static inline void fe_pow2523(fe o,
const fe a)
207 for (
int i = 250; i >= 0; i--)
218static inline int fe_parity(
const fe a)
225static inline int fe_neq(
const fe a,
const fe b)
231 return protocore_ct_eq(c, d, 32) ? 0 : -1;
308} Fe25519FromBytesArgs;
406 Fe25519MulArgs mul_args;
407 Fe25519SqArgs sq_args;
408 Fe25519CopyArgs copy_args;
409 Fe25519ZeroArgs zero_args;
410 Fe25519OneArgs one_args;
411 Fe25519ReduceArgs reduce_args;
412 Fe25519AddArgs add_args;
413 Fe25519SubArgs sub_args;
414 Fe25519CswapArgs cswap_args;
415 Fe25519FromBytesArgs frombytes_args;
416 Fe25519ToBytesArgs tobytes_args;
417 Fe25519InvertArgs invert_args;
418 Fe25519Pow2523Args pow2523_args;
419 Fe25519ParityArgs parity_args;
420 Fe25519NeqArgs neq_args;
427extern Fe25519Vars Fe25519V;
432 void (*
const hw_enable)(uint8_t *work);
433 void (*
const hw_disable)(uint8_t *work);
434 void (*
const mul)(uint8_t *work);
435 void (*
const sq)(uint8_t *work);
436 void (*
const copy)(uint8_t *work);
437 void (*
const zero)(uint8_t *work);
438 void (*
const one)(uint8_t *work);
439 void (*
const reduce_once)(uint8_t *work);
440 void (*
const add)(uint8_t *work);
441 void (*
const sub)(uint8_t *work);
442 void (*
const cswap)(uint8_t *work);
443 void (*
const frombytes)(uint8_t *work);
444 void (*
const tobytes)(uint8_t *work);
445 void (*
const invert)(uint8_t *work);
446 void (*
const pow2523)(uint8_t *work);
447 void (*
const get_parity)(uint8_t *work);
448 void (*
const get_neq)(uint8_t *work);
453void protocore_fe25519_hw_enable(uint8_t *work);
454void protocore_fe25519_hw_disable(uint8_t *work);
455void protocore_fe25519_mul(uint8_t *work);
456void protocore_fe25519_sq(uint8_t *work);
457void protocore_fe25519_copy(uint8_t *work);
458void protocore_fe25519_zero(uint8_t *work);
459void protocore_fe25519_one(uint8_t *work);
460void protocore_fe25519_reduce_once(uint8_t *work);
461void protocore_fe25519_add(uint8_t *work);
462void protocore_fe25519_sub(uint8_t *work);
463void protocore_fe25519_cswap(uint8_t *work);
464void protocore_fe25519_frombytes(uint8_t *work);
465void protocore_fe25519_tobytes(uint8_t *work);
466void protocore_fe25519_invert(uint8_t *work);
467void protocore_fe25519_pow2523(uint8_t *work);
468void protocore_fe25519_get_parity(uint8_t *work);
469void protocore_fe25519_get_neq(uint8_t *work);
475static const Fe25519Ns Fe25519 __attribute__((unused)) = {
476 .hw_enable = protocore_fe25519_hw_enable,
477 .hw_disable = protocore_fe25519_hw_disable,
478 .mul = protocore_fe25519_mul,
479 .sq = protocore_fe25519_sq,
480 .copy = protocore_fe25519_copy,
481 .zero = protocore_fe25519_zero,
482 .one = protocore_fe25519_one,
483 .reduce_once = protocore_fe25519_reduce_once,
484 .add = protocore_fe25519_add,
485 .sub = protocore_fe25519_sub,
486 .cswap = protocore_fe25519_cswap,
487 .frombytes = protocore_fe25519_frombytes,
488 .tobytes = protocore_fe25519_tobytes,
489 .invert = protocore_fe25519_invert,
490 .pow2523 = protocore_fe25519_pow2523,
491 .get_parity = protocore_fe25519_get_parity,
492 .get_neq = protocore_fe25519_get_neq,
Constant-time comparison for secret-dependent checks.
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
_Bool proto_bool
The truth value.
#define PROTOCORE_END_DECLS