Skip to content

Commit be82bd8

Browse files
committed
Improve comments/checks for fe_sqrt
1 parent 6ab3508 commit be82bd8

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

src/field.h

+8-6
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,14 @@ static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp2
246246
*/
247247
static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a);
248248

249-
/** If a has a square root, it is computed in r and 1 is returned. If a does not
250-
* have a square root, the root of its negation is computed and 0 is returned.
251-
* The input's magnitude can be at most 8. The output magnitude is 1 (but not
252-
* guaranteed to be normalized). The result in r will always be a square
253-
* itself. */
254-
static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a);
249+
/** Compute a square root of a field element.
250+
*
251+
* On input, a must be a valid field element with magnitude<=8; r need not be initialized.
252+
* Performs {r = sqrt(a)} or {r = sqrt(-a)}, whichever exists. The resulting value
253+
* represented by r will be a square itself. Variables r and a must not point to the same object.
254+
* On output, r will have magnitude 1 but will not be normalized.
255+
*/
256+
static int secp256k1_fe_sqrt(secp256k1_fe * SECP256K1_RESTRICT r, const secp256k1_fe * SECP256K1_RESTRICT a);
255257

256258
/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be
257259
* at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */

src/field_impl.h

+15-2
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,13 @@ static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) {
5555
* itself always a square (a ** ((p+1)/4) is the square of a ** ((p+1)/8)).
5656
*/
5757
secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1;
58-
int j;
58+
int j, ret;
5959

60+
#ifdef VERIFY
6061
VERIFY_CHECK(r != a);
62+
secp256k1_fe_verify(a);
63+
VERIFY_CHECK(a->magnitude <= 8);
64+
#endif
6165

6266
/** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in
6367
* { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block:
@@ -141,7 +145,16 @@ static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) {
141145
/* Check that a square root was actually calculated */
142146

143147
secp256k1_fe_sqr(&t1, r);
144-
return secp256k1_fe_equal(&t1, a);
148+
ret = secp256k1_fe_equal(&t1, a);
149+
150+
#ifdef VERIFY
151+
if (!ret) {
152+
secp256k1_fe_negate(&t1, &t1, 1);
153+
secp256k1_fe_normalize_var(&t1);
154+
VERIFY_CHECK(secp256k1_fe_equal_var(&t1, a));
155+
}
156+
#endif
157+
return ret;
145158
}
146159

147160
#ifndef VERIFY

0 commit comments

Comments
 (0)