Test secp256k1_modinv32{_var}, using inputs in 16-bit limb format, and returning inverse. */
| 1037 | |
| 1038 | /* Test secp256k1_modinv32{_var}, using inputs in 16-bit limb format, and returning inverse. */ |
| 1039 | static 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. */ |
no test coverage detected