diff options
author | tb <> | 2023-04-11 10:08:44 +0000 |
---|---|---|
committer | tb <> | 2023-04-11 10:08:44 +0000 |
commit | 2fc970f40eeb1044a661fa924f93ab9668d3910c (patch) | |
tree | 1a8331f19d48335fd135b93854c36f2ea3244918 /src/lib/libcrypto/bn/bn_mod_sqrt.c | |
parent | 8ba2869b3fad78a19522d1476fb6f12dc9bee1c3 (diff) | |
download | openbsd-2fc970f40eeb1044a661fa924f93ab9668d3910c.tar.gz openbsd-2fc970f40eeb1044a661fa924f93ab9668d3910c.tar.bz2 openbsd-2fc970f40eeb1044a661fa924f93ab9668d3910c.zip |
Add a new implementation of BN_mod_sqrt()
This is a reimplementation from scratch of the Tonelli-Shanks algorithm
based on Henri Cohen "A Course in Computational Algebraic Number Theory",
Springer GTM 138, section 1.5.1. It is API compatible with the previous
implementation, so no documentation change is required.
Contrary to the old implementation, this does not have any infinite loops
and has various additional sanity checks to prevent misbehavior in case
the input modulus is not a prime. It contains extensive comments and the
individual parts of the algorithm are split into digestible chunks instead
of having one huge function.
One difference of note is that it BN_mod_sqrt() now always returns the
smaller of the two possible answers. In other words, while its core is
non-deterministic, its answer is not.
ok jsing
Diffstat (limited to 'src/lib/libcrypto/bn/bn_mod_sqrt.c')
-rw-r--r-- | src/lib/libcrypto/bn/bn_mod_sqrt.c | 726 |
1 files changed, 726 insertions, 0 deletions
diff --git a/src/lib/libcrypto/bn/bn_mod_sqrt.c b/src/lib/libcrypto/bn/bn_mod_sqrt.c new file mode 100644 index 0000000000..acca540e25 --- /dev/null +++ b/src/lib/libcrypto/bn/bn_mod_sqrt.c | |||
@@ -0,0 +1,726 @@ | |||
1 | /* $OpenBSD: bn_mod_sqrt.c,v 1.1 2023/04/11 10:08:44 tb Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * Copyright (c) 2022 Theo Buehler <tb@openbsd.org> | ||
5 | * | ||
6 | * Permission to use, copy, modify, and distribute this software for any | ||
7 | * purpose with or without fee is hereby granted, provided that the above | ||
8 | * copyright notice and this permission notice appear in all copies. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #include <openssl/err.h> | ||
20 | |||
21 | #include "bn_local.h" | ||
22 | |||
23 | /* | ||
24 | * Tonelli-Shanks according to H. Cohen "A Course in Computational Algebraic | ||
25 | * Number Theory", Section 1.5.1, Springer GTM volume 138, Berlin, 1996. | ||
26 | * | ||
27 | * Under the assumption that p is prime and a is a quadratic residue, we know: | ||
28 | * | ||
29 | * a^[(p-1)/2] = 1 (mod p). (*) | ||
30 | * | ||
31 | * To find a square root of a (mod p), we handle three cases of increasing | ||
32 | * complexity. In the first two cases, we can compute a square root using an | ||
33 | * explicit formula, thus avoiding the probabilistic nature of Tonelli-Shanks. | ||
34 | * | ||
35 | * 1. p = 3 (mod 4). | ||
36 | * | ||
37 | * Set n = (p+1)/4. Then 2n = 1 + (p-1)/2 and (*) shows that x = a^n (mod p) | ||
38 | * is a square root of a: x^2 = a^(2n) = a * a^[(p-1)/2] = a (mod p). | ||
39 | * | ||
40 | * 2. p = 5 (mod 8). | ||
41 | * | ||
42 | * This uses a simplification due to Atkin. By Theorem 1.4.7 and 1.4.9, the | ||
43 | * Kronecker symbol (2/p) evaluates to (-1)^[(p^2-1)/8]. From p = 5 (mod 8) | ||
44 | * we get (p^2-1)/8 = 1 (mod 2), so (2/p) = -1, and thus | ||
45 | * | ||
46 | * 2^[(p-1)/2] = -1 (mod p). (**) | ||
47 | * | ||
48 | * Set b = (2a)^[(p-5)/8]. With (p-1)/2 = 2 + (p-5)/2, (*) and (**) show | ||
49 | * | ||
50 | * i = 2 a b^2 is a square root of -1 (mod p). | ||
51 | * | ||
52 | * Indeed, i^2 = 2^2 a^2 b^4 = 2^[(p-1)/2] a^[(p-1)/2] = -1 (mod p). Because | ||
53 | * of (i-1)^2 = -2i (mod p) and i (-i) = 1 (mod p), a square root of a is | ||
54 | * | ||
55 | * x = a b (i-1) | ||
56 | * | ||
57 | * as x^2 = a^2 b^2 (-2i) = a (2 a b^2) (-i) = a (mod p). | ||
58 | * | ||
59 | * 3. p = 1 (mod 8). | ||
60 | * | ||
61 | * This is the Tonelli-Shanks algorithm. For a prime p, the multiplicative | ||
62 | * group of GF(p) is cyclic of order p - 1 = 2^s q, with odd q. Denote its | ||
63 | * 2-Sylow subgroup by S. It is cyclic of order 2^s. The squares in S have | ||
64 | * order dividing 2^(s-1). They are the even powers of any generator z of S. | ||
65 | * If a is a quadratic residue, 1 = a^[(p-1)/2] = (a^q)^[2^(s-1)], so b = a^q | ||
66 | * is a square in S. Therefore there is an integer k such that b z^(2k) = 1. | ||
67 | * Set x = a^[(q+1)/2] z^k, and find x^2 = a (mod p). | ||
68 | * | ||
69 | * The problem is thus reduced to finding a generator z of the 2-Sylow | ||
70 | * subgroup S of GF(p)* and finding k. An iterative constructions avoids | ||
71 | * the need for an explicit k, a generator is found by a randomized search. | ||
72 | * | ||
73 | * While we do not actually know that p is a prime number, we can still apply | ||
74 | * the formulas in cases 1 and 2 and verify that we have indeed found a square | ||
75 | * root of p. Similarly, in case 3, we can try to find a quadratic non-residue, | ||
76 | * which will fail for example if p is a square. The iterative construction | ||
77 | * may or may not find a candidate square root which we can then validate. | ||
78 | */ | ||
79 | |||
80 | /* | ||
81 | * Handle the cases where p is 2, p isn't odd or p is one. Since BN_mod_sqrt() | ||
82 | * can run on untrusted data, a primality check is too expensive. Also treat | ||
83 | * the obvious cases where a is 0 or 1. | ||
84 | */ | ||
85 | |||
86 | static int | ||
87 | bn_mod_sqrt_trivial_cases(int *done, BIGNUM *out_sqrt, const BIGNUM *a, | ||
88 | const BIGNUM *p, BN_CTX *ctx) | ||
89 | { | ||
90 | *done = 1; | ||
91 | |||
92 | if (BN_abs_is_word(p, 2)) | ||
93 | return BN_set_word(out_sqrt, BN_is_odd(a)); | ||
94 | |||
95 | if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) { | ||
96 | BNerror(BN_R_P_IS_NOT_PRIME); | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | if (BN_is_zero(a) || BN_is_one(a)) | ||
101 | return BN_set_word(out_sqrt, BN_is_one(a)); | ||
102 | |||
103 | *done = 0; | ||
104 | |||
105 | return 1; | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Case 1. We know that (a/p) = 1 and that p = 3 (mod 4). | ||
110 | */ | ||
111 | |||
112 | static int | ||
113 | bn_mod_sqrt_p_is_3_mod_4(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p, | ||
114 | BN_CTX *ctx) | ||
115 | { | ||
116 | BIGNUM *n; | ||
117 | int ret = 0; | ||
118 | |||
119 | BN_CTX_start(ctx); | ||
120 | |||
121 | if ((n = BN_CTX_get(ctx)) == NULL) | ||
122 | goto err; | ||
123 | |||
124 | /* Calculate n = (|p| + 1) / 4. */ | ||
125 | if (!BN_uadd(n, p, BN_value_one())) | ||
126 | goto err; | ||
127 | if (!BN_rshift(n, n, 2)) | ||
128 | goto err; | ||
129 | |||
130 | /* By case 1 above, out_sqrt = a^n is a square root of a (mod p). */ | ||
131 | if (!BN_mod_exp_ct(out_sqrt, a, n, p, ctx)) | ||
132 | goto err; | ||
133 | |||
134 | ret = 1; | ||
135 | |||
136 | err: | ||
137 | BN_CTX_end(ctx); | ||
138 | |||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * Case 2. We know that (a/p) = 1 and that p = 5 (mod 8). | ||
144 | */ | ||
145 | |||
146 | static int | ||
147 | bn_mod_sqrt_p_is_5_mod_8(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p, | ||
148 | BN_CTX *ctx) | ||
149 | { | ||
150 | BIGNUM *b, *i, *n, *tmp; | ||
151 | int ret = 0; | ||
152 | |||
153 | BN_CTX_start(ctx); | ||
154 | |||
155 | if ((b = BN_CTX_get(ctx)) == NULL) | ||
156 | goto err; | ||
157 | if ((i = BN_CTX_get(ctx)) == NULL) | ||
158 | goto err; | ||
159 | if ((n = BN_CTX_get(ctx)) == NULL) | ||
160 | goto err; | ||
161 | if ((tmp = BN_CTX_get(ctx)) == NULL) | ||
162 | goto err; | ||
163 | |||
164 | /* Calculate n = (|p| - 5) / 8. Since p = 5 (mod 8), simply shift. */ | ||
165 | if (!BN_rshift(n, p, 3)) | ||
166 | goto err; | ||
167 | BN_set_negative(n, 0); | ||
168 | |||
169 | /* Compute tmp = 2a (mod p) for later use. */ | ||
170 | if (!BN_mod_lshift1(tmp, a, p, ctx)) | ||
171 | goto err; | ||
172 | |||
173 | /* Calculate b = (2a)^n (mod p). */ | ||
174 | if (!BN_mod_exp_ct(b, tmp, n, p, ctx)) | ||
175 | goto err; | ||
176 | |||
177 | /* Calculate i = 2 a b^2 (mod p). */ | ||
178 | if (!BN_mod_sqr(i, b, p, ctx)) | ||
179 | goto err; | ||
180 | if (!BN_mod_mul(i, tmp, i, p, ctx)) | ||
181 | goto err; | ||
182 | |||
183 | /* A square root is out_sqrt = a b (i-1) (mod p). */ | ||
184 | if (!BN_sub_word(i, 1)) | ||
185 | goto err; | ||
186 | if (!BN_mod_mul(out_sqrt, a, b, p, ctx)) | ||
187 | goto err; | ||
188 | if (!BN_mod_mul(out_sqrt, out_sqrt, i, p, ctx)) | ||
189 | goto err; | ||
190 | |||
191 | ret = 1; | ||
192 | |||
193 | err: | ||
194 | BN_CTX_end(ctx); | ||
195 | |||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | /* | ||
200 | * Case 3. We know that (a/p) = 1 and that p = 1 (mod 8). | ||
201 | */ | ||
202 | |||
203 | /* | ||
204 | * Simple helper. To find a generator of the 2-Sylow subgroup of GF(p)*, we | ||
205 | * need to find a quadratic non-residue of p, i.e., n such that (n/p) = -1. | ||
206 | */ | ||
207 | |||
208 | static int | ||
209 | bn_mod_sqrt_n_is_non_residue(int *is_non_residue, const BIGNUM *n, | ||
210 | const BIGNUM *p, BN_CTX *ctx) | ||
211 | { | ||
212 | switch (BN_kronecker(n, p, ctx)) { | ||
213 | case -1: | ||
214 | *is_non_residue = 1; | ||
215 | return 1; | ||
216 | case 1: | ||
217 | *is_non_residue = 0; | ||
218 | return 1; | ||
219 | case 0: | ||
220 | /* n divides p, so ... */ | ||
221 | BNerror(BN_R_P_IS_NOT_PRIME); | ||
222 | return 0; | ||
223 | default: | ||
224 | return 0; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * The following is the only non-deterministic part preparing Tonelli-Shanks. | ||
230 | * | ||
231 | * If we find n such that (n/p) = -1, then n^q (mod p) is a generator of the | ||
232 | * 2-Sylow subgroup of GF(p)*. To find such n, first try some small numbers, | ||
233 | * then random ones. | ||
234 | */ | ||
235 | |||
236 | static int | ||
237 | bn_mod_sqrt_find_sylow_generator(BIGNUM *out_generator, const BIGNUM *p, | ||
238 | const BIGNUM *q, BN_CTX *ctx) | ||
239 | { | ||
240 | BIGNUM *n, *p_abs, *thirty_two; | ||
241 | int i, is_non_residue; | ||
242 | int ret = 0; | ||
243 | |||
244 | BN_CTX_start(ctx); | ||
245 | |||
246 | if ((n = BN_CTX_get(ctx)) == NULL) | ||
247 | goto err; | ||
248 | if ((thirty_two = BN_CTX_get(ctx)) == NULL) | ||
249 | goto err; | ||
250 | if ((p_abs = BN_CTX_get(ctx)) == NULL) | ||
251 | goto err; | ||
252 | |||
253 | for (i = 2; i < 32; i++) { | ||
254 | if (!BN_set_word(n, i)) | ||
255 | goto err; | ||
256 | if (!bn_mod_sqrt_n_is_non_residue(&is_non_residue, n, p, ctx)) | ||
257 | goto err; | ||
258 | if (is_non_residue) | ||
259 | goto found; | ||
260 | } | ||
261 | |||
262 | if (!BN_set_word(thirty_two, 32)) | ||
263 | goto err; | ||
264 | if (!bn_copy(p_abs, p)) | ||
265 | goto err; | ||
266 | BN_set_negative(p_abs, 0); | ||
267 | |||
268 | for (i = 0; i < 128; i++) { | ||
269 | if (!bn_rand_interval(n, thirty_two, p_abs)) | ||
270 | goto err; | ||
271 | if (!bn_mod_sqrt_n_is_non_residue(&is_non_residue, n, p, ctx)) | ||
272 | goto err; | ||
273 | if (is_non_residue) | ||
274 | goto found; | ||
275 | } | ||
276 | |||
277 | /* | ||
278 | * The probability to get here is < 2^(-128) for prime p. For squares | ||
279 | * it is easy: for p = 1369 = 37^2 this happens in ~3% of runs. | ||
280 | */ | ||
281 | |||
282 | BNerror(BN_R_TOO_MANY_ITERATIONS); | ||
283 | goto err; | ||
284 | |||
285 | found: | ||
286 | /* | ||
287 | * If p is prime, n^q generates the 2-Sylow subgroup S of GF(p)*. | ||
288 | */ | ||
289 | |||
290 | if (!BN_mod_exp_ct(out_generator, n, q, p, ctx)) | ||
291 | goto err; | ||
292 | |||
293 | /* Sanity: p is not necessarily prime, so we could have found 0 or 1. */ | ||
294 | if (BN_is_zero(out_generator) || BN_is_one(out_generator)) { | ||
295 | BNerror(BN_R_P_IS_NOT_PRIME); | ||
296 | goto err; | ||
297 | } | ||
298 | |||
299 | ret = 1; | ||
300 | |||
301 | err: | ||
302 | BN_CTX_end(ctx); | ||
303 | |||
304 | return ret; | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * Initialization step for Tonelli-Shanks. | ||
309 | * | ||
310 | * In the end, b = a^q (mod p) and x = a^[(q+1)/2] (mod p). Cohen optimizes this | ||
311 | * to minimize taking powers of a. This is a bit confusing and distracting, so | ||
312 | * factor this into a separate function. | ||
313 | */ | ||
314 | |||
315 | static int | ||
316 | bn_mod_sqrt_tonelli_shanks_initialize(BIGNUM *b, BIGNUM *x, const BIGNUM *a, | ||
317 | const BIGNUM *p, const BIGNUM *q, BN_CTX *ctx) | ||
318 | { | ||
319 | BIGNUM *k; | ||
320 | int ret = 0; | ||
321 | |||
322 | BN_CTX_start(ctx); | ||
323 | |||
324 | if ((k = BN_CTX_get(ctx)) == NULL) | ||
325 | goto err; | ||
326 | |||
327 | /* k = (q-1)/2. Since q is odd, we can shift. */ | ||
328 | if (!BN_rshift1(k, q)) | ||
329 | goto err; | ||
330 | |||
331 | /* x = a^[(q-1)/2] (mod p). */ | ||
332 | if (!BN_mod_exp_ct(x, a, k, p, ctx)) | ||
333 | goto err; | ||
334 | |||
335 | /* b = ax^2 = a^q (mod p). */ | ||
336 | if (!BN_mod_sqr(b, x, p, ctx)) | ||
337 | goto err; | ||
338 | if (!BN_mod_mul(b, a, b, p, ctx)) | ||
339 | goto err; | ||
340 | |||
341 | /* x = ax = a^[(q+1)/2] (mod p). */ | ||
342 | if (!BN_mod_mul(x, a, x, p, ctx)) | ||
343 | goto err; | ||
344 | |||
345 | ret = 1; | ||
346 | |||
347 | err: | ||
348 | BN_CTX_end(ctx); | ||
349 | |||
350 | return ret; | ||
351 | } | ||
352 | |||
353 | /* | ||
354 | * Find smallest exponent m such that b^(2^m) = 1 (mod p). Assuming that a | ||
355 | * is a quadratic residue and p is a prime, we know that 1 <= m < r. | ||
356 | */ | ||
357 | |||
358 | static int | ||
359 | bn_mod_sqrt_tonelli_shanks_find_exponent(int *out_exponent, const BIGNUM *b, | ||
360 | const BIGNUM *p, int r, BN_CTX *ctx) | ||
361 | { | ||
362 | BIGNUM *x; | ||
363 | int m; | ||
364 | int ret = 0; | ||
365 | |||
366 | BN_CTX_start(ctx); | ||
367 | |||
368 | if ((x = BN_CTX_get(ctx)) == NULL) | ||
369 | goto err; | ||
370 | |||
371 | /* | ||
372 | * If r <= 1, the Tonelli-Shanks iteration should have terminated as | ||
373 | * r == 1 implies b == 1. | ||
374 | */ | ||
375 | if (r <= 1) { | ||
376 | BNerror(BN_R_P_IS_NOT_PRIME); | ||
377 | goto err; | ||
378 | } | ||
379 | |||
380 | /* | ||
381 | * Sanity check to ensure taking squares actually does something: | ||
382 | * If b is 1, the Tonelli-Shanks iteration should have terminated. | ||
383 | * If b is 0, something's very wrong, in particular p can't be prime. | ||
384 | */ | ||
385 | if (BN_is_zero(b) || BN_is_one(b)) { | ||
386 | BNerror(BN_R_P_IS_NOT_PRIME); | ||
387 | goto err; | ||
388 | } | ||
389 | |||
390 | if (!bn_copy(x, b)) | ||
391 | goto err; | ||
392 | |||
393 | for (m = 1; m < r; m++) { | ||
394 | if (!BN_mod_sqr(x, x, p, ctx)) | ||
395 | goto err; | ||
396 | if (BN_is_one(x)) | ||
397 | break; | ||
398 | } | ||
399 | |||
400 | if (m >= r) { | ||
401 | /* This means a is not a quadratic residue. As (a/p) = 1, ... */ | ||
402 | BNerror(BN_R_P_IS_NOT_PRIME); | ||
403 | goto err; | ||
404 | } | ||
405 | |||
406 | *out_exponent = m; | ||
407 | |||
408 | ret = 1; | ||
409 | |||
410 | err: | ||
411 | BN_CTX_end(ctx); | ||
412 | |||
413 | return ret; | ||
414 | } | ||
415 | |||
416 | /* | ||
417 | * The update step. With the minimal m such that b^(2^m) = 1 (mod m), | ||
418 | * set t = y^[2^(r-m-1)] (mod p) and update x = xt, y = t^2, b = by. | ||
419 | * This preserves the loop invariants a b = x^2, y^[2^(r-1)] = -1 and | ||
420 | * b^[2^(r-1)] = 1. | ||
421 | */ | ||
422 | |||
423 | static int | ||
424 | bn_mod_sqrt_tonelli_shanks_update(BIGNUM *b, BIGNUM *x, BIGNUM *y, | ||
425 | const BIGNUM *p, int m, int r, BN_CTX *ctx) | ||
426 | { | ||
427 | BIGNUM *t; | ||
428 | int ret = 0; | ||
429 | |||
430 | BN_CTX_start(ctx); | ||
431 | |||
432 | if ((t = BN_CTX_get(ctx)) == NULL) | ||
433 | goto err; | ||
434 | |||
435 | /* t = y^[2^(r-m-1)] (mod p). */ | ||
436 | if (!BN_set_bit(t, r - m - 1)) | ||
437 | goto err; | ||
438 | if (!BN_mod_exp_ct(t, y, t, p, ctx)) | ||
439 | goto err; | ||
440 | |||
441 | /* x = xt (mod p). */ | ||
442 | if (!BN_mod_mul(x, x, t, p, ctx)) | ||
443 | goto err; | ||
444 | |||
445 | /* y = t^2 = y^[2^(r-m)] (mod p). */ | ||
446 | if (!BN_mod_sqr(y, t, p, ctx)) | ||
447 | goto err; | ||
448 | |||
449 | /* b = by (mod p). */ | ||
450 | if (!BN_mod_mul(b, b, y, p, ctx)) | ||
451 | goto err; | ||
452 | |||
453 | ret = 1; | ||
454 | |||
455 | err: | ||
456 | BN_CTX_end(ctx); | ||
457 | |||
458 | return ret; | ||
459 | } | ||
460 | |||
461 | static int | ||
462 | bn_mod_sqrt_p_is_1_mod_8(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p, | ||
463 | BN_CTX *ctx) | ||
464 | { | ||
465 | BIGNUM *b, *q, *x, *y; | ||
466 | int e, m, r; | ||
467 | int ret = 0; | ||
468 | |||
469 | BN_CTX_start(ctx); | ||
470 | |||
471 | if ((b = BN_CTX_get(ctx)) == NULL) | ||
472 | goto err; | ||
473 | if ((q = BN_CTX_get(ctx)) == NULL) | ||
474 | goto err; | ||
475 | if ((x = BN_CTX_get(ctx)) == NULL) | ||
476 | goto err; | ||
477 | if ((y = BN_CTX_get(ctx)) == NULL) | ||
478 | goto err; | ||
479 | |||
480 | /* | ||
481 | * Factor p - 1 = 2^e q with odd q. Since p = 1 (mod 8), we know e >= 3. | ||
482 | */ | ||
483 | |||
484 | e = 1; | ||
485 | while (!BN_is_bit_set(p, e)) | ||
486 | e++; | ||
487 | if (!BN_rshift(q, p, e)) | ||
488 | goto err; | ||
489 | |||
490 | if (!bn_mod_sqrt_find_sylow_generator(y, p, q, ctx)) | ||
491 | goto err; | ||
492 | |||
493 | /* | ||
494 | * Set b = a^q (mod p) and x = a^[(q+1)/2] (mod p). | ||
495 | */ | ||
496 | if (!bn_mod_sqrt_tonelli_shanks_initialize(b, x, a, p, q, ctx)) | ||
497 | goto err; | ||
498 | |||
499 | /* | ||
500 | * The Tonelli-Shanks iteration. Starting with r = e, the following loop | ||
501 | * invariants hold at the start of the loop. | ||
502 | * | ||
503 | * a b = x^2 (mod p) | ||
504 | * y^[2^(r-1)] = -1 (mod p) | ||
505 | * b^[2^(r-1)] = 1 (mod p) | ||
506 | * | ||
507 | * In particular, if b = 1 (mod p), x is a square root of a. | ||
508 | * | ||
509 | * Since p - 1 = 2^e q, we have 2^(e-1) q = (p - 1) / 2, so in the first | ||
510 | * iteration this follows from (a/p) = 1, (n/p) = -1, y = n^q, b = a^q. | ||
511 | * | ||
512 | * In subsequent iterations, t = y^[2^(r-m-1)], where m is the smallest | ||
513 | * m such that b^(2^m) = 1. With x = xt (mod p) and b = bt^2 (mod p) the | ||
514 | * first invariant is preserved, the second and third follow from | ||
515 | * y = t^2 (mod p) and r = m as well as the choice of m. | ||
516 | * | ||
517 | * Finally, r is strictly decreasing in each iteration. If p is prime, | ||
518 | * let S be the 2-Sylow subgroup of GF(p)*. We can prove the algorithm | ||
519 | * stops: Let S_r be the subgroup of S consisting of elements of order | ||
520 | * dividing 2^r. Then S_r = <y> and b is in S_(r-1). The S_r form a | ||
521 | * descending filtration of S and when r = 1, then b = 1. | ||
522 | */ | ||
523 | |||
524 | for (r = e; r >= 1; r = m) { | ||
525 | /* | ||
526 | * Termination condition. If b == 1 then x is a square root. | ||
527 | */ | ||
528 | if (BN_is_one(b)) | ||
529 | goto done; | ||
530 | |||
531 | /* Find smallest exponent 1 <= m < r such that b^(2^m) == 1. */ | ||
532 | if (!bn_mod_sqrt_tonelli_shanks_find_exponent(&m, b, p, r, ctx)) | ||
533 | goto err; | ||
534 | |||
535 | /* | ||
536 | * With t = y^[2^(r-m-1)], update x = xt, y = t^2, b = by. | ||
537 | */ | ||
538 | if (!bn_mod_sqrt_tonelli_shanks_update(b, x, y, p, m, r, ctx)) | ||
539 | goto err; | ||
540 | |||
541 | /* | ||
542 | * Sanity check to make sure we don't loop indefinitely. | ||
543 | * bn_mod_sqrt_tonelli_shanks_find_exponent() ensures m < r. | ||
544 | */ | ||
545 | if (r <= m) | ||
546 | goto err; | ||
547 | } | ||
548 | |||
549 | /* | ||
550 | * If p is prime, we should not get here. | ||
551 | */ | ||
552 | |||
553 | BNerror(BN_R_NOT_A_SQUARE); | ||
554 | goto err; | ||
555 | |||
556 | done: | ||
557 | if (!bn_copy(out_sqrt, x)) | ||
558 | goto err; | ||
559 | |||
560 | ret = 1; | ||
561 | |||
562 | err: | ||
563 | BN_CTX_end(ctx); | ||
564 | |||
565 | return ret; | ||
566 | } | ||
567 | |||
568 | /* | ||
569 | * Choose the smaller of sqrt and |p| - sqrt. | ||
570 | */ | ||
571 | |||
572 | static int | ||
573 | bn_mod_sqrt_normalize(BIGNUM *sqrt, const BIGNUM *p, BN_CTX *ctx) | ||
574 | { | ||
575 | BIGNUM *x; | ||
576 | int ret = 0; | ||
577 | |||
578 | BN_CTX_start(ctx); | ||
579 | |||
580 | if ((x = BN_CTX_get(ctx)) == NULL) | ||
581 | goto err; | ||
582 | |||
583 | if (!BN_lshift1(x, sqrt)) | ||
584 | goto err; | ||
585 | |||
586 | if (BN_ucmp(x, p) > 0) { | ||
587 | if (!BN_usub(sqrt, p, sqrt)) | ||
588 | goto err; | ||
589 | } | ||
590 | |||
591 | ret = 1; | ||
592 | |||
593 | err: | ||
594 | BN_CTX_end(ctx); | ||
595 | |||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | /* | ||
600 | * Verify that a = (sqrt_a)^2 (mod p). Requires that a is reduced (mod p). | ||
601 | */ | ||
602 | |||
603 | static int | ||
604 | bn_mod_sqrt_verify(const BIGNUM *a, const BIGNUM *sqrt_a, const BIGNUM *p, | ||
605 | BN_CTX *ctx) | ||
606 | { | ||
607 | BIGNUM *x; | ||
608 | int ret = 0; | ||
609 | |||
610 | BN_CTX_start(ctx); | ||
611 | |||
612 | if ((x = BN_CTX_get(ctx)) == NULL) | ||
613 | goto err; | ||
614 | |||
615 | if (!BN_mod_sqr(x, sqrt_a, p, ctx)) | ||
616 | goto err; | ||
617 | |||
618 | if (BN_cmp(x, a) != 0) { | ||
619 | BNerror(BN_R_NOT_A_SQUARE); | ||
620 | goto err; | ||
621 | } | ||
622 | |||
623 | ret = 1; | ||
624 | |||
625 | err: | ||
626 | BN_CTX_end(ctx); | ||
627 | |||
628 | return ret; | ||
629 | } | ||
630 | |||
631 | static int | ||
632 | bn_mod_sqrt_internal(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p, | ||
633 | BN_CTX *ctx) | ||
634 | { | ||
635 | BIGNUM *a_mod_p, *sqrt; | ||
636 | BN_ULONG lsw; | ||
637 | int done; | ||
638 | int kronecker; | ||
639 | int ret = 0; | ||
640 | |||
641 | BN_CTX_start(ctx); | ||
642 | |||
643 | if ((a_mod_p = BN_CTX_get(ctx)) == NULL) | ||
644 | goto err; | ||
645 | if ((sqrt = BN_CTX_get(ctx)) == NULL) | ||
646 | goto err; | ||
647 | |||
648 | if (!BN_nnmod(a_mod_p, a, p, ctx)) | ||
649 | goto err; | ||
650 | |||
651 | if (!bn_mod_sqrt_trivial_cases(&done, sqrt, a_mod_p, p, ctx)) | ||
652 | goto err; | ||
653 | if (done) | ||
654 | goto verify; | ||
655 | |||
656 | /* | ||
657 | * Make sure that the Kronecker symbol (a/p) == 1. In case p is prime | ||
658 | * this is equivalent to a having a square root (mod p). The cost of | ||
659 | * BN_kronecker() is O(log^2(n)). This is small compared to the cost | ||
660 | * O(log^4(n)) of Tonelli-Shanks. | ||
661 | */ | ||
662 | |||
663 | if ((kronecker = BN_kronecker(a_mod_p, p, ctx)) == -2) | ||
664 | goto err; | ||
665 | if (kronecker <= 0) { | ||
666 | /* This error is only accurate if p is known to be a prime. */ | ||
667 | BNerror(BN_R_NOT_A_SQUARE); | ||
668 | goto err; | ||
669 | } | ||
670 | |||
671 | lsw = BN_lsw(p); | ||
672 | |||
673 | if (lsw % 4 == 3) { | ||
674 | if (!bn_mod_sqrt_p_is_3_mod_4(sqrt, a_mod_p, p, ctx)) | ||
675 | goto err; | ||
676 | } else if (lsw % 8 == 5) { | ||
677 | if (!bn_mod_sqrt_p_is_5_mod_8(sqrt, a_mod_p, p, ctx)) | ||
678 | goto err; | ||
679 | } else if (lsw % 8 == 1) { | ||
680 | if (!bn_mod_sqrt_p_is_1_mod_8(sqrt, a_mod_p, p, ctx)) | ||
681 | goto err; | ||
682 | } else { | ||
683 | /* Impossible to hit since the trivial cases ensure p is odd. */ | ||
684 | BNerror(BN_R_P_IS_NOT_PRIME); | ||
685 | goto err; | ||
686 | } | ||
687 | |||
688 | if (!bn_mod_sqrt_normalize(sqrt, p, ctx)) | ||
689 | goto err; | ||
690 | |||
691 | verify: | ||
692 | if (!bn_mod_sqrt_verify(a_mod_p, sqrt, p, ctx)) | ||
693 | goto err; | ||
694 | |||
695 | if (!bn_copy(out_sqrt, sqrt)) | ||
696 | goto err; | ||
697 | |||
698 | ret = 1; | ||
699 | |||
700 | err: | ||
701 | BN_CTX_end(ctx); | ||
702 | |||
703 | return ret; | ||
704 | } | ||
705 | |||
706 | BIGNUM * | ||
707 | BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | ||
708 | { | ||
709 | BIGNUM *out_sqrt; | ||
710 | |||
711 | if ((out_sqrt = in) == NULL) | ||
712 | out_sqrt = BN_new(); | ||
713 | if (out_sqrt == NULL) | ||
714 | goto err; | ||
715 | |||
716 | if (!bn_mod_sqrt_internal(out_sqrt, a, p, ctx)) | ||
717 | goto err; | ||
718 | |||
719 | return out_sqrt; | ||
720 | |||
721 | err: | ||
722 | if (out_sqrt != in) | ||
723 | BN_free(out_sqrt); | ||
724 | |||
725 | return NULL; | ||
726 | } | ||