void run_sqrt(void) { secp256k1_fe_t ns, x, s, t; /* Check sqrt(0) is 0 */ secp256k1_fe_set_int(&x, 0); secp256k1_fe_sqr(&s, &x); test_sqrt(&s, &x); /* Check sqrt of small squares (and their negatives) */ for (int i=1; i<=100; i++) { secp256k1_fe_set_int(&x, i); secp256k1_fe_sqr(&s, &x); test_sqrt(&s, &x); secp256k1_fe_negate(&t, &s, 1); test_sqrt(&t, NULL); } /* Consistency checks for large random values */ for (int i=0; i<10; i++) { random_fe_non_square(&ns); for (int j=0; j<count; j++) { random_fe(&x); secp256k1_fe_sqr(&s, &x); test_sqrt(&s, &x); secp256k1_fe_negate(&t, &s, 1); test_sqrt(&t, NULL); secp256k1_fe_mul(&t, &s, &ns); test_sqrt(&t, NULL); } } }
static void secp256k1_gej_add_ge_bl(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b, secp256k1_fe_t *rzr) { secp256k1_fe_t z1z1, z1, u2, x1, y1, t0, s2, h, hh, i, j, t1, rr, v, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11; // 7M + 4S + 2 normalize + 22 mul_int/add/negate if (a->infinity) { VERIFY_CHECK(rzr == NULL); secp256k1_gej_set_ge(r, b); return; } if (b->infinity) { if (rzr) { secp256k1_fe_set_int(rzr, 1); } *r = *a; return; } r->infinity = 0; x1 = a->x; secp256k1_fe_normalize_weak(&x1); y1 = a->y; secp256k1_fe_normalize_weak(&y1); secp256k1_fe_sqr(&z1z1, &a->z); // z1z1 = z1^2 secp256k1_fe_mul(&u2, &b->x, &z1z1); // u2 = x2*z1z1 secp256k1_fe_mul(&t0, &a->z, &z1z1); // t0 = z1*z1z1 secp256k1_fe_mul(&s2, &b->y, &t0); // s2 = y2 * t0 secp256k1_fe_negate(&h, &x1, 1); secp256k1_fe_add(&h, &u2); // h = u2-x1 (3) secp256k1_fe_sqr(&hh,&h); // hh = h^2 i = hh; secp256k1_fe_mul_int(&i,4); // i = 4*hh if (secp256k1_fe_normalizes_to_zero_var(&h)) { if (secp256k1_fe_normalizes_to_zero_var(&i)) { secp256k1_gej_double_var(r, a, rzr); } else { if (rzr) { secp256k1_fe_set_int(rzr, 0); } r->infinity = 1; } return; } secp256k1_fe_mul(&j,&h,&i); // j = h*i secp256k1_fe_negate(&t1, &y1, 1); secp256k1_fe_add(&t1, &s2); // t1 = s2-y1 rr = t1; secp256k1_fe_mul_int(&rr, 2); // rr = 2 * t1; secp256k1_fe_mul(&v, &x1, &i); // v = x1 * i secp256k1_fe_sqr(&t2, &rr); // t2 = rr^2 t3 = v; secp256k1_fe_mul_int(&t3, 2); // t3 = 2*v secp256k1_fe_negate(&t4, &j, 1); secp256k1_fe_add(&t4, &t2); // t4 = t2 - j secp256k1_fe_negate(&r->x, &t3, 2); secp256k1_fe_add(&r->x, &t4); // x3 = t4 - t3; //secp256k1_fe_normalize_weak(&r->x); secp256k1_fe_negate(&t5, &r->x, 6); secp256k1_fe_add(&t5, &v); // t5 = v - x3 secp256k1_fe_mul(&t6,&y1,&j); // t6 = y1 * j t7 = t6; secp256k1_fe_mul_int(&t7,2); // t7 = 2*t6; secp256k1_fe_mul(&t8,&rr,&t5); // t8 = rr* t5; secp256k1_fe_negate(&r->y, &t7, 2); secp256k1_fe_add(&r->y,&t8);// y3 = t8-t7 //secp256k1_fe_normalize_weak(&r->y); t9 = h; secp256k1_fe_add(&t9, &a->z); // t9 = z1 + h secp256k1_fe_sqr(&t10, &t9); // t10 = t9^2 secp256k1_fe_negate(&t11, &z1z1, 1); secp256k1_fe_add(&t11, &t10); // t11 = t10-z1z1 secp256k1_fe_negate(&r->z, &hh, 1); secp256k1_fe_add(&r->z, &t11); // z3 = t11 - hh }
void run_sqr(void) { secp256k1_fe_t x, s; { secp256k1_fe_set_int(&x, 1); secp256k1_fe_negate(&x, &x, 1); for (int i=1; i<=512; ++i) { secp256k1_fe_mul_int(&x, 2); secp256k1_fe_normalize(&x); secp256k1_fe_sqr(&s, &x); } } }
int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) { secp256k1_fe_t x; secp256k1_fe_mul(&x, a, ai); secp256k1_fe_t one; secp256k1_fe_set_int(&one, 1); return check_fe_equal(&x, &one); }