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-01-08 12:08:44 Functions: 100 540 18.5 %

          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  1571740777 :                fd_f25519_t const * b ) {
      38  1571740777 :   fiat_25519_carry_mul( r->el, a->el, b->el );
      39  1571740777 :   return r;
      40  1571740777 : }
      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  1494687692 :                fd_f25519_t const * a ) {
      46  1494687692 :   fiat_25519_carry_square( r->el, a->el );
      47  1494687692 :   return r;
      48  1494687692 : }
      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   377859298 :                fd_f25519_t const * b ) {
      55   377859298 :   fiat_25519_add( r->el, a->el, b->el );
      56   377859298 :   fiat_25519_carry( r->el, r->el );
      57   377859298 :   return r;
      58   377859298 : }
      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   152806031 :                fd_f25519_t const * b ) {
      65   152806031 :   fiat_25519_sub( r->el, a->el, b->el );
      66   152806031 :   fiat_25519_carry( r->el, r->el );
      67   152806031 :   return r;
      68   152806031 : }
      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   833637350 :                   fd_f25519_t const * b ) {
      77   833637350 :   fiat_25519_add( r->el, a->el, b->el );
      78   833637350 :   return r;
      79   833637350 : }
      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   660129324 :                   fd_f25519_t const * b ) {
      88   660129324 :   fiat_25519_sub( r->el, a->el, b->el );
      89   660129324 :   return r;
      90   660129324 : }
      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    81034974 :                fd_f25519_t const * a ) {
      96    81034974 :   fiat_25519_opp( r->el, a->el );
      97    81034974 :   return r;
      98    81034974 : }
      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    33482010 :                       fd_f25519_t const * a ) {
     104    33482010 :   fiat_25519_carry_scmul_121666( r->el, a->el );
     105    33482010 :   return r;
     106    33482010 : }
     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, according to RFC 8032. */
     111             : FD_25519_INLINE fd_f25519_t *
     112             : fd_f25519_frombytes( fd_f25519_t * r,
     113     3534538 :                      uchar const   buf[ 32 ] ) {
     114     3534538 :   fiat_25519_from_bytes( r->el, buf );
     115     3534538 :   return r;
     116     3534538 : }
     117             : 
     118             : /* fd_f25519_tobytes serializes a fd_f25519_t element a into
     119             :    a 32-byte buffer out, and returns out.
     120             :    out is in little endian form, according to RFC 8032. */
     121             : FD_25519_INLINE uchar *
     122             : fd_f25519_tobytes( uchar               out[ 32 ],
     123     8605644 :                    fd_f25519_t const * a ) {
     124     8605644 :   fiat_25519_to_bytes( out, a->el );
     125     8605644 :   return out;
     126     8605644 : }
     127             : 
     128             : /* fd_f25519_if sets r = a0 if cond, else r = a1, equivalent to:
     129             :    r = cond ? a0 : a1.
     130             :    Note: this is constant time. */
     131             : FD_25519_INLINE fd_f25519_t *
     132             : fd_f25519_if( fd_f25519_t *       r,
     133             :               int const           cond, /* 0, 1 */
     134             :               fd_f25519_t const * a0,
     135  2032261408 :               fd_f25519_t const * a1 ) {
     136  2032261408 :   fiat_25519_selectznz( r->el, (uchar)cond, a1->el, a0->el );
     137  2032261408 :   return r;
     138  2032261408 : }
     139             : 
     140             : /* fd_f25519_swap_if swaps r1, r2 if cond, else leave them as is.
     141             :    Note: this is constant time. */
     142             : FD_25519_INLINE void
     143             : fd_f25519_swap_if( fd_f25519_t * restrict r1,
     144             :                    fd_f25519_t * restrict r2,
     145    67226624 :                    int const              cond /* 0, 1 */ ) {
     146             : 
     147             : #if USE_FIAT_32
     148             :   uint m  = (uint)-!!cond;
     149             :   uint h0 = m & (r1->el[0] ^ r2->el[0]);
     150             :   uint h1 = m & (r1->el[1] ^ r2->el[1]);
     151             :   uint h2 = m & (r1->el[2] ^ r2->el[2]);
     152             :   uint h3 = m & (r1->el[3] ^ r2->el[3]);
     153             :   uint h4 = m & (r1->el[4] ^ r2->el[4]);
     154             :   uint h5 = m & (r1->el[5] ^ r2->el[5]);
     155             :   uint h6 = m & (r1->el[6] ^ r2->el[6]);
     156             :   uint h7 = m & (r1->el[7] ^ r2->el[7]);
     157             :   uint h8 = m & (r1->el[8] ^ r2->el[8]);
     158             :   uint h9 = m & (r1->el[9] ^ r2->el[9]);
     159             : 
     160             : #else
     161    67226624 :   ulong m  = (ulong)-!!cond;
     162    67226624 :   ulong h0 = m & (r1->el[0] ^ r2->el[0]);
     163    67226624 :   ulong h1 = m & (r1->el[1] ^ r2->el[1]);
     164    67226624 :   ulong h2 = m & (r1->el[2] ^ r2->el[2]);
     165    67226624 :   ulong h3 = m & (r1->el[3] ^ r2->el[3]);
     166    67226624 :   ulong h4 = m & (r1->el[4] ^ r2->el[4]);
     167    67226624 : #endif
     168             : 
     169    67226624 :   r1->el[0] ^= h0;
     170    67226624 :   r1->el[1] ^= h1;
     171    67226624 :   r1->el[2] ^= h2;
     172    67226624 :   r1->el[3] ^= h3;
     173    67226624 :   r1->el[4] ^= h4;
     174             : 
     175    67226624 :   r2->el[0] ^= h0;
     176    67226624 :   r2->el[1] ^= h1;
     177    67226624 :   r2->el[2] ^= h2;
     178    67226624 :   r2->el[3] ^= h3;
     179    67226624 :   r2->el[4] ^= h4;
     180             : 
     181             : #if USE_FIAT_32
     182             :   r1->el[5] ^= h5;
     183             :   r1->el[6] ^= h6;
     184             :   r1->el[7] ^= h7;
     185             :   r1->el[8] ^= h8;
     186             :   r1->el[9] ^= h9;
     187             : 
     188             :   r2->el[5] ^= h5;
     189             :   r2->el[6] ^= h6;
     190             :   r2->el[7] ^= h7;
     191             :   r2->el[8] ^= h8;
     192             :   r2->el[9] ^= h9;
     193             : #endif
     194    67226624 : }
     195             : 
     196             : /* fd_f25519_set copies r = a, and returns r. */
     197             : FD_25519_INLINE fd_f25519_t *
     198             : fd_f25519_set( fd_f25519_t * r,
     199   339435378 :                fd_f25519_t const * a ) {
     200   339435378 :   r->el[0] = a->el[0];
     201   339435378 :   r->el[1] = a->el[1];
     202   339435378 :   r->el[2] = a->el[2];
     203   339435378 :   r->el[3] = a->el[3];
     204   339435378 :   r->el[4] = a->el[4];
     205             : #if USE_FIAT_32
     206             :   r->el[5] = a->el[5];
     207             :   r->el[6] = a->el[6];
     208             :   r->el[7] = a->el[7];
     209             :   r->el[8] = a->el[8];
     210             :   r->el[9] = a->el[9];
     211             : #endif
     212   339435378 :   return r;
     213   339435378 : }
     214             : 
     215             : /* fd_f25519_is_zero returns 1 if a == 0, 0 otherwise. */
     216             : FD_25519_INLINE int
     217    10391450 : fd_f25519_is_zero( fd_f25519_t const * a ) {
     218             :   // fiat_25519_tight_field_element x;
     219             :   // fiat_25519_carry( x, a->el );
     220             : #if USE_FIAT_32
     221             :   uint const * x = a->el;
     222             :   if(( x[0] == 0
     223             :     && x[1] == 0
     224             :     && x[2] == 0
     225             :     && x[3] == 0
     226             :     && x[4] == 0
     227             :     && x[5] == 0
     228             :     && x[6] == 0
     229             :     && x[7] == 0
     230             :     && x[8] == 0
     231             :     && x[9] == 0
     232             :   ) || (
     233             :        x[0] == 0x3ffffed
     234             :     && x[1] == 0x1ffffff
     235             :     && x[2] == 0x3ffffff
     236             :     && x[3] == 0x1ffffff
     237             :     && x[4] == 0x3ffffff
     238             :     && x[5] == 0x1ffffff
     239             :     && x[6] == 0x3ffffff
     240             :     && x[7] == 0x1ffffff
     241             :     && x[8] == 0x3ffffff
     242             :     && x[9] == 0x1ffffff
     243             :   )) {
     244             :     return 1;
     245             :   }
     246             : #else
     247    10391450 :   ulong const * x = a->el;
     248    10391450 :   if(( x[0] == 0
     249    10391450 :     && x[1] == 0
     250    10391450 :     && x[2] == 0
     251    10391450 :     && x[3] == 0
     252    10391450 :     && x[4] == 0
     253    10391450 :   ) || (
     254    10390910 :        x[0] == 0x7ffffffffffed
     255    10390910 :     && x[1] == 0x7ffffffffffff
     256    10390910 :     && x[2] == 0x7ffffffffffff
     257    10390910 :     && x[3] == 0x7ffffffffffff
     258    10390910 :     && x[4] == 0x7ffffffffffff
     259    10390910 :   )) {
     260     2100840 :     return 1;
     261     2100840 :   }
     262     8290610 : #endif
     263     8290610 :   return 0;
     264    10391450 : }
     265             : 
     266             : /*
     267             :  * Vectorized
     268             :  */
     269             : 
     270             : /* fd_f25519_muln computes r_i = a_i * b_i */
     271             : FD_25519_INLINE void
     272             : fd_f25519_mul2( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     273    68197364 :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2 ) {
     274    68197364 :   fd_f25519_mul( r1, a1, b1 );
     275    68197364 :   fd_f25519_mul( r2, a2, b2 );
     276    68197364 : }
     277             : 
     278             : FD_25519_INLINE void
     279             : fd_f25519_mul3( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     280             :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
     281   230846857 :                 fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3 ) {
     282   230846857 :   fd_f25519_mul( r1, a1, b1 );
     283   230846857 :   fd_f25519_mul( r2, a2, b2 );
     284   230846857 :   fd_f25519_mul( r3, a3, b3 );
     285   230846857 : }
     286             : 
     287             : FD_25519_INLINE void
     288             : fd_f25519_mul4( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     289             :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
     290             :                 fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3,
     291   160599862 :                 fd_f25519_t * r4, fd_f25519_t const * a4, fd_f25519_t const * b4 ) {
     292   160599862 :   fd_f25519_mul( r1, a1, b1 );
     293   160599862 :   fd_f25519_mul( r2, a2, b2 );
     294   160599862 :   fd_f25519_mul( r3, a3, b3 );
     295   160599862 :   fd_f25519_mul( r4, a4, b4 );
     296   160599862 : }
     297             : 
     298             : /* fd_f25519_sqrn computes r_i = a_i^2 */
     299             : FD_25519_INLINE void
     300             : fd_f25519_sqr2( fd_f25519_t * r1, fd_f25519_t const * a1,
     301    33482010 :                 fd_f25519_t * r2, fd_f25519_t const * a2 ) {
     302    33482010 :   fd_f25519_sqr( r1, a1 );
     303    33482010 :   fd_f25519_sqr( r2, a2 );
     304    33482010 : }
     305             : 
     306             : FD_25519_INLINE void
     307             : fd_f25519_sqr3( fd_f25519_t * r1, fd_f25519_t const * a1,
     308             :                 fd_f25519_t * r2, fd_f25519_t const * a2,
     309           0 :                 fd_f25519_t * r3, fd_f25519_t const * a3 ) {
     310           0 :   fd_f25519_sqr( r1, a1 );
     311           0 :   fd_f25519_sqr( r2, a2 );
     312           0 :   fd_f25519_sqr( r3, a3 );
     313           0 : }
     314             : 
     315             : FD_25519_INLINE void
     316             : fd_f25519_sqr4( fd_f25519_t * r1, fd_f25519_t const * a1,
     317             :                 fd_f25519_t * r2, fd_f25519_t const * a2,
     318             :                 fd_f25519_t * r3, fd_f25519_t const * a3,
     319   140703781 :                 fd_f25519_t * r4, fd_f25519_t const * a4 ) {
     320   140703781 :   fd_f25519_sqr( r1, a1 );
     321   140703781 :   fd_f25519_sqr( r2, a2 );
     322   140703781 :   fd_f25519_sqr( r3, a3 );
     323   140703781 :   fd_f25519_sqr( r4, a4 );
     324   140703781 : }
     325             : 
     326             : FD_PROTOTYPES_END

Generated by: LCOV version 1.14