LCOV - code coverage report
Current view: top level - ballet/ed25519 - fd_f25519.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 26 26 100.0 %
Date: 2025-12-05 04:49:52 Functions: 13 150 8.7 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_ballet_ed25519_fd_f25519_h
       2             : #define HEADER_fd_src_ballet_ed25519_fd_f25519_h
       3             : 
       4             : /* fd_f25519.h provides the public field API for the base field of curve25519.
       5             : 
       6             :    Most operations in this API should be assumed to take a variable amount
       7             :    of time depending on inputs, and thus should not be exposed to secret data.
       8             : 
       9             :    Constant-time operations are made explicit. */
      10             : 
      11             : #include "../fd_ballet_base.h"
      12             : #include "../../util/rng/fd_rng.h"
      13             : 
      14             : #define FD_25519_INLINE static inline
      15             : 
      16             : /* fd_f25519_t is the type of a field element, i.e. an integer
      17             :    mod p = 2^255 - 19.
      18             :    it's internal representation (and alignment) depends on the
      19             :    backend: ref, avx, avx512. */
      20             : 
      21             : #if FD_HAS_AVX512
      22             : #include "avx512/fd_f25519.h"
      23             : #else
      24             : #include "ref/fd_f25519.h"
      25             : #endif
      26             : 
      27             : /* field constants. these are imported from table/fd_f25519_table_{arch}.c.
      28             :    they are (re)defined here to avoid breaking compilation when the table needs
      29             :    to be rebuilt. */
      30             : static const fd_f25519_t fd_f25519_zero[1];
      31             : static const fd_f25519_t fd_f25519_one[1];
      32             : static const fd_f25519_t fd_f25519_minus_one[1];
      33             : static const fd_f25519_t fd_f25519_two[1];
      34             : static const fd_f25519_t fd_f25519_nine[1];
      35             : static const fd_f25519_t fd_f25519_k[1];
      36             : static const fd_f25519_t fd_f25519_minus_k[1];
      37             : static const fd_f25519_t fd_f25519_d[1];
      38             : static const fd_f25519_t fd_f25519_sqrtm1[1];
      39             : static const fd_f25519_t fd_f25519_invsqrt_a_minus_d[1];
      40             : static const fd_f25519_t fd_f25519_one_minus_d_sq[1];
      41             : static const fd_f25519_t fd_f25519_d_minus_one_sq[1];
      42             : static const fd_f25519_t fd_f25519_sqrt_ad_minus_one[1];
      43             : 
      44             : FD_PROTOTYPES_BEGIN
      45             : 
      46             : /* fd_f25519_mul computes r = a * b, and returns r. */
      47             : fd_f25519_t *
      48             : fd_f25519_mul( fd_f25519_t *       r,
      49             :                fd_f25519_t const * a,
      50             :                fd_f25519_t const * b );
      51             : 
      52             : /* fd_f25519_sqr computes r = a^2, and returns r. */
      53             : fd_f25519_t *
      54             : fd_f25519_sqr( fd_f25519_t *       r,
      55             :                fd_f25519_t const * a );
      56             : 
      57             : /* fd_f25519_add computes r = a + b, and returns r. */
      58             : fd_f25519_t *
      59             : fd_f25519_add( fd_f25519_t *       r,
      60             :                fd_f25519_t const * a,
      61             :                fd_f25519_t const * b );
      62             : 
      63             : /* fd_f25519_add computes r = a - b, and returns r. */
      64             : fd_f25519_t *
      65             : fd_f25519_sub( fd_f25519_t *       r,
      66             :                fd_f25519_t const * a,
      67             :                fd_f25519_t const * b );
      68             : 
      69             : /* fd_f25519_add_nr computes r = a + b, and returns r.
      70             :    Note: this does NOT reduce the result mod p.
      71             :    It can be used before mul, sqr. */
      72             : fd_f25519_t *
      73             : fd_f25519_add_nr( fd_f25519_t * r,
      74             :                   fd_f25519_t const * a,
      75             :                   fd_f25519_t const * b );
      76             : 
      77             : /* fd_f25519_sub_nr computes r = a - b, and returns r.
      78             :    Note: this does NOT reduce the result mod p.
      79             :    It can be used before mul, sqr. */
      80             : fd_f25519_t *
      81             : fd_f25519_sub_nr( fd_f25519_t * r,
      82             :                   fd_f25519_t const * a,
      83             :                   fd_f25519_t const * b );
      84             : 
      85             : /* fd_f25519_add computes r = -a, and returns r. */
      86             : fd_f25519_t *
      87             : fd_f25519_neg( fd_f25519_t *       r,
      88             :                fd_f25519_t const * a );
      89             : 
      90             : /* fd_f25519_mul_121666 computes r = a * k, k=121666, and returns r. */
      91             : fd_f25519_t *
      92             : fd_f25519_mul_121666( fd_f25519_t *       r,
      93             :                       fd_f25519_t const * a );
      94             : 
      95             : /* fd_f25519_frombytes deserializes a 32-byte buffer buf into a
      96             :    fd_f25519_t element r, and returns r.
      97             :    buf is in little endian form, we accept non-canonical elements
      98             :    unlike RFC 8032. */
      99             : fd_f25519_t *
     100             : fd_f25519_frombytes( fd_f25519_t * r,
     101             :                      uchar const   buf[ 32 ] );
     102             : 
     103             : /* fd_f25519_tobytes serializes a fd_f25519_t element a into
     104             :    a 32-byte buffer out, and returns out.
     105             :    out is in little endian form, according to RFC 8032
     106             :    (we don't output non-canonical elements). */
     107             : uchar *
     108             : fd_f25519_tobytes( uchar               out[ 32 ],
     109             :                    fd_f25519_t const * a );
     110             : 
     111             : /* fd_f25519_set copies r = a, and returns r. */
     112             : fd_f25519_t *
     113             : fd_f25519_set( fd_f25519_t *       r,
     114             :                fd_f25519_t const * a );
     115             : 
     116             : /* fd_f25519_is_zero returns 1 if a == 0, 0 otherwise. */
     117             : int
     118             : fd_f25519_is_zero( fd_f25519_t const * a );
     119             : 
     120             : /* fd_f25519_if sets r = a0 if cond, else r = a1, equivalent to:
     121             :    r = cond ? a0 : a1.
     122             :    Note: this is constant time. */
     123             : fd_f25519_t *
     124             : fd_f25519_if( fd_f25519_t *       r,
     125             :               int const           cond, /* 0, 1 */
     126             :               fd_f25519_t const * a0,
     127             :               fd_f25519_t const * a1 );
     128             : 
     129             : /* fd_f25519_rng generates a random fd_f25519_t element.
     130             :    Note: insecure, for tests only. */
     131             : fd_f25519_t *
     132             : fd_f25519_rng_unsafe( fd_f25519_t * r,
     133             :                       fd_rng_t *    rng );
     134             : 
     135             : /*
     136             :  * Derived
     137             :  */
     138             : 
     139             : /* fd_f25519_eq returns 1 if a == b, 0 otherwise. */
     140             : FD_25519_INLINE int
     141             : fd_f25519_eq( fd_f25519_t const * a,
     142     9582853 :               fd_f25519_t const * b ) {
     143     9582853 :   fd_f25519_t r[1];
     144     9582853 :   fd_f25519_sub( r, a, b );
     145     9582853 :   return fd_f25519_is_zero( r );
     146     9582853 : }
     147             : 
     148             : /* fd_f25519_is_nonzero returns 1 (true) if a != 0, 0 if a == 0. */
     149             : FD_25519_INLINE int
     150      300000 : fd_f25519_is_nonzero( fd_f25519_t const * a ) {
     151      300000 :   return !fd_f25519_is_zero( a );
     152      300000 : }
     153             : 
     154             : /* fd_f25519_sgn returns the sign of a (lsb). */
     155             : FD_25519_INLINE int
     156     6167687 : fd_f25519_sgn( fd_f25519_t const * a ) {
     157             :   //TODO: make it faster (unless inlining already optimizes out unnecessary code)
     158     6167687 :   uchar buf[32];
     159     6167687 :   fd_f25519_tobytes( buf, a );
     160     6167687 :   return buf[0] & 1;
     161     6167687 : }
     162             : 
     163             : /* fd_f25519_abs sets r = |a|. */
     164             : FD_25519_INLINE fd_f25519_t *
     165             : fd_f25519_abs( fd_f25519_t *       r,
     166     2424525 :                fd_f25519_t const * a ) {
     167     2424525 :   fd_f25519_t neg_a[1];
     168     2424525 :   fd_f25519_neg( neg_a, a );
     169     2424525 :   return fd_f25519_if( r, fd_f25519_sgn(a), neg_a, a );
     170     2424525 : }
     171             : 
     172             : /* fd_f25519_abs sets r = -|a|. */
     173             : FD_25519_INLINE fd_f25519_t *
     174             : fd_f25519_neg_abs( fd_f25519_t *       r,
     175       90006 :                    fd_f25519_t const * a ) {
     176       90006 :   fd_f25519_t neg_a[1];
     177       90006 :   fd_f25519_neg( neg_a, a );
     178       90006 :   return fd_f25519_if( r, fd_f25519_sgn(a), a, neg_a );
     179       90006 : }
     180             : 
     181             : /*
     182             :  * Inv & Sqrt
     183             :  */
     184             : 
     185             : /* fd_f25519_inv computes r = 1/a, and returns r. */
     186             : fd_f25519_t *
     187             : fd_f25519_inv( fd_f25519_t *       r,
     188             :                fd_f25519_t const * a );
     189             : 
     190             : /* fd_f25519_pow22523 computes r = a^(2^252-3), and returns r. */
     191             : fd_f25519_t *
     192             : fd_f25519_pow22523( fd_f25519_t *       r,
     193             :                     fd_f25519_t const * a );
     194             : 
     195             : /* fd_f25519_sqrt_ratio computes r = (u * v^3) * (u * v^7)^((p-5)/8),
     196             :    returns 0 on success, 1 on failure. */
     197             : int
     198             : fd_f25519_sqrt_ratio( fd_f25519_t *       r,
     199             :                       fd_f25519_t const * u,
     200             :                       fd_f25519_t const * v );
     201             : 
     202             : /* fd_f25519_sqrt_ratio computes r = 1/sqrt(v),
     203             :    returns 0 on success, 1 on failure. */
     204             : FD_25519_INLINE int
     205             : fd_f25519_inv_sqrt( fd_f25519_t *       r,
     206      601713 :                     fd_f25519_t const * v ) {
     207      601713 :   return fd_f25519_sqrt_ratio( r, fd_f25519_one, v );
     208      601713 : }
     209             : 
     210             : /*
     211             :  * Vectorized
     212             :  */
     213             : 
     214             : /* fd_f25519_muln computes r_i = a_i * b_i */
     215             : void
     216             : fd_f25519_mul2( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     217             :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2 );
     218             : 
     219             : void
     220             : fd_f25519_mul3( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     221             :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
     222             :                 fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3 );
     223             : 
     224             : void
     225             : fd_f25519_mul4( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     226             :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
     227             :                 fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3,
     228             :                 fd_f25519_t * r4, fd_f25519_t const * a4, fd_f25519_t const * b4 );
     229             : 
     230             : /* fd_f25519_sqrn computes r_i = a_i^2 */
     231             : void
     232             : fd_f25519_sqr2( fd_f25519_t * r1, fd_f25519_t const * a1,
     233             :                 fd_f25519_t * r2, fd_f25519_t const * a2 );
     234             : 
     235             : void
     236             : fd_f25519_sqr3( fd_f25519_t * r1, fd_f25519_t const * a1,
     237             :                 fd_f25519_t * r2, fd_f25519_t const * a2,
     238             :                 fd_f25519_t * r3, fd_f25519_t const * a3 );
     239             : 
     240             : void
     241             : fd_f25519_sqr4( fd_f25519_t * r1, fd_f25519_t const * a1,
     242             :                 fd_f25519_t * r2, fd_f25519_t const * a2,
     243             :                 fd_f25519_t * r3, fd_f25519_t const * a3,
     244             :                 fd_f25519_t * r4, fd_f25519_t const * a4 );
     245             : 
     246             : /* fd_f25519_pow22523 computes r = a^(2^252-3), and returns r. */
     247             : fd_f25519_t *
     248             : fd_f25519_pow22523_2( fd_f25519_t * r1, fd_f25519_t const * a1,
     249             :                       fd_f25519_t * r2, fd_f25519_t const * a2 );
     250             : 
     251             : /* fd_f25519_sqrt_ratio computes r = (u * v^3) * (u * v^7)^((p-5)/8),
     252             :    returns 0 on success, 1 on failure. */
     253             : int
     254             : fd_f25519_sqrt_ratio2( fd_f25519_t * r1, fd_f25519_t const * u1, fd_f25519_t const * v1,
     255             :                        fd_f25519_t * r2, fd_f25519_t const * u2, fd_f25519_t const * v2 );
     256             : 
     257             : /* fd_f25519_debug prints the element a, for debugging purposes. */
     258             : void
     259             : fd_f25519_debug( char const *        name,
     260             :                  fd_f25519_t const * a );
     261             : 
     262             : FD_PROTOTYPES_END
     263             : 
     264             : #endif /* HEADER_fd_src_ballet_ed25519_fd_f25519_h */

Generated by: LCOV version 1.14