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

          Line data    Source code
       1             : #include "../fd_curve25519.h"
       2             : 
       3             : /* All the functions in this file are considered "secure", specifically:
       4             : 
       5             :    - Constant time in the input, i.e. the input can be a secret
       6             :    - Small and auditable code base, incl. simple types
       7             :    - No local variables = no need to clear them before exit
       8             :    - Clear registers via FD_FN_SENSITIVE
       9             :  */
      10             : 
      11             : /* fd_ed25519_point_add_secure computes r = a + b.
      12             : 
      13             :    It's equivalent to fd_ed25519_point_add_with_opts( r, a, b, 1, 1, 0 ),
      14             :    i.e. it assumes that b is from a precomputation table.
      15             : 
      16             :    This implementation has no temporary variables and clears registers on return.
      17             :    The intent is to avoid that an attacker can retrieve information about b,
      18             :    that was chosen in const time based on a secret value. */
      19             : FD_25519_INLINE fd_ed25519_point_t * FD_FN_SENSITIVE
      20             : fd_ed25519_point_add_secure( fd_ed25519_point_t *       restrict r,
      21             :                              fd_ed25519_point_t const * restrict a,
      22             :                              fd_ed25519_point_t const * restrict b,
      23             :                              fd_ed25519_point_t *       restrict tmp0,
      24    75091072 :                              fd_ed25519_point_t *       restrict tmp1 ) {
      25    75091072 :   fd_f25519_t * r1 = tmp0->X;
      26    75091072 :   fd_f25519_t * r2 = tmp0->Y;
      27    75091072 :   fd_f25519_t * r3 = tmp0->Z;
      28    75091072 :   fd_f25519_t * r4 = tmp0->T;
      29    75091072 :   fd_f25519_t * r5 = tmp1->X;
      30    75091072 :   fd_f25519_t * r6 = tmp1->Y;
      31    75091072 :   fd_f25519_t * r7 = tmp1->Z;
      32    75091072 :   fd_f25519_t * r8 = tmp1->T;
      33             : 
      34    75091072 :   fd_f25519_sub_nr( r1, a->Y, a->X );
      35    75091072 :   fd_f25519_add_nr( r3, a->Y, a->X );
      36             : 
      37    75091072 : #if CURVE25519_PRECOMP_XY
      38    75091072 :   fd_f25519_mul3(   r5, r1,   b->X,
      39    75091072 :                     r6, r3,   b->Y,
      40    75091072 :                     r7, a->T, b->T );
      41             : #else
      42             :   fd_f25519_sub_nr( r2, b->Y, b->X );
      43             :   fd_f25519_add_nr( r4, b->Y, b->X );
      44             :   fd_f25519_mul3(   r5, r1,   r2,
      45             :                     r6, r3,   r4,
      46             :                     r7, a->T, b->T );
      47             : #endif
      48    75091072 :   fd_f25519_add(    r8, a->Z, a->Z );
      49             : 
      50    75091072 :   fd_f25519_sub_nr( r1, r6, r5 );
      51    75091072 :   fd_f25519_sub_nr( r2, r8, r7 );
      52    75091072 :   fd_f25519_add_nr( r3, r8, r7 );
      53    75091072 :   fd_f25519_add_nr( r4, r6, r5 );
      54    75091072 :   fd_f25519_mul4( r->X, r1, r2,
      55    75091072 :                   r->Y, r3, r4,
      56    75091072 :                   r->Z, r2, r3,
      57    75091072 :                   r->T, r1, r4 );
      58    75091072 :   return r;
      59    75091072 : }
      60             : 
      61             : /* fd_ed25519_partial_dbl_secure partially computes r = 2 a.
      62             : 
      63             :    It's equivalent to fd_ed25519_partial_dbl( r, a ).
      64             : 
      65             :    This implementation has no temporary variables and clears registers on return.
      66             :    The intent is to avoid that an attacker can retrieve information about a,
      67             :    that's a partial aggregation of secretly chosen points. */
      68             : FD_25519_INLINE void FD_FN_SENSITIVE
      69             : fd_ed25519_partial_dbl_secure( fd_ed25519_point_t * restrict       r,
      70             :                                fd_ed25519_point_t const * restrict a,
      71     4693192 :                                fd_ed25519_point_t * restrict       tmp) {
      72     4693192 :   fd_f25519_t * r1 = tmp->X;
      73     4693192 :   fd_f25519_t * r2 = tmp->Y;
      74     4693192 :   fd_f25519_t * r3 = tmp->Z;
      75     4693192 :   fd_f25519_t * r4 = tmp->T;
      76             : 
      77     4693192 :   fd_f25519_add_nr( r1, a->X, a->Y );
      78             : 
      79     4693192 :   fd_f25519_sqr4( r2, a->X,
      80     4693192 :                   r3, a->Y,
      81     4693192 :                   r4, a->Z,
      82     4693192 :                   r1, r1 );
      83             : 
      84             :   /* important: reduce mod p (these values are used in add/sub) */
      85     4693192 :   fd_f25519_add( r4, r4, r4 );
      86     4693192 :   fd_f25519_add( r->T, r2, r3 );
      87     4693192 :   fd_f25519_sub( r->Z, r2, r3 );
      88             : 
      89     4693192 :   fd_f25519_add_nr( r->Y, r4, r->Z );
      90     4693192 :   fd_f25519_sub_nr( r->X, r->T, r1 );
      91     4693192 : }
      92             : 
      93             : /* fd_ed25519_point_dbln_secure computes r = 2^n a.
      94             : 
      95             :    It's equivalent to fd_ed25519_point_dbln( r, a, n ).
      96             : 
      97             :    This implementation has no temporary variables and clears registers on return.
      98             :    The intent is to avoid that an attacker can retrieve information about a,
      99             :    that's a partial aggregation of secretly chosen points. */
     100             : FD_25519_INLINE void FD_FN_SENSITIVE
     101             : fd_ed25519_point_dbln_secure( fd_ed25519_point_t *          r,
     102             :                               fd_ed25519_point_t const *    a,
     103             :                               int                           n,
     104             :                               fd_ed25519_point_t * restrict t,
     105     1173298 :                               fd_ed25519_point_t * restrict tmp ) {
     106     1173298 :   fd_ed25519_partial_dbl_secure( t, a, tmp );
     107     4693192 :   for( uchar i=1; i<n; i++ ) {
     108             :     // fd_ed25519_point_add_final_mul_projective( r, t );
     109     3519894 :     fd_f25519_mul3( r->X, t->X, t->Y,
     110     3519894 :                     r->Y, t->Z, t->T,
     111     3519894 :                     r->Z, t->Y, t->Z );
     112             : 
     113     3519894 :     fd_ed25519_partial_dbl_secure( t, r, tmp );
     114     3519894 :   }
     115             :   // fd_ed25519_point_add_final_mul( r, t );
     116     1173298 :   fd_f25519_mul4( r->X, t->X, t->Y,
     117     1173298 :                   r->Y, t->Z, t->T,
     118     1173298 :                   r->Z, t->Y, t->Z,
     119     1173298 :                   r->T, t->X, t->T );
     120     1173298 : }
     121             : 
     122             : /* fd_ed25519_point_if sets r = a0 if secret_cond, else r = a1.
     123             :    Equivalent to r = secret_cond ? a0 : a1.
     124             :    Note: this is const time, as the underlying fd_f25519_if is const time. */
     125             : FD_25519_INLINE void FD_FN_SENSITIVE
     126             : fd_ed25519_point_if( fd_ed25519_point_t * restrict r,
     127             :                      uchar                         secret_cond, /* 0, 1 */
     128             :                      fd_ed25519_point_t const *    a0,
     129   600728576 :                      fd_ed25519_point_t const *    a1 ) {
     130   600728576 :   fd_f25519_if( r->X, secret_cond, a0->X, a1->X );
     131   600728576 :   fd_f25519_if( r->Y, secret_cond, a0->Y, a1->Y );
     132   600728576 :   fd_f25519_if( r->T, secret_cond, a0->T, a1->T );
     133   600728576 : }
     134             : 
     135             : /* fd_ed25519_point_neg_if sets r = -r if secret_cond, else r = r.
     136             :    Equivalent to r = secret_cond ? -r : r.
     137             :    Note: this is const time, as the underlying fd_f25519_if is const time. */
     138             : FD_25519_INLINE void FD_FN_SENSITIVE
     139             : fd_ed25519_point_neg_if( fd_ed25519_point_t * FD_RESTRICT r,
     140             :                          fd_ed25519_point_t * const       a,
     141    75091072 :                          uchar const                      secret_cond /* 0, 1 */ ) {
     142    75091072 :   fd_f25519_neg( r->Z, a->T );
     143    75091072 :   fd_f25519_if( r->T, secret_cond, r->Z, a->T );
     144    75091072 : #if CURVE25519_PRECOMP_XY
     145    75091072 :   fd_f25519_if( r->X, secret_cond, a->Y, a->X );
     146    75091072 :   fd_f25519_if( r->Y, secret_cond, a->X, a->Y );
     147             : #else
     148             :   fd_f25519_neg( r->Z, a->X );
     149             :   fd_f25519_if( r->X, secret_cond, r->X, a->Z );
     150             : #endif
     151    75091072 : }

Generated by: LCOV version 1.14