/* scalar25519.h -- arithmetic mod L (the Ed25519 base point's order), * for reducing SHA-512 output to a valid scalar and checking a * signature's S component for the RFC 8032 malleability requirement * (S < L, not just S < 2^256). * * Deliberately NOT the intricate hand-tuned "sc_reduce" reduction most * reference implementations use (a bespoke Barrett-style reduction with * constants specific to L, notoriously easy to transcribe wrong) -- * this is a plain binary long-division reduction, one bit at a time. * O(512) steps per reduction; this is a verify-only, non-hot-path * library (one reduction per signature check), so the simpler, * more obviously-correct approach is the right tradeoff here. */ #ifndef SCALAR25519_H #define SCALAR25519_H #include /* 32-byte little-endian scalars, reduced mod L where noted. */ /* Reduce a 64-byte little-endian value (e.g. raw SHA-512 output) mod L, * producing a 32-byte little-endian result < L. */ void scalar_reduce512(uint8_t out[32], const uint8_t in[64]); /* 1 if the 32-byte little-endian scalar is < L (a well-formed, * non-malleable signature component per RFC 8032), else 0. */ int scalar_lt_L(const uint8_t s[32]); /* out = (a*b + c) mod L, all 32-byte little-endian scalars (a, b, c need * not already be reduced mod L, though every caller in this codebase * passes already-reduced inputs). Needed for EdDSA signing's * S = (k*a + r) mod L step -- verify never needed scalar multiplication, * only reduction, so this didn't exist until signing did. */ void scalar_muladd(uint8_t out[32], const uint8_t a[32], const uint8_t b[32], const uint8_t c[32]); #endif /* SCALAR25519_H */