LCOV - code coverage report
Current view: top level - ballet/ed25519/avx512 - fd_curve25519_secure.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 59 59 100.0 %
Date: 2024-11-13 11:58:15 Functions: 4 4 100.0 %

          Line data    Source code
       1             : #include "../fd_curve25519.h"
       2             : #include "./fd_r43x6_ge.h"
       3             : 
       4             : /* All the functions in this file are considered "secure", specifically:
       5             : 
       6             :    - Constant time in the input, i.e. the input can be a secret
       7             :    - Small and auditable code base, incl. simple types
       8             :    - No local variables = no need to clear them before exit
       9             :    - Clear registers via FD_FN_SENSITIVE
      10             :  */
      11             : 
      12             : /* FD_R43X6_GE_ADD_TABLE_ALT is similar to FD_R43X6_GE_ADD_TABLE,
      13             :    with 3 minor differences:
      14             :    1. order of arguments: P3, P2 points in extended Edwards coordinates,
      15             :       T1 precomputed table point
      16             :    2. T1 = (Y-X : Y+X : Z==1 : kT)
      17             :    3. temp vars as input, so we can safely clear them in the caller
      18             : */
      19    60609624 : #define FD_R43X6_GE_ADD_TABLE_ALT( P3, P2, T1, _ta, _tb ) do {                                                                  \
      20    60609624 :     FD_R43X6_QUAD_MOV          ( _ta, T1 );                     /* _ta = (Y1-X1,Y1+X1,Z1  ,T1*2d), s61|s61|s61|s61 */ \
      21    60609624 :     FD_R43X6_QUAD_PERMUTE      ( _tb, 1,0,2,3, P2 );            /* _tb = (Y2,   X2,   Z2,  T2   ), s61|s61|s61|s61 */ \
      22    60609624 :     FD_R43X6_QUAD_LANE_SUB_FAST( _tb, _tb, 1,0,0,0, _tb, P2 );  /* _tb = (Y2-X2,X2,   Z2,  T2   ), s62|s61|s61|s61 */ \
      23    60609624 :     FD_R43X6_QUAD_LANE_ADD_FAST( _tb, _tb, 0,1,1,0, _tb, P2 );  /* _tb = (Y2-X2,Y2+X2,Z2*2,T2   ), s62|s62|s61|s61 */ \
      24    60609624 :     FD_R43X6_QUAD_MUL_FAST     ( _ta, _ta, _tb );               /* _ta = (A,    B,    D,   C    ), u62|u62|u62|u62 */ \
      25    60609624 :     FD_R43X6_QUAD_FOLD_UNSIGNED( _ta, _ta );                    /* P3  = (A,    B,    D,   C    ), u44|u44|u44|u44 */ \
      26    60609624 :     FD_R43X6_QUAD_PERMUTE      ( _tb, 1,0,3,2, _ta );           /* _tb = (B,    A,    C,   D    ), u62|u62|u62|u62 */ \
      27    60609624 :     FD_R43X6_QUAD_LANE_SUB_FAST( _tb, _tb, 1,0,0,1, _tb, _ta ); /* _tb = (E,    A,    C,   F    ), s62|u62|u62|s62 */ \
      28    60609624 :     FD_R43X6_QUAD_LANE_ADD_FAST( _tb, _tb, 0,1,1,0, _tb, _ta ); /* _tb = (E,    H,    G,   F    ), s62|u63|u63|s62 */ \
      29    60609624 :     FD_R43X6_QUAD_PERMUTE      ( _ta, 0,2,2,0, _tb );           /* _ta = (E,    G,    G,   E    ), u44|u44|u44|u44 */ \
      30    60609624 :     FD_R43X6_QUAD_PERMUTE      ( _tb, 3,1,3,1, _tb );           /* _tb = (F,    H,    F,   H    ), u44|u44|u44|u44 */ \
      31    60609624 :     FD_R43X6_QUAD_MUL_FAST     ( _ta, _ta, _tb );               /* _ta = (X3,   Y3,   Z3,  T3   ), u62|u62|u62|u62 */ \
      32    60609624 :     FD_R43X6_QUAD_FOLD_UNSIGNED( P3, _ta );                     /* P3  = (X3,   Y3,   Z3,  T3   ), u44|u44|u44|u44 */ \
      33    60609624 :   } while(0)
      34             : 
      35             : /* fd_ed25519_point_add_secure computes r = a + b.
      36             : 
      37             :    It's equivalent to fd_ed25519_point_add_with_opts( r, a, b, 1, 1, 0 ),
      38             :    i.e. it assumes that b is from a precomputation table.
      39             : 
      40             :    This implementation has no temporary variables and clears registers on return.
      41             :    The intent is to avoid that an attacker can retrieve information about b,
      42             :    that was chosen in const time based on a secret value. */
      43             : FD_25519_INLINE void FD_FN_SENSITIVE
      44             : fd_ed25519_point_add_secure( fd_ed25519_point_t *       restrict r,
      45             :                              fd_ed25519_point_t const * restrict a,
      46             :                              fd_ed25519_point_t const * restrict b,
      47             :                              fd_ed25519_point_t *       restrict tmp0,
      48    37545536 :                              fd_ed25519_point_t *       restrict tmp1 ) {
      49             : 
      50    37545536 :   FD_R43X6_GE_ADD_TABLE_ALT( r->P, a->P, b->P, tmp0->P, tmp1->P );
      51             : 
      52    37545536 : }
      53             : 
      54             : /* FD_R43X6_GE_DBL_ALT is similar to FD_R43X6_GE_DBL,
      55             :    with 2 minor differences:
      56             :    1. removed _BB, by reordering instructions
      57             :    2. temp vars as input, so we can safely clear them in the caller
      58             : */
      59     2346596 : #define FD_R43X6_GE_DBL_ALT( P3, P1, _ta, _tb ) do {                                                                              \
      60     2346596 :     FD_R43X6_QUAD_PERMUTE      ( _ta, 1,1,2,0, P1 );            /* _ta = (Y1,       Y1,Z1,  X1), u44/u44/u44/u44 */ \
      61     2346596 :     FD_R43X6_QUAD_LANE_ADD_FAST( _ta, _ta, 1,0,0,0, _ta, P1 );  /* _ta = (X1+Y1,    Y1,Z1,  X1), u45/u44/u44/u44 */ \
      62     2346596 :     FD_R43X6_QUAD_SQR_FAST     ( _ta, _ta );                    /* _ta = ((X1+Y1)^2,B, Z1^2,A ), u61/u61/u61/u61 */ \
      63     2346596 :     FD_R43X6_QUAD_FOLD_UNSIGNED( _ta, _ta );                    /* _ta = ((X1+Y1)^2,B, Z1^2,A ), u44/u44/u44/u44 */ \
      64     2346596 :     FD_R43X6_QUAD_LANE_ADD_FAST( _ta, _ta, 0,0,1,0, _ta, _ta ); /* _ta = ((X1+Y1)^2,B, C,   A ), u44/u44/u45/u44 */ \
      65     2346596 :     FD_R43X6_QUAD_PERMUTE      ( _tb, 3,3,3,3, _ta );           /* _tb = (A,        A, A,   A ), u44/u44/u44/u44 */ \
      66     2346596 :     FD_R43X6_QUAD_LANE_ADD_FAST( _tb, _tb, 0,0,1,0, _tb, _ta ); /* _tb = (A,        A, A+C, A ), u44/u44/u45/u44 */ \
      67     2346596 :     FD_R43X6_QUAD_LANE_SUB_FAST( _tb, _tb, 1,0,0,0, _tb, _ta ); /* _tb = (A-(sum)^2,A, A+C, A ), u45/u44/u45/u44 */ \
      68     2346596 :     FD_R43X6_QUAD_PERMUTE      ( _ta, 1,1,1,1, _ta );           /* _ta = (B,        B, B,   B ), u44/u44/u44/u44 */ \
      69     2346596 :     FD_R43X6_QUAD_LANE_ADD_FAST( _tb, _tb, 1,0,0,1, _tb, _ta ); /* _tb = (E,        A, A+C, H ), u46/u44/u45/u45 */ \
      70     2346596 :     FD_R43X6_QUAD_LANE_SUB_FAST( _tb, _tb, 0,1,1,0, _tb, _ta ); /* _tb = (E,        G, F,   H ), u46/u45/u46/u45 */ \
      71     2346596 :     FD_R43X6_QUAD_PERMUTE      ( _ta, 0,1,1,0, _tb );           /* _tb = (E,        G, G,   E ), u46/u45/u45/u46 */ \
      72     2346596 :     FD_R43X6_QUAD_PERMUTE      ( _tb, 2,3,2,3, _tb );           /* _tb = (F,        H, F,   H ), u46/u45/u46/u45 */ \
      73     2346596 :     FD_R43X6_QUAD_MUL_FAST     ( _ta, _ta, _tb );               /* _ta = (X3,       Y3,Z3,  T3), u62/u62/u62/u62 */ \
      74     2346596 :     FD_R43X6_QUAD_FOLD_UNSIGNED( P3, _ta );                     /* P3  = (X3,       Y3,Z3,  T3), u44/u44/u44/u44 */ \
      75     2346596 :   } while(0)
      76             : 
      77             : /* fd_ed25519_point_dbln_secure computes r = 2^n a.
      78             : 
      79             :    It's equivalent to fd_ed25519_point_dbln( r, a, n ).
      80             : 
      81             :    This implementation has no temporary variables and clears registers on return.
      82             :    The intent is to avoid that an attacker can retrieve information about a,
      83             :    that's a partial aggregation of secretly chosen points. */
      84             : FD_25519_INLINE void FD_FN_SENSITIVE
      85             : fd_ed25519_point_dbln_secure( fd_ed25519_point_t *       r,
      86             :                               fd_ed25519_point_t const * a,
      87             :                               int                        n,
      88             :                               fd_ed25519_point_t *       restrict tmp0,
      89      586649 :                               fd_ed25519_point_t *       restrict tmp1 ) {
      90      586649 :   FD_R43X6_GE_DBL_ALT( r->P, a->P, tmp0->P, tmp1->P );
      91     2346596 :   for( uchar i=1; i<n; i++ ) {
      92     1759947 :     FD_R43X6_GE_DBL_ALT( r->P, r->P, tmp0->P, tmp1->P );
      93     1759947 :   }
      94      586649 : }
      95             : 
      96             : /* fd_ed25519_point_if sets r = a0 if secret_cond, else r = a1.
      97             :    Equivalent to r = secret_cond ? a0 : a1.
      98             :    Note: this is const time, as the underlying wwl_if is const time. */
      99             : FD_25519_INLINE void FD_FN_SENSITIVE
     100             : fd_ed25519_point_if( fd_ed25519_point_t * restrict r,
     101             :                      uchar const                   secret_cond, /* 0, 1 */
     102             :                      fd_ed25519_point_t const *    a0,
     103   300364288 :                      fd_ed25519_point_t const *    a1 ) {
     104   300364288 :   r->P03 = wwl_if( -secret_cond, a0->P03, a1->P03 );
     105   300364288 :   r->P14 = wwl_if( -secret_cond, a0->P14, a1->P14 );
     106   300364288 :   r->P25 = wwl_if( -secret_cond, a0->P25, a1->P25 );
     107   300364288 : }
     108             : 
     109             : /* fd_ed25519_point_neg_if sets r = -r if secret_cond, else r = r.
     110             :    Equivalent to r = secret_cond ? -r : r.
     111             :    Note: this is const time, as the underlying wwl_if is const time. */
     112             : FD_25519_INLINE void FD_FN_SENSITIVE
     113             : fd_ed25519_point_neg_if( fd_ed25519_point_t * FD_RESTRICT r,
     114             :                          fd_ed25519_point_t * const       a,
     115    37545536 :                          uchar const                      secret_cond /* 0, 1 */ ) {
     116    37545536 :   FD_R43X6_QUAD_DECL( _p );
     117    37545536 :   _p03 = wwl( 8796093022189L, 8796093022189L, 8796093022189L, 8796093022189L, 8796093022207L, 8796093022207L, 8796093022207L, 8796093022207L );
     118    37545536 :   _p14 = wwl( 8796093022207L, 8796093022207L, 8796093022207L, 8796093022207L, 8796093022207L, 8796093022207L, 8796093022207L, 8796093022207L );
     119    37545536 :   _p25 = wwl( 8796093022207L, 8796093022207L, 8796093022207L, 8796093022207L, 1099511627775L, 1099511627775L, 1099511627775L, 1099511627775L );
     120    37545536 :   r->P03 = wwv_sub_if( 136, _p03, a->P03, a->P03 );
     121    37545536 :   r->P14 = wwv_sub_if( 136, _p14, a->P14, a->P14 );
     122    37545536 :   r->P25 = wwv_sub_if( 136, _p25, a->P25, a->P25 );
     123    37545536 :   FD_R43X6_QUAD_PERMUTE( r->P, 1,0,2,3, r->P );
     124    37545536 :   r->P03 = wwl_if( -secret_cond, r->P03, a->P03 );
     125    37545536 :   r->P14 = wwl_if( -secret_cond, r->P14, a->P14 );
     126    37545536 :   r->P25 = wwl_if( -secret_cond, r->P25, a->P25 );
     127    37545536 : }

Generated by: LCOV version 1.14