Skip to content

Commit 465159c

Browse files
committed
Further shorten the addition chain for scalar inversion.
Reduce the number of squarings by one and reduce the number of multiplications by three.
1 parent cf12fa1 commit 465159c

File tree

1 file changed

+29
-52
lines changed

1 file changed

+29
-52
lines changed

src/scalar_impl.h

Lines changed: 29 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,19 @@ static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar
6969
/* First compute xN as x ^ (2^N - 1) for some values of N,
7070
* and uM as x ^ M for some values of M. */
7171
secp256k1_scalar x2, x3, x6, x8, x14, x28, x56, x112, x126;
72-
secp256k1_scalar u2, u5;
72+
secp256k1_scalar u2, u5, u9, u11, u13;
7373

7474
secp256k1_scalar_sqr(&u2, x);
7575
secp256k1_scalar_mul(&x2, &u2, x);
7676
secp256k1_scalar_mul(&u5, &u2, &x2);
7777
secp256k1_scalar_mul(&x3, &u5, &u2);
78+
secp256k1_scalar_mul(&u9, &x3, &u2);
79+
secp256k1_scalar_mul(&u11, &u9, &u2);
80+
secp256k1_scalar_mul(&u13, &u11, &u2);
7881

79-
secp256k1_scalar_sqr(&x6, &x3);
80-
for (i = 0; i < 2; i++) {
81-
secp256k1_scalar_sqr(&x6, &x6);
82-
}
83-
secp256k1_scalar_mul(&x6, &x6, &x3);
82+
secp256k1_scalar_sqr(&x6, &u13);
83+
secp256k1_scalar_sqr(&x6, &x6);
84+
secp256k1_scalar_mul(&x6, &x6, &u11);
8485

