MCPcopy Create free account
hub / github.com/ElementsProject/elements / test_modinv32_uint16

Function test_modinv32_uint16

src/secp256k1/src/tests.c:1039–1093  ·  view source on GitHub ↗

Test secp256k1_modinv32{_var}, using inputs in 16-bit limb format, and returning inverse. */

Source from the content-addressed store, hash-verified

1037
1038/* Test secp256k1_modinv32{_var}, using inputs in 16-bit limb format, and returning inverse. */
1039static void test_modinv32_uint16(uint16_t* out, const uint16_t* in, const uint16_t* mod) {
1040 uint16_t tmp[16];
1041 secp256k1_modinv32_signed30 x;
1042 secp256k1_modinv32_modinfo m;
1043 int i, vartime, nonzero;
1044
1045 uint16_to_signed30(&x, in);
1046 nonzero = (x.v[0] | x.v[1] | x.v[2] | x.v[3] | x.v[4] | x.v[5] | x.v[6] | x.v[7] | x.v[8]) != 0;
1047 uint16_to_signed30(&m.modulus, mod);
1048
1049 /* compute 1/modulus mod 2^30 */
1050 m.modulus_inv30 = modinv2p64(m.modulus.v[0]) & 0x3fffffff;
1051 CHECK(((m.modulus_inv30 * m.modulus.v[0]) & 0x3fffffff) == 1);
1052
1053 /* Test secp256k1_jacobi32_maybe_var. */
1054 if (nonzero) {
1055 int jac;
1056 uint16_t sqr[16], negone[16];
1057 mulmod256(sqr, in, in, mod);
1058 uint16_to_signed30(&x, sqr);
1059 /* Compute jacobi symbol of in^2, which must be 1 (or uncomputable). */
1060 jac = secp256k1_jacobi32_maybe_var(&x, &m);
1061 CHECK(jac == 0 || jac == 1);
1062 /* Then compute the jacobi symbol of -(in^2). x and -x have opposite
1063 * jacobi symbols if and only if (mod % 4) == 3. */
1064 negone[0] = mod[0] - 1;
1065 for (i = 1; i < 16; ++i) negone[i] = mod[i];
1066 mulmod256(sqr, sqr, negone, mod);
1067 uint16_to_signed30(&x, sqr);
1068 jac = secp256k1_jacobi32_maybe_var(&x, &m);
1069 CHECK(jac == 0 || jac == 1 - (mod[0] & 2));
1070 }
1071
1072 uint16_to_signed30(&x, in);
1073 mutate_sign_signed30(&m.modulus);
1074 for (vartime = 0; vartime < 2; ++vartime) {
1075 /* compute inverse */
1076 (vartime ? secp256k1_modinv32_var : secp256k1_modinv32)(&x, &m);
1077
1078 /* produce output */
1079 signed30_to_uint16(out, &x);
1080
1081 /* check if the inverse times the input is 1 (mod m), unless x is 0. */
1082 mulmod256(tmp, out, in, mod);
1083 CHECK(tmp[0] == nonzero);
1084 for (i = 1; i < 16; ++i) CHECK(tmp[i] == 0);
1085
1086 /* invert again */
1087 (vartime ? secp256k1_modinv32_var : secp256k1_modinv32)(&x, &m);
1088
1089 /* check if the result is equal to the input */
1090 signed30_to_uint16(tmp, &x);
1091 for (i = 0; i < 16; ++i) CHECK(tmp[i] == in[i]);
1092 }
1093}
1094
1095#ifdef SECP256K1_WIDEMUL_INT128
1096/* Convert a 256-bit number represented as 16 uint16_t's to signed62 notation. */

Callers 1

run_modinv_testsFunction · 0.85

Calls 6

uint16_to_signed30Function · 0.85
modinv2p64Function · 0.85
mulmod256Function · 0.85
mutate_sign_signed30Function · 0.85
signed30_to_uint16Function · 0.85

Tested by

no test coverage detected