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 : }
|