LCOV - code coverage report
Current view: top level - ballet/ed25519/avx512 - fd_f25519.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 58 93 62.4 %
Date: 2024-11-13 11:58:15 Functions: 73 540 13.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             : #include "fd_r43x6.h"
       7             : 
       8             : #define FD_F25519_ALIGN 64
       9             : 
      10             : /* A fd_f25519_t stores a curve25519 field element in 5 ulong, aligned to 64 bytes */
      11             : struct fd_f25519 {
      12             :   fd_r43x6_t el __attribute__((aligned(FD_F25519_ALIGN)));
      13             : };
      14             : typedef struct fd_f25519 fd_f25519_t;
      15             : 
      16             : #include "../table/fd_f25519_table_avx512.c"
      17             : 
      18             : FD_PROTOTYPES_BEGIN
      19             : 
      20             : /*
      21             :  * Implementation of inline functions
      22             :  */
      23             : 
      24             : /* fd_f25519_mul computes r = a * b, and returns r. */
      25             : FD_25519_INLINE fd_f25519_t *
      26             : fd_f25519_mul( fd_f25519_t * r,
      27             :                fd_f25519_t const * a,
      28    16317134 :                fd_f25519_t const * b ) {
      29    16317134 :   FD_R43X6_MUL1_INL( r->el, a->el, b->el );
      30    16317134 :   return r;
      31    16317134 : }
      32             : 
      33             : /* fd_f25519_sqr computes r = a^2, and returns r. */
      34             : FD_25519_INLINE fd_f25519_t *
      35             : fd_f25519_sqr( fd_f25519_t * r,
      36   254011927 :                fd_f25519_t const * a ) {
      37   254011927 :   FD_R43X6_SQR1_INL( r->el, a->el );
      38   254011927 :   return r;
      39   254011927 : }
      40             : 
      41             : /* fd_f25519_add computes r = a + b, and returns r. */
      42             : FD_25519_INLINE fd_f25519_t *
      43             : fd_f25519_add( fd_f25519_t * r,
      44             :                fd_f25519_t const * a,
      45     1323139 :                fd_f25519_t const * b ) {
      46     1323139 :   (r->el) = fd_r43x6_add( (a->el), (b->el) );
      47     1323139 :   return r;
      48     1323139 : }
      49             : 
      50             : /* fd_f25519_add computes r = a - b, and returns r. */
      51             : FD_25519_INLINE fd_f25519_t *
      52             : fd_f25519_sub( fd_f25519_t * r,
      53             :                fd_f25519_t const * a,
      54     3253477 :                fd_f25519_t const * b ) {
      55     3253477 :   (r->el) = fd_r43x6_fold_signed( fd_r43x6_sub_fast( (a->el), (b->el) ) );
      56     3253477 :   return r;
      57     3253477 : }
      58             : 
      59             : /* fd_f25519_add computes r = a + b, and returns r.
      60             :    Note: this does NOT reduce the result mod p.
      61             :    It can be used before mul, sqr. */
      62             : FD_25519_INLINE fd_f25519_t *
      63             : fd_f25519_add_nr( fd_f25519_t * r,
      64             :                   fd_f25519_t const * a,
      65           2 :                   fd_f25519_t const * b ) {
      66           2 :   (r->el) = fd_r43x6_add_fast( (a->el), (b->el) );
      67           2 :   return r;
      68           2 : }
      69             : 
      70             : /* fd_f25519_sub 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_sub_nr( fd_f25519_t * r,
      75             :                   fd_f25519_t const * a,
      76           0 :                   fd_f25519_t const * b ) {
      77           0 :   (r->el) = fd_r43x6_sub_fast( (a->el), (b->el) );
      78           0 :   return r;
      79           0 : }
      80             : 
      81             : /* fd_f25519_add computes r = -a, and returns r. */
      82             : FD_25519_INLINE fd_f25519_t *
      83             : fd_f25519_neg( fd_f25519_t * r,
      84     1001743 :                fd_f25519_t const * a ) {
      85     1001743 :   (r->el) = fd_r43x6_neg_fast( (a->el) );
      86     1001743 :   return r;
      87     1001743 : }
      88             : 
      89             : /* fd_f25519_add computes r = a * k, k=121666, and returns r. */
      90             : FD_25519_INLINE fd_f25519_t *
      91             : fd_f25519_mul_121666( fd_f25519_t * r,
      92           0 :                       FD_FN_UNUSED fd_f25519_t const * a ) {
      93           0 :   (r->el) = fd_r43x6_fold_unsigned( fd_r43x6_scale_fast( 121666L, (a->el) ) );
      94           0 :   return r;
      95           0 : }
      96             : 
      97             : /* fd_f25519_frombytes deserializes a 32-byte buffer buf into a
      98             :    fd_f25519_t element r, and returns r.
      99             :    buf is in little endian form, according to RFC 8032. */
     100             : FD_25519_INLINE fd_f25519_t *
     101             : fd_f25519_frombytes( fd_f25519_t * r,
     102     1198831 :                      uchar const   buf[ 32 ] ) {
     103     1198831 :   ulong y0 = fd_ulong_load_8_fast( buf );                         /* Bits   0- 63 */
     104     1198831 :   ulong y1 = fd_ulong_load_8_fast( buf+8 );                       /* Bits  64-127 */
     105     1198831 :   ulong y2 = fd_ulong_load_8_fast( buf+16 );                      /* Bits 128-191 */
     106     1198831 :   ulong y3 = fd_ulong_load_8_fast( buf+24 ) & 0x7fffffffffffffff; /* Bits 192-254 */
     107     1198831 :   r->el = fd_r43x6_unpack( wv( y0, y1, y2, y3 ) );
     108     1198831 :   return r;
     109     1198831 : }
     110             : 
     111             : /* fd_f25519_tobytes serializes a fd_f25519_t element a into
     112             :    a 32-byte buffer out, and returns out.
     113             :    out is in little endian form, according to RFC 8032. */
     114             : FD_25519_INLINE uchar *
     115             : fd_f25519_tobytes( uchar               out[ 32 ],
     116     3210413 :                    fd_f25519_t const * a ) {
     117     3210413 :   wv_stu( out, fd_r43x6_pack( fd_r43x6_mod( a->el ) ) );
     118     3210413 :   return out;
     119     3210413 : }
     120             : 
     121             : /* fd_f25519_if sets r = a0 if cond, else r = a1, equivalent to:
     122             :    r = cond ? a0 : a1.
     123             :    Note: this is constant time. */
     124             : FD_25519_INLINE fd_f25519_t *
     125             : fd_f25519_if( fd_f25519_t *       r,
     126             :               int const           cond, /* 0, 1 */
     127             :               fd_f25519_t const * a0,
     128     1259126 :               fd_f25519_t const * a1 ) {
     129     1259126 :   r->el = fd_r43x6_if( -!!cond, a0->el, a1->el );
     130     1259126 :   return r;
     131     1259126 : }
     132             : 
     133             : /* fd_f25519_swap_if swaps r1, r2 if cond, else leave them as is.
     134             :    Note: this is constant time. */
     135             : FD_25519_INLINE void
     136             : fd_f25519_swap_if( fd_f25519_t * restrict r1,
     137             :                    fd_f25519_t * restrict r2,
     138           0 :                    int const              cond /* 0, 1 */ ) {
     139           0 :   wwl_t zero = wwl_zero();
     140           0 :   wwl_t m = wwl_xor(r1->el, r2->el);
     141           0 :   m  = wwl_if( -!!cond, m, zero );
     142           0 :   r1->el = wwl_xor( r1->el, m );
     143           0 :   r2->el = wwl_xor( r2->el, m );
     144           0 : }
     145             : 
     146             : /* fd_f25519_set copies r = a, and returns r. */
     147             : FD_25519_INLINE fd_f25519_t *
     148             : fd_f25519_set( fd_f25519_t * r,
     149     1132630 :                fd_f25519_t const * a ) {
     150     1132630 :   r->el = a->el;
     151     1132630 :   return r;
     152     1132630 : }
     153             : 
     154             : /* fd_f25519_is_zero returns 1 if a == 0, 0 otherwise. */
     155             : FD_25519_INLINE int
     156     2957796 : fd_f25519_is_zero( fd_f25519_t const * a ) {
     157     2957796 :   return ( ( wwl_eq( a->el, fd_r43x6_zero() ) & 0xFF ) == 0xFF )
     158     2957796 :       || ( ( wwl_eq( a->el, fd_r43x6_p() )    & 0xFF ) == 0xFF );
     159     2957796 : }
     160             : 
     161             : /*
     162             :  * Vectorized
     163             :  */
     164             : 
     165             : /* fd_f25519_muln computes r_i = a_i * b_i */
     166             : FD_25519_INLINE void
     167             : fd_f25519_mul2( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     168      616669 :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2 ) {
     169      616669 :   FD_R43X6_MUL2_INL( r1->el, a1->el, b1->el,
     170      616669 :                      r2->el, a2->el, b2->el );
     171      616669 : }
     172             : 
     173             : FD_25519_INLINE void
     174             : fd_f25519_mul3( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     175             :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
     176           0 :                 fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3 ) {
     177           0 :   FD_R43X6_MUL3_INL( r1->el, a1->el, b1->el,
     178           0 :                      r2->el, a2->el, b2->el,
     179           0 :                      r3->el, a3->el, b3->el );
     180           0 : }
     181             : 
     182             : FD_25519_INLINE void
     183             : fd_f25519_mul4( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     184             :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
     185             :                 fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3,
     186       30002 :                 fd_f25519_t * r4, fd_f25519_t const * a4, fd_f25519_t const * b4 ) {
     187       30002 :   FD_R43X6_MUL4_INL( r1->el, a1->el, b1->el,
     188       30002 :                      r2->el, a2->el, b2->el,
     189       30002 :                      r3->el, a3->el, b3->el,
     190       30002 :                      r4->el, a4->el, b4->el );
     191       30002 : }
     192             : 
     193             : /* fd_f25519_sqrn computes r_i = a_i^2 */
     194             : FD_25519_INLINE void
     195             : fd_f25519_sqr2( fd_f25519_t * r1, fd_f25519_t const * a1,
     196           0 :                 fd_f25519_t * r2, fd_f25519_t const * a2 ) {
     197           0 :   FD_R43X6_SQR2_INL( r1->el, a1->el,
     198           0 :                      r2->el, a2->el );
     199           0 : }
     200             : 
     201             : FD_25519_INLINE void
     202             : fd_f25519_sqr3( fd_f25519_t * r1, fd_f25519_t const * a1,
     203             :                 fd_f25519_t * r2, fd_f25519_t const * a2,
     204           0 :                 fd_f25519_t * r3, fd_f25519_t const * a3 ) {
     205           0 :   FD_R43X6_SQR3_INL( r1->el, a1->el,
     206           0 :                      r2->el, a2->el,
     207           0 :                      r3->el, a3->el );
     208           0 : }
     209             : 
     210             : FD_25519_INLINE void
     211             : fd_f25519_sqr4( fd_f25519_t * r1, fd_f25519_t const * a1,
     212             :                 fd_f25519_t * r2, fd_f25519_t const * a2,
     213             :                 fd_f25519_t * r3, fd_f25519_t const * a3,
     214           0 :                 fd_f25519_t * r4, fd_f25519_t const * a4 ) {
     215           0 :   FD_R43X6_SQR4_INL( r1->el, a1->el,
     216           0 :                      r2->el, a2->el,
     217           0 :                      r3->el, a3->el,
     218           0 :                      r4->el, a4->el );
     219           0 : }
     220             : 
     221             : FD_PROTOTYPES_END

Generated by: LCOV version 1.14