8586
secp256k1_scalar_sqr(&x8, &x6);
8687
secp256k1_scalar_sqr(&x8, &x8);
@@ -130,18 +131,14 @@ static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar
130131
secp256k1_scalar_sqr(t, t);
131132
}
132133
secp256k1_scalar_mul(t, t, &u5); /* 101 */
133-
for (i = 0; i < 2; i++) { /* 0 */
134+
for (i = 0; i < 5; i++) { /* 0 */
134135
secp256k1_scalar_sqr(t, t);
135136
}
136-
secp256k1_scalar_mul(t, t, x); /* 1 */
137-
for (i = 0; i < 4; i++) { /* 0 */
137+
secp256k1_scalar_mul(t, t, &u11); /* 1011 */
138+
for (i = 0; i < 4; i++) {
138139
secp256k1_scalar_sqr(t, t);
139140
}
140-
secp256k1_scalar_mul(t, t, &x3); /* 111 */
141-
for (i = 0; i < 3; i++) { /* 0 */
142-
secp256k1_scalar_sqr(t, t);
143-
}
144-
secp256k1_scalar_mul(t, t, &x2); /* 11 */
141+
secp256k1_scalar_mul(t, t, &u11); /* 1011 */
145142
for (i = 0; i < 4; i++) { /* 0 */
146143
secp256k1_scalar_sqr(t, t);
147144
}
@@ -150,26 +147,22 @@ static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar
150147
secp256k1_scalar_sqr(t, t);
151148
}
152149
secp256k1_scalar_mul(t, t, &x3); /* 111 */
153-
for (i = 0; i < 4; i++) { /* 00 */
150+
for (i = 0; i < 6; i++) { /* 00 */
154151
secp256k1_scalar_sqr(t, t);
155152
}
156-
secp256k1_scalar_mul(t, t, &x2); /* 11 */
153+
secp256k1_scalar_mul(t, t, &u13); /* 1101 */
157154
for (i = 0; i < 4; i++) { /* 0 */
158155
secp256k1_scalar_sqr(t, t);
159156
}
160157
secp256k1_scalar_mul(t, t, &u5); /* 101 */
161-
for (i = 0; i < 4; i++) { /* 0 */
162-
secp256k1_scalar_sqr(t, t);
163-
}
164-
secp256k1_scalar_mul(t, t, &x3); /* 111 */
165158
for (i = 0; i < 3; i++) {
166159
secp256k1_scalar_sqr(t, t);
167160
}
168-
secp256k1_scalar_mul(t, t, &u5); /* 101 */
169-
for (i = 0; i < 3; i++) { /* 00 */
161+
secp256k1_scalar_mul(t, t, &x3); /* 111 */
162+
for (i = 0; i < 5; i++) { /* 0 */
170163
secp256k1_scalar_sqr(t, t);
171164
}
172-
secp256k1_scalar_mul(t, t, x); /* 1 */
165+
secp256k1_scalar_mul(t, t, &u9); /* 1001 */
173166
for (i = 0; i < 6; i++) { /* 000 */
174167
secp256k1_scalar_sqr(t, t);
175168
}
@@ -186,50 +179,34 @@ static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar
186179
secp256k1_scalar_sqr(t, t);
187180
}
188181
secp256k1_scalar_mul(t, t, &x8); /* 11111111 */
189-
for (i = 0; i < 2; i++) { /* 0 */
190-
secp256k1_scalar_sqr(t, t);
191-
}
192-
secp256k1_scalar_mul(t, t, x); /* 1 */
193-
for (i = 0; i < 3; i++) { /* 00 */
182+
for (i = 0; i < 5; i++) { /* 0 */
194183
secp256k1_scalar_sqr(t, t);
195184
}
196-
secp256k1_scalar_mul(t, t, x); /* 1 */
197-
for (i = 0; i < 3; i++) { /* 00 */
198-
secp256k1_scalar_sqr(t, t);
199-
}
200-
secp256k1_scalar_mul(t, t, x); /* 1 */
201-
for (i = 0; i < 4; i++) { /* 0 */
202-
secp256k1_scalar_sqr(t, t);
203-
}
204-
secp256k1_scalar_mul(t, t, &x3); /* 111 */
205-
for (i = 0; i < 3; i++) {
185+
secp256k1_scalar_mul(t, t, &u9); /* 1001 */
186+
for (i = 0; i < 6; i++) { /* 00 */
206187
secp256k1_scalar_sqr(t, t);
207188
}
208-
secp256k1_scalar_mul(t, t, &u5); /* 101 */
209-
for (i = 0; i < 5; i++) { /* 000 */
189+
secp256k1_scalar_mul(t, t, &u11); /* 1011 */
190+
for (i = 0; i < 4; i++) {
210191
secp256k1_scalar_sqr(t, t);
211192
}
212-
secp256k1_scalar_mul(t, t, &x2); /* 11 */
213-
for (i = 0; i < 4; i++) { /* 00 */
193+
secp256k1_scalar_mul(t, t, &u13); /* 1101 */
194+
for (i = 0; i < 5; i++) {
214195
secp256k1_scalar_sqr(t, t);
215196
}
216197
secp256k1_scalar_mul(t, t, &x2); /* 11 */
217-
for (i = 0; i < 2; i++) { /* 0 */
198+
for (i = 0; i < 6; i++) { /* 00 */
218199
secp256k1_scalar_sqr(t, t);
219200
}
220-
secp256k1_scalar_mul(t, t, x); /* 1 */
221-
for (i = 0; i < 8; i++) { /* 000000 */
201+
secp256k1_scalar_mul(t, t, &u13); /* 1101 */
202+
for (i = 0; i < 10; i++) { /* 000000 */
222203
secp256k1_scalar_sqr(t, t);
223204
}
224-
secp256k1_scalar_mul(t, t, &x2); /* 11 */
225-
for (i = 0; i < 3; i++) { /* 0 */
205+
secp256k1_scalar_mul(t, t, &u13); /* 1101 */
206+
for (i = 0; i < 4; i++) {
226207
secp256k1_scalar_sqr(t, t);
227208
}
228-
secp256k1_scalar_mul(t, t, &x2); /* 11 */
229-
for (i = 0; i < 3; i++) { /* 00 */
230-
secp256k1_scalar_sqr(t, t);
231-
}
232-
secp256k1_scalar_mul(t, t, x); /* 1 */
209+
secp256k1_scalar_mul(t, t, &u9); /* 1001 */
233210
for (i = 0; i < 6; i++) { /* 00000 */
234211
secp256k1_scalar_sqr(t, t);
235212
}

0 commit comments

Comments
 (0)