@@ -61,18 +61,43 @@ static void secp256k1_ecdh_point_multiply(secp256k1_gej_t *r, const secp256k1_ge
61
61
secp256k1_ge_t tmpa ;
62
62
secp256k1_fe_t Z ;
63
63
64
+ #ifdef USE_ENDOMORPHISM
65
+ secp256k1_ge_t pre_a_lam [ECMULT_TABLE_SIZE (WINDOW_A )];
66
+ int wnaf_1 [256 ];
67
+ int wnaf_lam [256 ];
68
+ int n_words_lam ;
69
+ secp256k1_scalar_t q_1 , q_lam ;
70
+ #else
64
71
int wnaf [256 ];
72
+ #endif
65
73
int n_words ;
66
74
67
75
int i ;
68
76
int is_zero = secp256k1_scalar_is_zero (scalar );
69
77
secp256k1_scalar_t sc = * scalar ;
78
+
79
+ /* build wnaf representation for q. */
80
+ #ifdef USE_ENDOMORPHISM
81
+ /* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */
82
+ secp256k1_scalar_split_lambda (& q_1 , & q_lam , & sc );
83
+ /* the wNAF ladder cannot handle zero, so bump this to one .. we will
84
+ * correct the result after the fact */
85
+ q_1 .d [0 ] += is_zero ;
86
+ q_lam .d [0 ] += is_zero ;
87
+ VERIFY_CHECK (!secp256k1_scalar_is_zero (& q_1 ));
88
+ VERIFY_CHECK (!secp256k1_scalar_is_zero (& q_lam ));
89
+
90
+ n_words = secp256k1_ecdh_wnaf (wnaf_1 , & q_1 , WINDOW_A - 1 );
91
+ n_words_lam = secp256k1_ecdh_wnaf (wnaf_lam , & q_lam , WINDOW_A - 1 );
92
+ VERIFY_CHECK (n_words == n_words_lam );
93
+ #else
70
94
/* the wNAF ladder cannot handle zero, so bump this to one .. we will
71
95
* correct the result after the fact */
72
96
sc .d [0 ] += is_zero ;
97
+ VERIFY_CHECK (!secp256k1_scalar_is_zero (& sc ));
73
98
74
- /* build wnaf representation for q. */
75
99
n_words = secp256k1_ecdh_wnaf (wnaf , & sc , WINDOW_A - 1 );
100
+ #endif
76
101
77
102
/* Calculate odd multiples of a.
78
103
* All multiples are brought to the same Z 'denominator', which is stored
@@ -82,6 +107,11 @@ static void secp256k1_ecdh_point_multiply(secp256k1_gej_t *r, const secp256k1_ge
82
107
*/
83
108
secp256k1_gej_set_ge (r , a );
84
109
secp256k1_ecmult_odd_multiples_table_globalz_windowa (pre_a , & Z , r );
110
+ #ifdef USE_ENDOMORPHISM
111
+ for (i = 0 ; i < ECMULT_TABLE_SIZE (WINDOW_A ); i ++ ) {
112
+ secp256k1_ge_mul_lambda (& pre_a_lam [i ], & pre_a [i ]);
113
+ }
114
+ #endif
85
115
secp256k1_gej_set_infinity (r );
86
116
87
117
for (i = n_words ; i >= 0 ; i -- ) {
@@ -90,10 +120,22 @@ static void secp256k1_ecdh_point_multiply(secp256k1_gej_t *r, const secp256k1_ge
90
120
for (j = 0 ; j < WINDOW_A - 1 ; ++ j ) {
91
121
secp256k1_gej_double_var (r , r , NULL );
92
122
}
123
+ #ifdef USE_ENDOMORPHISM
124
+ n = wnaf_1 [i ];
125
+ ECMULT_TABLE_GET_GE (& tmpa , pre_a , n , WINDOW_A );
126
+ VERIFY_CHECK (n != 0 );
127
+ secp256k1_gej_add_ge (r , r , & tmpa );
128
+
129
+ n = wnaf_lam [i ];
130
+ ECMULT_TABLE_GET_GE (& tmpa , pre_a_lam , n , WINDOW_A );
131
+ VERIFY_CHECK (n != 0 );
132
+ secp256k1_gej_add_ge (r , r , & tmpa );
133
+ #else
93
134
n = wnaf [i ];
94
135
VERIFY_CHECK (n != 0 );
95
136
ECMULT_TABLE_GET_GE (& tmpa , pre_a , n , WINDOW_A );
96
137
secp256k1_gej_add_ge (r , r , & tmpa );
138
+ #endif
97
139
}
98
140
99
141
if (!r -> infinity ) {
0 commit comments