LCOV - code coverage report
Current view: top level - ballet/ed25519/ref - fd_f25519.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 117 122 95.9 %
Date: 2025-11-15 04:42:28 Functions: 71 500 14.2 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_ballet_ed25519_fd_f25519_h
       2             : #error "Do not include this directly; use fd_f25519.h"
       3             : #endif
       4             : 
       5             : #include "../../fd_ballet_base.h"
       6             : 
       7             : #define USE_FIAT_32 0
       8             : #if USE_FIAT_32
       9             : #include "../../fiat-crypto/curve25519_32.c"
      10             : #else
      11             : #include "../../fiat-crypto/curve25519_64.c"
      12             : #endif
      13             : 
      14             : /* A fd_f25519_t stores a curve25519 field element in 10 uint (32 bit),
      15             :    or 5 ulong (64 bit). */
      16             : struct fd_f25519 {
      17             : #if USE_FIAT_32
      18             :   uint el[10];
      19             : #else
      20             :   ulong el[5];
      21             : #endif
      22             : };
      23             : typedef struct fd_f25519 fd_f25519_t;
      24             : 
      25             : #include "../table/fd_f25519_table_ref.c"
      26             : 
      27             : FD_PROTOTYPES_BEGIN
      28             : 
      29             : /*
      30             :  * Implementation of inline functions
      31             :  */
      32             : 
      33             : /* fd_f25519_mul computes r = a * b, and returns r. */
      34             : FD_25519_INLINE fd_f25519_t *
      35             : fd_f25519_mul( fd_f25519_t * r,
      36             :                fd_f25519_t const * a,
      37  1541820143 :                fd_f25519_t const * b ) {
      38  1541820143 :   fiat_25519_carry_mul( r->el, a->el, b->el );
      39  1541820143 :   return r;
      40  1541820143 : }
      41             : 
      42             : /* fd_f25519_sqr computes r = a^2, and returns r. */
      43             : FD_25519_INLINE fd_f25519_t *
      44             : fd_f25519_sqr( fd_f25519_t * r,
      45  1480431104 :                fd_f25519_t const * a ) {
      46  1480431104 :   fiat_25519_carry_square( r->el, a->el );
      47  1480431104 :   return r;
      48  1480431104 : }
      49             : 
      50             : /* fd_f25519_add computes r = a + b, and returns r. */
      51             : FD_25519_INLINE fd_f25519_t *
      52             : fd_f25519_add( fd_f25519_t * r,
      53             :                fd_f25519_t const * a,
      54   373877743 :                fd_f25519_t const * b ) {
      55   373877743 :   fiat_25519_add( r->el, a->el, b->el );
      56   373877743 :   fiat_25519_carry( r->el, r->el );
      57   373877743 :   return r;
      58   373877743 : }
      59             : 
      60             : /* fd_f25519_add computes r = a - b, and returns r. */
      61             : FD_25519_INLINE fd_f25519_t *
      62             : fd_f25519_sub( fd_f25519_t * r,
      63             :                fd_f25519_t const * a,
      64   151956190 :                fd_f25519_t const * b ) {
      65   151956190 :   fiat_25519_sub( r->el, a->el, b->el );
      66   151956190 :   fiat_25519_carry( r->el, r->el );
      67   151956190 :   return r;
      68   151956190 : }
      69             : 
      70             : /* fd_f25519_add computes r = a + b, and returns r.
      71             :    Note: this does NOT reduce the result mod p.
      72             :    It can be used before mul, sqr. */
      73             : FD_25519_INLINE fd_f25519_t *
      74             : fd_f25519_add_nr( fd_f25519_t * r,
      75             :                   fd_f25519_t const * a,
      76   819794197 :                   fd_f25519_t const * b ) {
      77   819794197 :   fiat_25519_add( r->el, a->el, b->el );
      78   819794197 :   return r;
      79   819794197 : }
      80             : 
      81             : /* fd_f25519_sub computes r = a - b, and returns r.
      82             :    Note: this does NOT reduce the result mod p.
      83             :    It can be used before mul, sqr. */
      84             : FD_25519_INLINE fd_f25519_t *
      85             : fd_f25519_sub_nr( fd_f25519_t * r,
      86             :                   fd_f25519_t const * a,
      87   648326468 :                   fd_f25519_t const * b ) {
      88   648326468 :   fiat_25519_sub( r->el, a->el, b->el );
      89   648326468 :   return r;
      90   648326468 : }
      91             : 
      92             : /* fd_f25519_add computes r = -a, and returns r. */
      93             : FD_25519_INLINE fd_f25519_t *
      94             : fd_f25519_neg( fd_f25519_t * r,
      95    78839363 :                fd_f25519_t const * a ) {
      96    78839363 :   fiat_25519_opp( r->el, a->el );
      97    78839363 :   return r;
      98    78839363 : }
      99             : 
     100             : /* fd_f25519_add computes r = a * k, k=121666, and returns r. */
     101             : FD_25519_INLINE fd_f25519_t *
     102             : fd_f25519_mul_121666( fd_f25519_t * r,
     103    33518730 :                       fd_f25519_t const * a ) {
     104    33518730 :   fiat_25519_carry_scmul_121666( r->el, a->el );
     105    33518730 :   return r;
     106    33518730 : }
     107             : 
     108             : /* fd_f25519_frombytes deserializes a 32-byte buffer buf into a
     109             :    fd_f25519_t element r, and returns r.
     110             :    buf is in little endian form, we accept non-canonical elements
     111             :    unlike RFC 8032. */
     112             : FD_25519_INLINE fd_f25519_t *
     113             : fd_f25519_frombytes( fd_f25519_t * r,
     114     3524052 :                      uchar const   buf[ 32 ] ) {
     115     3524052 :   fiat_25519_from_bytes( r->el, buf );
     116     3524052 :   return r;
     117     3524052 : }
     118             : 
     119             : /* fd_f25519_tobytes serializes a fd_f25519_t element a into
     120             :    a 32-byte buffer out, and returns out.
     121             :    out is in little endian form, according to RFC 8032
     122             :    (we don't output non-canonical elements). */
     123             : FD_25519_INLINE uchar *
     124             : fd_f25519_tobytes( uchar               out[ 32 ],
     125     8508934 :                    fd_f25519_t const * a ) {
     126     8508934 :   fiat_25519_to_bytes( out, a->el );
     127     8508934 :   return out;
     128     8508934 : }
     129             : 
     130             : /* fd_f25519_if sets r = a0 if cond, else r = a1, equivalent to:
     131             :    r = cond ? a0 : a1.
     132             :    Note: this is constant time. */
     133             : FD_25519_INLINE fd_f25519_t *
     134             : fd_f25519_if( fd_f25519_t *       r,
     135             :               int const           cond, /* 0, 1 */
     136             :               fd_f25519_t const * a0,
     137  1973943634 :               fd_f25519_t const * a1 ) {
     138  1973943634 :   fiat_25519_selectznz( r->el, (uchar)cond, a1->el, a0->el );
     139  1973943634 :   return r;
     140  1973943634 : }
     141             : 
     142             : /* fd_f25519_swap_if swaps r1, r2 if cond, else leave them as is.
     143             :    Note: this is constant time. */
     144             : FD_25519_INLINE void
     145             : fd_f25519_swap_if( fd_f25519_t * restrict r1,
     146             :                    fd_f25519_t * restrict r2,
     147    67300352 :                    int const              cond /* 0, 1 */ ) {
     148             : 
     149             : #if USE_FIAT_32
     150             :   uint m  = (uint)-!!cond;
     151             :   uint h0 = m & (r1->el[0] ^ r2->el[0]);
     152             :   uint h1 = m & (r1->el[1] ^ r2->el[1]);
     153             :   uint h2 = m & (r1->el[2] ^ r2->el[2]);
     154             :   uint h3 = m & (r1->el[3] ^ r2->el[3]);
     155             :   uint h4 = m & (r1->el[4] ^ r2->el[4]);
     156             :   uint h5 = m & (r1->el[5] ^ r2->el[5]);
     157             :   uint h6 = m & (r1->el[6] ^ r2->el[6]);
     158             :   uint h7 = m & (r1->el[7] ^ r2->el[7]);
     159             :   uint h8 = m & (r1->el[8] ^ r2->el[8]);
     160             :   uint h9 = m & (r1->el[9] ^ r2->el[9]);
     161             : 
     162             : #else
     163    67300352 :   ulong m  = (ulong)-!!cond;
     164    67300352 :   ulong h0 = m & (r1->el[0] ^ r2->el[0]);
     165    67300352 :   ulong h1 = m & (r1->el[1] ^ r2->el[1]);
     166    67300352 :   ulong h2 = m & (r1->el[2] ^ r2->el[2]);
     167    67300352 :   ulong h3 = m & (r1->el[3] ^ r2->el[3]);
     168    67300352 :   ulong h4 = m & (r1->el[4] ^ r2->el[4]);
     169    67300352 : #endif
     170             : 
     171    67300352 :   r1->el[0] ^= h0;
     172    67300352 :   r1->el[1] ^= h1;
     173    67300352 :   r1->el[2] ^= h2;
     174    67300352 :   r1->el[3] ^= h3;
     175    67300352 :   r1->el[4] ^= h4;
     176             : 
     177    67300352 :   r2->el[0] ^= h0;
     178    67300352 :   r2->el[1] ^= h1;
     179    67300352 :   r2->el[2] ^= h2;
     180    67300352 :   r2->el[3] ^= h3;
     181    67300352 :   r2->el[4] ^= h4;
     182             : 
     183             : #if USE_FIAT_32
     184             :   r1->el[5] ^= h5;
     185             :   r1->el[6] ^= h6;
     186             :   r1->el[7] ^= h7;
     187             :   r1->el[8] ^= h8;
     188             :   r1->el[9] ^= h9;
     189             : 
     190             :   r2->el[5] ^= h5;
     191             :   r2->el[6] ^= h6;
     192             :   r2->el[7] ^= h7;
     193             :   r2->el[8] ^= h8;
     194             :   r2->el[9] ^= h9;
     195             : #endif
     196    67300352 : }
     197             : 
     198             : /* fd_f25519_set copies r = a, and returns r. */
     199             : FD_25519_INLINE fd_f25519_t *
     200             : fd_f25519_set( fd_f25519_t * r,
     201   329860498 :                fd_f25519_t const * a ) {
     202   329860498 :   r->el[0] = a->el[0];
     203   329860498 :   r->el[1] = a->el[1];
     204   329860498 :   r->el[2] = a->el[2];
     205   329860498 :   r->el[3] = a->el[3];
     206   329860498 :   r->el[4] = a->el[4];
     207             : #if USE_FIAT_32
     208             :   r->el[5] = a->el[5];
     209             :   r->el[6] = a->el[6];
     210             :   r->el[7] = a->el[7];
     211             :   r->el[8] = a->el[8];
     212             :   r->el[9] = a->el[9];
     213             : #endif
     214   329860498 :   return r;
     215   329860498 : }
     216             : 
     217             : /* fd_f25519_is_zero returns 1 if a == 0, 0 otherwise. */
     218             : FD_25519_INLINE int
     219    10332206 : fd_f25519_is_zero( fd_f25519_t const * a ) {
     220             :   // fiat_25519_tight_field_element x;
     221             :   // fiat_25519_carry( x, a->el );
     222             : #if USE_FIAT_32
     223             :   uint const * x = a->el;
     224             :   if(( x[0] == 0
     225             :     && x[1] == 0
     226             :     && x[2] == 0
     227             :     && x[3] == 0
     228             :     && x[4] == 0
     229             :     && x[5] == 0
     230             :     && x[6] == 0
     231             :     && x[7] == 0
     232             :     && x[8] == 0
     233             :     && x[9] == 0
     234             :   ) || (
     235             :        x[0] == 0x3ffffed
     236             :     && x[1] == 0x1ffffff
     237             :     && x[2] == 0x3ffffff
     238             :     && x[3] == 0x1ffffff
     239             :     && x[4] == 0x3ffffff
     240             :     && x[5] == 0x1ffffff
     241             :     && x[6] == 0x3ffffff
     242             :     && x[7] == 0x1ffffff
     243             :     && x[8] == 0x3ffffff
     244             :     && x[9] == 0x1ffffff
     245             :   )) {
     246             :     return 1;
     247             :   }
     248             : #else
     249    10332206 :   ulong const * x = a->el;
     250    10332206 :   if(( x[0] == 0
     251    10332206 :     && x[1] == 0
     252    10332206 :     && x[2] == 0
     253    10332206 :     && x[3] == 0
     254    10332206 :     && x[4] == 0
     255    10332206 :   ) || (
     256    10331876 :        x[0] == 0x7ffffffffffed
     257    10331876 :     && x[1] == 0x7ffffffffffff
     258    10331876 :     && x[2] == 0x7ffffffffffff
     259    10331876 :     && x[3] == 0x7ffffffffffff
     260    10331876 :     && x[4] == 0x7ffffffffffff
     261    10331876 :   )) {
     262     2084396 :     return 1;
     263     2084396 :   }
     264     8247810 : #endif
     265     8247810 :   return 0;
     266    10332206 : }
     267             : 
     268             : /*
     269             :  * Vectorized
     270             :  */
     271             : 
     272             : /* fd_f25519_muln computes r_i = a_i * b_i */
     273             : FD_25519_INLINE void
     274             : fd_f25519_mul2( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     275    68237060 :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2 ) {
     276    68237060 :   fd_f25519_mul( r1, a1, b1 );
     277    68237060 :   fd_f25519_mul( r2, a2, b2 );
     278    68237060 : }
     279             : 
     280             : FD_25519_INLINE void
     281             : fd_f25519_mul3( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     282             :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
     283   227731145 :                 fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3 ) {
     284   227731145 :   fd_f25519_mul( r1, a1, b1 );
     285   227731145 :   fd_f25519_mul( r2, a2, b2 );
     286   227731145 :   fd_f25519_mul( r3, a3, b3 );
     287   227731145 : }
     288             : 
     289             : FD_25519_INLINE void
     290             : fd_f25519_mul4( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     291             :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
     292             :                 fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3,
     293   155642481 :                 fd_f25519_t * r4, fd_f25519_t const * a4, fd_f25519_t const * b4 ) {
     294   155642481 :   fd_f25519_mul( r1, a1, b1 );
     295   155642481 :   fd_f25519_mul( r2, a2, b2 );
     296   155642481 :   fd_f25519_mul( r3, a3, b3 );
     297   155642481 :   fd_f25519_mul( r4, a4, b4 );
     298   155642481 : }
     299             : 
     300             : /* fd_f25519_sqrn computes r_i = a_i^2 */
     301             : FD_25519_INLINE void
     302             : fd_f25519_sqr2( fd_f25519_t * r1, fd_f25519_t const * a1,
     303    33518730 :                 fd_f25519_t * r2, fd_f25519_t const * a2 ) {
     304    33518730 :   fd_f25519_sqr( r1, a1 );
     305    33518730 :   fd_f25519_sqr( r2, a2 );
     306    33518730 : }
     307             : 
     308             : FD_25519_INLINE void
     309             : fd_f25519_sqr3( fd_f25519_t * r1, fd_f25519_t const * a1,
     310             :                 fd_f25519_t * r2, fd_f25519_t const * a2,
     311           0 :                 fd_f25519_t * r3, fd_f25519_t const * a3 ) {
     312           0 :   fd_f25519_sqr( r1, a1 );
     313           0 :   fd_f25519_sqr( r2, a2 );
     314           0 :   fd_f25519_sqr( r3, a3 );
     315           0 : }
     316             : 
     317             : FD_25519_INLINE void
     318             : fd_f25519_sqr4( fd_f25519_t * r1, fd_f25519_t const * a1,
     319             :                 fd_f25519_t * r2, fd_f25519_t const * a2,
     320             :                 fd_f25519_t * r3, fd_f25519_t const * a3,
     321   139913838 :                 fd_f25519_t * r4, fd_f25519_t const * a4 ) {
     322   139913838 :   fd_f25519_sqr( r1, a1 );
     323   139913838 :   fd_f25519_sqr( r2, a2 );
     324   139913838 :   fd_f25519_sqr( r3, a3 );
     325   139913838 :   fd_f25519_sqr( r4, a4 );
     326   139913838 : }
     327             : 
     328             : FD_PROTOTYPES_END

Generated by: LCOV version 1.14