@@ -63,69 +63,127 @@ void static secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen) {
6363}
6464
6565void static secp256k1_fe_sqrt (secp256k1_fe_t * r , const secp256k1_fe_t * a ) {
66- // calculate a^p, with p={15,780,1022,1023}
67- secp256k1_fe_t a2 ; secp256k1_fe_sqr (& a2 , a );
68- secp256k1_fe_t a3 ; secp256k1_fe_mul (& a3 , & a2 , a );
69- secp256k1_fe_t a6 ; secp256k1_fe_sqr (& a6 , & a3 );
70- secp256k1_fe_t a12 ; secp256k1_fe_sqr (& a12 , & a6 );
71- secp256k1_fe_t a15 ; secp256k1_fe_mul (& a15 , & a12 , & a3 );
72- secp256k1_fe_t a30 ; secp256k1_fe_sqr (& a30 , & a15 );
73- secp256k1_fe_t a60 ; secp256k1_fe_sqr (& a60 , & a30 );
74- secp256k1_fe_t a120 ; secp256k1_fe_sqr (& a120 , & a60 );
75- secp256k1_fe_t a240 ; secp256k1_fe_sqr (& a240 , & a120 );
76- secp256k1_fe_t a255 ; secp256k1_fe_mul (& a255 , & a240 , & a15 );
77- secp256k1_fe_t a510 ; secp256k1_fe_sqr (& a510 , & a255 );
78- secp256k1_fe_t a750 ; secp256k1_fe_mul (& a750 , & a510 , & a240 );
79- secp256k1_fe_t a780 ; secp256k1_fe_mul (& a780 , & a750 , & a30 );
80- secp256k1_fe_t a1020 ; secp256k1_fe_sqr (& a1020 , & a510 );
81- secp256k1_fe_t a1022 ; secp256k1_fe_mul (& a1022 , & a1020 , & a2 );
82- secp256k1_fe_t a1023 ; secp256k1_fe_mul (& a1023 , & a1022 , a );
83- secp256k1_fe_t x = a15 ;
84- for (int i = 0 ; i < 21 ; i ++ ) {
85- for (int j = 0 ; j < 10 ; j ++ ) secp256k1_fe_sqr (& x , & x );
86- secp256k1_fe_mul (& x , & x , & a1023 );
87- }
88- for (int j = 0 ; j < 10 ; j ++ ) secp256k1_fe_sqr (& x , & x );
89- secp256k1_fe_mul (& x , & x , & a1022 );
90- for (int i = 0 ; i < 2 ; i ++ ) {
91- for (int j = 0 ; j < 10 ; j ++ ) secp256k1_fe_sqr (& x , & x );
92- secp256k1_fe_mul (& x , & x , & a1023 );
93- }
94- for (int j = 0 ; j < 10 ; j ++ ) secp256k1_fe_sqr (& x , & x );
95- secp256k1_fe_mul (r , & x , & a780 );
66+
67+ // The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in
68+ // { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block:
69+ // 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223]
70+
71+ secp256k1_fe_t x2 ;
72+ secp256k1_fe_sqr (& x2 , a );
73+ secp256k1_fe_mul (& x2 , & x2 , a );
74+
75+ secp256k1_fe_t x3 ;
76+ secp256k1_fe_sqr (& x3 , & x2 );
77+ secp256k1_fe_mul (& x3 , & x3 , a );
78+
79+ secp256k1_fe_t x6 = x3 ;
80+ for (int j = 0 ; j < 3 ; j ++ ) secp256k1_fe_sqr (& x6 , & x6 );
81+ secp256k1_fe_mul (& x6 , & x6 , & x3 );
82+
83+ secp256k1_fe_t x9 = x6 ;
84+ for (int j = 0 ; j < 3 ; j ++ ) secp256k1_fe_sqr (& x9 , & x9 );
85+ secp256k1_fe_mul (& x9 , & x9 , & x3 );
86+
87+ secp256k1_fe_t x11 = x9 ;
88+ for (int j = 0 ; j < 2 ; j ++ ) secp256k1_fe_sqr (& x11 , & x11 );
89+ secp256k1_fe_mul (& x11 , & x11 , & x2 );
90+
91+ secp256k1_fe_t x22 = x11 ;
92+ for (int j = 0 ; j < 11 ; j ++ ) secp256k1_fe_sqr (& x22 , & x22 );
93+ secp256k1_fe_mul (& x22 , & x22 , & x11 );
94+
95+ secp256k1_fe_t x44 = x22 ;
96+ for (int j = 0 ; j < 22 ; j ++ ) secp256k1_fe_sqr (& x44 , & x44 );
97+ secp256k1_fe_mul (& x44 , & x44 , & x22 );
98+
99+ secp256k1_fe_t x88 = x44 ;
100+ for (int j = 0 ; j < 44 ; j ++ ) secp256k1_fe_sqr (& x88 , & x88 );
101+ secp256k1_fe_mul (& x88 , & x88 , & x44 );
102+
103+ secp256k1_fe_t x176 = x88 ;
104+ for (int j = 0 ; j < 88 ; j ++ ) secp256k1_fe_sqr (& x176 , & x176 );
105+ secp256k1_fe_mul (& x176 , & x176 , & x88 );
106+
107+ secp256k1_fe_t x220 = x176 ;
108+ for (int j = 0 ; j < 44 ; j ++ ) secp256k1_fe_sqr (& x220 , & x220 );
109+ secp256k1_fe_mul (& x220 , & x220 , & x44 );
110+
111+ secp256k1_fe_t x223 = x220 ;
112+ for (int j = 0 ; j < 3 ; j ++ ) secp256k1_fe_sqr (& x223 , & x223 );
113+ secp256k1_fe_mul (& x223 , & x223 , & x3 );
114+
115+ // The final result is then assembled using a sliding window over the blocks.
116+
117+ secp256k1_fe_t t1 = x223 ;
118+ for (int j = 0 ; j < 23 ; j ++ ) secp256k1_fe_sqr (& t1 , & t1 );
119+ secp256k1_fe_mul (& t1 , & t1 , & x22 );
120+ for (int j = 0 ; j < 6 ; j ++ ) secp256k1_fe_sqr (& t1 , & t1 );
121+ secp256k1_fe_mul (& t1 , & t1 , & x2 );
122+ secp256k1_fe_sqr (& t1 , & t1 );
123+ secp256k1_fe_sqr (r , & t1 );
96124}
97125
98126void static secp256k1_fe_inv (secp256k1_fe_t * r , const secp256k1_fe_t * a ) {
99- // calculate a^p, with p={45,63,1019,1023}
100- secp256k1_fe_t a2 ; secp256k1_fe_sqr (& a2 , a );
101- secp256k1_fe_t a3 ; secp256k1_fe_mul (& a3 , & a2 , a );
102- secp256k1_fe_t a4 ; secp256k1_fe_sqr (& a4 , & a2 );
103- secp256k1_fe_t a5 ; secp256k1_fe_mul (& a5 , & a4 , a );
104- secp256k1_fe_t a10 ; secp256k1_fe_sqr (& a10 , & a5 );
105- secp256k1_fe_t a11 ; secp256k1_fe_mul (& a11 , & a10 , a );
106- secp256k1_fe_t a21 ; secp256k1_fe_mul (& a21 , & a11 , & a10 );
107- secp256k1_fe_t a42 ; secp256k1_fe_sqr (& a42 , & a21 );
108- secp256k1_fe_t a45 ; secp256k1_fe_mul (& a45 , & a42 , & a3 );
109- secp256k1_fe_t a63 ; secp256k1_fe_mul (& a63 , & a42 , & a21 );
110- secp256k1_fe_t a126 ; secp256k1_fe_sqr (& a126 , & a63 );
111- secp256k1_fe_t a252 ; secp256k1_fe_sqr (& a252 , & a126 );
112- secp256k1_fe_t a504 ; secp256k1_fe_sqr (& a504 , & a252 );
113- secp256k1_fe_t a1008 ; secp256k1_fe_sqr (& a1008 , & a504 );
114- secp256k1_fe_t a1019 ; secp256k1_fe_mul (& a1019 , & a1008 , & a11 );
115- secp256k1_fe_t a1023 ; secp256k1_fe_mul (& a1023 , & a1019 , & a4 );
116- secp256k1_fe_t x = a63 ;
117- for (int i = 0 ; i < 21 ; i ++ ) {
118- for (int j = 0 ; j < 10 ; j ++ ) secp256k1_fe_sqr (& x , & x );
119- secp256k1_fe_mul (& x , & x , & a1023 );
120- }
121- for (int j = 0 ; j < 10 ; j ++ ) secp256k1_fe_sqr (& x , & x );
122- secp256k1_fe_mul (& x , & x , & a1019 );
123- for (int i = 0 ; i < 2 ; i ++ ) {
124- for (int j = 0 ; j < 10 ; j ++ ) secp256k1_fe_sqr (& x , & x );
125- secp256k1_fe_mul (& x , & x , & a1023 );
126- }
127- for (int j = 0 ; j < 10 ; j ++ ) secp256k1_fe_sqr (& x , & x );
128- secp256k1_fe_mul (r , & x , & a45 );
127+
128+ // The binary representation of (p - 2) has 5 blocks of 1s, with lengths in
129+ // { 1, 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block:
130+ // [1], [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223]
131+
132+ secp256k1_fe_t x2 ;
133+ secp256k1_fe_sqr (& x2 , a );
134+ secp256k1_fe_mul (& x2 , & x2 , a );
135+
136+ secp256k1_fe_t x3 ;
137+ secp256k1_fe_sqr (& x3 , & x2 );
138+ secp256k1_fe_mul (& x3 , & x3 , a );
139+
140+ secp256k1_fe_t x6 = x3 ;
141+ for (int j = 0 ; j < 3 ; j ++ ) secp256k1_fe_sqr (& x6 , & x6 );
142+ secp256k1_fe_mul (& x6 , & x6 , & x3 );
143+
144+ secp256k1_fe_t x9 = x6 ;
145+ for (int j = 0 ; j < 3 ; j ++ ) secp256k1_fe_sqr (& x9 , & x9 );
146+ secp256k1_fe_mul (& x9 , & x9 , & x3 );
147+
148+ secp256k1_fe_t x11 = x9 ;
149+ for (int j = 0 ; j < 2 ; j ++ ) secp256k1_fe_sqr (& x11 , & x11 );
150+ secp256k1_fe_mul (& x11 , & x11 , & x2 );
151+
152+ secp256k1_fe_t x22 = x11 ;
153+ for (int j = 0 ; j < 11 ; j ++ ) secp256k1_fe_sqr (& x22 , & x22 );
154+ secp256k1_fe_mul (& x22 , & x22 , & x11 );
155+
156+ secp256k1_fe_t x44 = x22 ;
157+ for (int j = 0 ; j < 22 ; j ++ ) secp256k1_fe_sqr (& x44 , & x44 );
158+ secp256k1_fe_mul (& x44 , & x44 , & x22 );
159+
160+ secp256k1_fe_t x88 = x44 ;
161+ for (int j = 0 ; j < 44 ; j ++ ) secp256k1_fe_sqr (& x88 , & x88 );
162+ secp256k1_fe_mul (& x88 , & x88 , & x44 );
163+
164+ secp256k1_fe_t x176 = x88 ;
165+ for (int j = 0 ; j < 88 ; j ++ ) secp256k1_fe_sqr (& x176 , & x176 );
166+ secp256k1_fe_mul (& x176 , & x176 , & x88 );
167+
168+ secp256k1_fe_t x220 = x176 ;
169+ for (int j = 0 ; j < 44 ; j ++ ) secp256k1_fe_sqr (& x220 , & x220 );
170+ secp256k1_fe_mul (& x220 , & x220 , & x44 );
171+
172+ secp256k1_fe_t x223 = x220 ;
173+ for (int j = 0 ; j < 3 ; j ++ ) secp256k1_fe_sqr (& x223 , & x223 );
174+ secp256k1_fe_mul (& x223 , & x223 , & x3 );
175+
176+ // The final result is then assembled using a sliding window over the blocks.
177+
178+ secp256k1_fe_t t1 = x223 ;
179+ for (int j = 0 ; j < 23 ; j ++ ) secp256k1_fe_sqr (& t1 , & t1 );
180+ secp256k1_fe_mul (& t1 , & t1 , & x22 );
181+ for (int j = 0 ; j < 5 ; j ++ ) secp256k1_fe_sqr (& t1 , & t1 );
182+ secp256k1_fe_mul (& t1 , & t1 , a );
183+ for (int j = 0 ; j < 3 ; j ++ ) secp256k1_fe_sqr (& t1 , & t1 );
184+ secp256k1_fe_mul (& t1 , & t1 , & x2 );
185+ for (int j = 0 ; j < 2 ; j ++ ) secp256k1_fe_sqr (& t1 , & t1 );
186+ secp256k1_fe_mul (r , & t1 , a );
129187}
130188
131189void static secp256k1_fe_inv_var (secp256k1_fe_t * r , const secp256k1_fe_t * a ) {
0 commit comments