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: 2024-11-13 11:58:15 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  1571732784 :                fd_f25519_t const * b ) {
      38  1571732784 :   fiat_25519_carry_mul( r->el, a->el, b->el );
      39  1571732784 :   return r;
      40  1571732784 : }
      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  1494659838 :                fd_f25519_t const * a ) {
      46  1494659838 :   fiat_25519_carry_square( r->el, a->el );
      47  1494659838 :   return r;
      48  1494659838 : }
      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   377858447 :                fd_f25519_t const * b ) {
      55   377858447 :   fiat_25519_add( r->el, a->el, b->el );
      56   377858447 :   fiat_25519_carry( r->el, r->el );
      57   377858447 :   return r;
      58   377858447 : }
      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   152805701 :                fd_f25519_t const * b ) {
      65   152805701 :   fiat_25519_sub( r->el, a->el, b->el );
      66   152805701 :   fiat_25519_carry( r->el, r->el );
      67   152805701 :   return r;
      68   152805701 : }
      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   833631317 :                   fd_f25519_t const * b ) {
      77   833631317 :   fiat_25519_add( r->el, a->el, b->el );
      78   833631317 :   return r;
      79   833631317 : }
      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   660122386 :                   fd_f25519_t const * b ) {
      88   660122386 :   fiat_25519_sub( r->el, a->el, b->el );
      89   660122386 :   return r;
      90   660122386 : }
      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    81034392 :                fd_f25519_t const * a ) {
      96    81034392 :   fiat_25519_opp( r->el, a->el );
      97    81034392 :   return r;
      98    81034392 : }
      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    33479970 :                       fd_f25519_t const * a ) {
     104    33479970 :   fiat_25519_carry_scmul_121666( r->el, a->el );
     105    33479970 :   return r;
     106    33479970 : }
     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     3534468 :                      uchar const   buf[ 32 ] ) {
     114     3534468 :   fiat_25519_from_bytes( r->el, buf );
     115     3534468 :   return r;
     116     3534468 : }
     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     8605476 :                    fd_f25519_t const * a ) {
     124     8605476 :   fiat_25519_to_bytes( out, a->el );
     125     8605476 :   return out;
     126     8605476 : }
     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  2032250932 :               fd_f25519_t const * a1 ) {
     136  2032250932 :   fiat_25519_selectznz( r->el, (uchar)cond, a1->el, a0->el );
     137  2032250932 :   return r;
     138  2032250932 : }
     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    67222528 :                    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    67222528 :   ulong m  = (ulong)-!!cond;
     162    67222528 :   ulong h0 = m & (r1->el[0] ^ r2->el[0]);
     163    67222528 :   ulong h1 = m & (r1->el[1] ^ r2->el[1]);
     164    67222528 :   ulong h2 = m & (r1->el[2] ^ r2->el[2]);
     165    67222528 :   ulong h3 = m & (r1->el[3] ^ r2->el[3]);
     166    67222528 :   ulong h4 = m & (r1->el[4] ^ r2->el[4]);
     167    67222528 : #endif
     168             : 
     169    67222528 :   r1->el[0] ^= h0;
     170    67222528 :   r1->el[1] ^= h1;
     171    67222528 :   r1->el[2] ^= h2;
     172    67222528 :   r1->el[3] ^= h3;
     173    67222528 :   r1->el[4] ^= h4;
     174             : 
     175    67222528 :   r2->el[0] ^= h0;
     176    67222528 :   r2->el[1] ^= h1;
     177    67222528 :   r2->el[2] ^= h2;
     178    67222528 :   r2->el[3] ^= h3;
     179    67222528 :   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    67222528 : }
     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   339433654 :                fd_f25519_t const * a ) {
     200   339433654 :   r->el[0] = a->el[0];
     201   339433654 :   r->el[1] = a->el[1];
     202   339433654 :   r->el[2] = a->el[2];
     203   339433654 :   r->el[3] = a->el[3];
     204   339433654 :   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   339433654 :   return r;
     213   339433654 : }
     214             : 
     215             : /* fd_f25519_is_zero returns 1 if a == 0, 0 otherwise. */
     216             : FD_25519_INLINE int
     217    10391264 : 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    10391264 :   ulong const * x = a->el;
     248    10391264 :   if(( x[0] == 0
     249    10391264 :     && x[1] == 0
     250    10391264 :     && x[2] == 0
     251    10391264 :     && x[3] == 0
     252    10391264 :     && x[4] == 0
     253    10391264 :   ) || (
     254    10390724 :        x[0] == 0x7ffffffffffed
     255    10390724 :     && x[1] == 0x7ffffffffffff
     256    10390724 :     && x[2] == 0x7ffffffffffff
     257    10390724 :     && x[3] == 0x7ffffffffffff
     258    10390724 :     && x[4] == 0x7ffffffffffff
     259    10390724 :   )) {
     260     2100754 :     return 1;
     261     2100754 :   }
     262     8290510 : #endif
     263     8290510 :   return 0;
     264    10391264 : }
     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    68193278 :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2 ) {
     274    68193278 :   fd_f25519_mul( r1, a1, b1 );
     275    68193278 :   fd_f25519_mul( r2, a2, b2 );
     276    68193278 : }
     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   230846156 :                 fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3 ) {
     282   230846156 :   fd_f25519_mul( r1, a1, b1 );
     283   230846156 :   fd_f25519_mul( r2, a2, b2 );
     284   230846156 :   fd_f25519_mul( r3, a3, b3 );
     285   230846156 : }
     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   160601261 :                 fd_f25519_t * r4, fd_f25519_t const * a4, fd_f25519_t const * b4 ) {
     292   160601261 :   fd_f25519_mul( r1, a1, b1 );
     293   160601261 :   fd_f25519_mul( r2, a2, b2 );
     294   160601261 :   fd_f25519_mul( r3, a3, b3 );
     295   160601261 :   fd_f25519_mul( r4, a4, b4 );
     296   160601261 : }
     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    33479970 :                 fd_f25519_t * r2, fd_f25519_t const * a2 ) {
     302    33479970 :   fd_f25519_sqr( r1, a1 );
     303    33479970 :   fd_f25519_sqr( r2, a2 );
     304    33479970 : }
     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   140703691 :                 fd_f25519_t * r4, fd_f25519_t const * a4 ) {
     320   140703691 :   fd_f25519_sqr( r1, a1 );
     321   140703691 :   fd_f25519_sqr( r2, a2 );
     322   140703691 :   fd_f25519_sqr( r3, a3 );
     323   140703691 :   fd_f25519_sqr( r4, a4 );
     324   140703691 : }
     325             : 
     326             : FD_PROTOTYPES_END

Generated by: LCOV version 1.14