Implement pairing check
This commit is contained in:
parent
b9f4e7737e
commit
c68056638a
|
@ -52,6 +52,19 @@ void p1_sub(blst_p1 *out, const blst_p1 *a, const blst_p1 *b) {
|
||||||
blst_p1_add_or_double(out, a, &bneg);
|
blst_p1_add_or_double(out, a, &bneg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Is there really no better way to do this?
|
||||||
|
void p2_mul(blst_p2 *out, const blst_p2 *a, const blst_fr *b) {
|
||||||
|
blst_scalar s;
|
||||||
|
blst_scalar_from_fr(&s, b);
|
||||||
|
blst_p2_mult(out, a, s.b, 8 * sizeof(blst_scalar));
|
||||||
|
}
|
||||||
|
|
||||||
|
void p2_sub(blst_p2 *out, const blst_p2 *a, const blst_p2 *b) {
|
||||||
|
blst_p2 bneg = *b;
|
||||||
|
blst_p2_cneg(&bneg, true);
|
||||||
|
blst_p2_add_or_double(out, a, &bneg);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: would be good to have an optimised multiexp for this
|
// TODO: would be good to have an optimised multiexp for this
|
||||||
void linear_combination_g1(blst_p1 *out, const blst_p1 *p, const blst_fr *coeffs, const uint64_t len) {
|
void linear_combination_g1(blst_p1 *out, const blst_p1 *p, const blst_fr *coeffs, const uint64_t len) {
|
||||||
blst_p1 tmp;
|
blst_p1 tmp;
|
||||||
|
@ -61,3 +74,27 @@ void linear_combination_g1(blst_p1 *out, const blst_p1 *p, const blst_fr *coeffs
|
||||||
blst_p1_add_or_double(out, out, &tmp);
|
blst_p1_add_or_double(out, out, &tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool pairings_verify(const blst_p1 *aa1, const blst_p2 *aa2, const blst_p1 *bb1, const blst_p2 *bb2) {
|
||||||
|
blst_fp12 loop0, loop1, gt_point;
|
||||||
|
blst_p1_affine a1, b1;
|
||||||
|
blst_p2_affine a2, b2;
|
||||||
|
|
||||||
|
// As an optimisation, we want to invert one of the pairings,
|
||||||
|
// so we negate one of the points.
|
||||||
|
blst_p1 a1neg = *aa1;
|
||||||
|
blst_p1_cneg(&a1neg, true);
|
||||||
|
|
||||||
|
blst_p1_to_affine(&a1, &a1neg);
|
||||||
|
blst_p1_to_affine(&b1, bb1);
|
||||||
|
blst_p2_to_affine(&a2, aa2);
|
||||||
|
blst_p2_to_affine(&b2, bb2);
|
||||||
|
|
||||||
|
blst_miller_loop(&loop0, &a2, &a1);
|
||||||
|
blst_miller_loop(&loop1, &b2, &b1);
|
||||||
|
|
||||||
|
blst_fp12_mul(>_point, &loop0, &loop1);
|
||||||
|
blst_final_exp(>_point, >_point);
|
||||||
|
|
||||||
|
return blst_fp12_is_one(>_point);
|
||||||
|
}
|
||||||
|
|
|
@ -29,4 +29,7 @@ bool fr_equal(const blst_fr *aa, const blst_fr *bb);
|
||||||
void fr_negate(blst_fr *out, const blst_fr *in);
|
void fr_negate(blst_fr *out, const blst_fr *in);
|
||||||
void p1_mul(blst_p1 *out, const blst_p1 *a, const blst_fr *b);
|
void p1_mul(blst_p1 *out, const blst_p1 *a, const blst_fr *b);
|
||||||
void p1_sub(blst_p1 *out, const blst_p1 *a, const blst_p1 *b);
|
void p1_sub(blst_p1 *out, const blst_p1 *a, const blst_p1 *b);
|
||||||
|
void p2_mul(blst_p2 *out, const blst_p2 *a, const blst_fr *b);
|
||||||
|
void p2_sub(blst_p2 *out, const blst_p2 *a, const blst_p2 *b);
|
||||||
void linear_combination_g1(blst_p1 *out, const blst_p1 *p, const blst_fr *coeffs, const uint64_t len);
|
void linear_combination_g1(blst_p1 *out, const blst_p1 *p, const blst_fr *coeffs, const uint64_t len);
|
||||||
|
bool pairings_verify(const blst_p1 *a1, const blst_p2 *a2, const blst_p1 *b1, const blst_p2 *b2);
|
||||||
|
|
|
@ -78,6 +78,35 @@ void p1_sub_works(void) {
|
||||||
TEST_CHECK(blst_p1_is_equal(&tmp, &res));
|
TEST_CHECK(blst_p1_is_equal(&tmp, &res));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void p2_mul_works(void) {
|
||||||
|
blst_fr minus1;
|
||||||
|
blst_p2 g2_gen, g2_gen_neg, res;
|
||||||
|
|
||||||
|
// Multiply the generator by minus one (the second root of unity)
|
||||||
|
blst_p2_from_affine(&g2_gen, &BLS12_381_G2);
|
||||||
|
blst_fr_from_uint64(&minus1, m1);
|
||||||
|
p2_mul(&res, &g2_gen, &minus1);
|
||||||
|
|
||||||
|
// We should end up with negative the generator
|
||||||
|
blst_p2_from_affine(&g2_gen_neg, &BLS12_381_NEG_G2);
|
||||||
|
|
||||||
|
TEST_CHECK(blst_p2_is_equal(&res, &g2_gen_neg));
|
||||||
|
}
|
||||||
|
|
||||||
|
void p2_sub_works(void) {
|
||||||
|
blst_p2 g2_gen, g2_gen_neg;
|
||||||
|
blst_p2 tmp, res;
|
||||||
|
|
||||||
|
blst_p2_from_affine(&g2_gen, &BLS12_381_G2);
|
||||||
|
blst_p2_from_affine(&g2_gen_neg, &BLS12_381_NEG_G2);
|
||||||
|
|
||||||
|
// 2 * g2_gen = g2_gen - g2_gen_neg
|
||||||
|
blst_p2_double(&tmp, &g2_gen);
|
||||||
|
p2_sub(&res, &g2_gen, &g2_gen_neg);
|
||||||
|
|
||||||
|
TEST_CHECK(blst_p2_is_equal(&tmp, &res));
|
||||||
|
}
|
||||||
|
|
||||||
void identity_g1_is_infinity(void) {
|
void identity_g1_is_infinity(void) {
|
||||||
blst_p1 identity_g1;
|
blst_p1 identity_g1;
|
||||||
blst_p1_from_affine(&identity_g1, &identity_g1_affine);
|
blst_p1_from_affine(&identity_g1, &identity_g1_affine);
|
||||||
|
@ -103,6 +132,25 @@ void g1_linear_combination(void) {
|
||||||
TEST_CHECK(blst_p1_is_equal(&exp, &res));
|
TEST_CHECK(blst_p1_is_equal(&exp, &res));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pairings_work(void) {
|
||||||
|
// Verify that e([3]g1, [5]g2) = e([5]g1, [3]g2)
|
||||||
|
blst_fr three, five;
|
||||||
|
blst_p1 g1_3, g1_5;
|
||||||
|
blst_p2 g2_3, g2_5;
|
||||||
|
|
||||||
|
// Set up
|
||||||
|
fr_from_uint64(&three, 3);
|
||||||
|
fr_from_uint64(&five, 5);
|
||||||
|
p1_mul(&g1_3, blst_p1_generator(), &three);
|
||||||
|
p1_mul(&g1_5, blst_p1_generator(), &five);
|
||||||
|
p2_mul(&g2_3, blst_p2_generator(), &three);
|
||||||
|
p2_mul(&g2_5, blst_p2_generator(), &five);
|
||||||
|
|
||||||
|
// Verify the pairing
|
||||||
|
TEST_CHECK(true == pairings_verify(&g1_3, &g2_5, &g1_5, &g2_3));
|
||||||
|
TEST_CHECK(false == pairings_verify(&g1_3, &g2_3, &g1_5, &g2_5));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_LIST =
|
TEST_LIST =
|
||||||
{
|
{
|
||||||
{"fr_is_one_works", fr_is_one_works },
|
{"fr_is_one_works", fr_is_one_works },
|
||||||
|
@ -111,7 +159,10 @@ TEST_LIST =
|
||||||
{"fr_negate_works", fr_negate_works},
|
{"fr_negate_works", fr_negate_works},
|
||||||
{"p1_mul_works", p1_mul_works},
|
{"p1_mul_works", p1_mul_works},
|
||||||
{"p1_sub_works", p1_sub_works},
|
{"p1_sub_works", p1_sub_works},
|
||||||
|
{"p2_mul_works", p2_mul_works},
|
||||||
|
{"p2_sub_works", p2_sub_works},
|
||||||
{"identity_g1_is_infinity", identity_g1_is_infinity},
|
{"identity_g1_is_infinity", identity_g1_is_infinity},
|
||||||
{"g1_linear_combination", g1_linear_combination},
|
{"g1_linear_combination", g1_linear_combination},
|
||||||
|
{"pairings_work", pairings_work},
|
||||||
{ NULL, NULL } /* zero record marks the end of the list */
|
{ NULL, NULL } /* zero record marks the end of the list */
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue