LCOV - code coverage report
Current view: top level - ballet/ed25519/avx512 - fd_f25519.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 58 92 63.0 %
Date: 2025-12-14 05:09:06 Functions: 51 500 10.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             : #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    16065715 :                fd_f25519_t const * b ) {
      29    16065715 :   FD_R43X6_MUL1_INL( r->el, a->el, b->el );
      30    16065715 :   return r;
      31    16065715 : }
      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   249115780 :                fd_f25519_t const * a ) {
      37   249115780 :   FD_R43X6_SQR1_INL( r->el, a->el );
      38   249115780 :   return r;
      39   249115780 : }
      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     1320680 :                fd_f25519_t const * b ) {
      46     1320680 :   (r->el) = fd_r43x6_add( (a->el), (b->el) );
      47     1320680 :   return r;
      48     1320680 : }
      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     3236920 :                fd_f25519_t const * b ) {
      55     3236920 :   (r->el) = fd_r43x6_fold_signed( fd_r43x6_sub_fast( (a->el), (b->el) ) );
      56     3236920 :   return r;
      57     3236920 : }
      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      992526 :                fd_f25519_t const * a ) {
      85      992526 :   (r->el) = fd_r43x6_neg( (a->el) );
      86      992526 :   return r;
      87      992526 : }
      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, we accept non-canonical elements
     100             :    unlike RFC 8032. */
     101             : FD_25519_INLINE fd_f25519_t *
     102             : fd_f25519_frombytes( fd_f25519_t * r,
     103     1196431 :                      uchar const   buf[ 32 ] ) {
     104     1196431 :   ulong y0 = fd_ulong_load_8_fast( buf );                         /* Bits   0- 63 */
     105     1196431 :   ulong y1 = fd_ulong_load_8_fast( buf+8 );                       /* Bits  64-127 */
     106     1196431 :   ulong y2 = fd_ulong_load_8_fast( buf+16 );                      /* Bits 128-191 */
     107     1196431 :   ulong y3 = fd_ulong_load_8_fast( buf+24 ) & 0x7fffffffffffffff; /* Bits 192-254 */
     108     1196431 :   r->el = fd_r43x6_unpack( wv( y0, y1, y2, y3 ) );
     109     1196431 :   return r;
     110     1196431 : }
     111             : 
     112             : /* fd_f25519_tobytes serializes a fd_f25519_t element a into
     113             :    a 32-byte buffer out, and returns out.
     114             :    out is in little endian form, according to RFC 8032
     115             :    (we don't output non-canonical elements). */
     116             : FD_25519_INLINE uchar *
     117             : fd_f25519_tobytes( uchar               out[ 32 ],
     118     3167844 :                    fd_f25519_t const * a ) {
     119     3167844 :   wv_stu( out, fd_r43x6_pack( fd_r43x6_mod( a->el ) ) );
     120     3167844 :   return out;
     121     3167844 : }
     122             : 
     123             : /* fd_f25519_if sets r = a0 if cond, else r = a1, equivalent to:
     124             :    r = cond ? a0 : a1.
     125             :    Note: this is constant time. */
     126             : FD_25519_INLINE fd_f25519_t *
     127             : fd_f25519_if( fd_f25519_t *       r,
     128             :               int const           cond, /* 0, 1 */
     129             :               fd_f25519_t const * a0,
     130     1252079 :               fd_f25519_t const * a1 ) {
     131     1252079 :   r->el = fd_r43x6_if( -!!cond, a0->el, a1->el );
     132     1252079 :   return r;
     133     1252079 : }
     134             : 
     135             : /* fd_f25519_swap_if swaps r1, r2 if cond, else leave them as is.
     136             :    Note: this is constant time. */
     137             : FD_25519_INLINE void
     138             : fd_f25519_swap_if( fd_f25519_t * restrict r1,
     139             :                    fd_f25519_t * restrict r2,
     140           0 :                    int const              cond /* 0, 1 */ ) {
     141           0 :   wwl_t zero = wwl_zero();
     142           0 :   wwl_t m = wwl_xor(r1->el, r2->el);
     143           0 :   m  = wwl_if( -!!cond, m, zero );
     144           0 :   r1->el = wwl_xor( r1->el, m );
     145           0 :   r2->el = wwl_xor( r2->el, m );
     146           0 : }
     147             : 
     148             : /* fd_f25519_set copies r = a, and returns r. */
     149             : FD_25519_INLINE fd_f25519_t *
     150             : fd_f25519_set( fd_f25519_t * r,
     151     1130536 :                fd_f25519_t const * a ) {
     152     1130536 :   r->el = a->el;
     153     1130536 :   return r;
     154     1130536 : }
     155             : 
     156             : /* fd_f25519_is_zero returns 1 if a == 0, 0 otherwise. */
     157             : FD_25519_INLINE int
     158     2939413 : fd_f25519_is_zero( fd_f25519_t const * a ) {
     159     2939413 :   return ( ( wwl_eq( a->el, fd_r43x6_zero() ) & 0xFF ) == 0xFF )
     160     2939413 :       || ( ( wwl_eq( a->el, fd_r43x6_p() )    & 0xFF ) == 0xFF );
     161     2939413 : }
     162             : 
     163             : /*
     164             :  * Vectorized
     165             :  */
     166             : 
     167             : /* fd_f25519_muln computes r_i = a_i * b_i */
     168             : FD_25519_INLINE void
     169             : fd_f25519_mul2( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     170      599802 :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2 ) {
     171      599802 :   FD_R43X6_MUL2_INL( r1->el, a1->el, b1->el,
     172      599802 :                      r2->el, a2->el, b2->el );
     173      599802 : }
     174             : 
     175             : FD_25519_INLINE void
     176             : fd_f25519_mul3( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     177             :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
     178           0 :                 fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3 ) {
     179           0 :   FD_R43X6_MUL3_INL( r1->el, a1->el, b1->el,
     180           0 :                      r2->el, a2->el, b2->el,
     181           0 :                      r3->el, a3->el, b3->el );
     182           0 : }
     183             : 
     184             : FD_25519_INLINE void
     185             : fd_f25519_mul4( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
     186             :                 fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
     187             :                 fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3,
     188       30002 :                 fd_f25519_t * r4, fd_f25519_t const * a4, fd_f25519_t const * b4 ) {
     189       30002 :   FD_R43X6_MUL4_INL( r1->el, a1->el, b1->el,
     190       30002 :                      r2->el, a2->el, b2->el,
     191       30002 :                      r3->el, a3->el, b3->el,
     192       30002 :                      r4->el, a4->el, b4->el );
     193       30002 : }
     194             : 
     195             : /* fd_f25519_sqrn computes r_i = a_i^2 */
     196             : FD_25519_INLINE void
     197             : fd_f25519_sqr2( fd_f25519_t * r1, fd_f25519_t const * a1,
     198           0 :                 fd_f25519_t * r2, fd_f25519_t const * a2 ) {
     199           0 :   FD_R43X6_SQR2_INL( r1->el, a1->el,
     200           0 :                      r2->el, a2->el );
     201           0 : }
     202             : 
     203             : FD_25519_INLINE void
     204             : fd_f25519_sqr3( fd_f25519_t * r1, fd_f25519_t const * a1,
     205             :                 fd_f25519_t * r2, fd_f25519_t const * a2,
     206           0 :                 fd_f25519_t * r3, fd_f25519_t const * a3 ) {
     207           0 :   FD_R43X6_SQR3_INL( r1->el, a1->el,
     208           0 :                      r2->el, a2->el,
     209           0 :                      r3->el, a3->el );
     210           0 : }
     211             : 
     212             : FD_25519_INLINE void
     213             : fd_f25519_sqr4( fd_f25519_t * r1, fd_f25519_t const * a1,
     214             :                 fd_f25519_t * r2, fd_f25519_t const * a2,
     215             :                 fd_f25519_t * r3, fd_f25519_t const * a3,
     216           0 :                 fd_f25519_t * r4, fd_f25519_t const * a4 ) {
     217             :   FD_R43X6_SQR4_INL( r1->el, a1->el,
     218           0 :                      r2->el, a2->el,
     219           0 :                      r3->el, a3->el,
     220           0 :                      r4->el, a4->el );
     221           0 : }
     222             : 
     223             : FD_PROTOTYPES_END

Generated by: LCOV version 1.14