From 0861520a7ed0fa0ae59a69db7891ace8bc7a8eaf Mon Sep 17 00:00:00 2001 From: Dankrad Feist Date: Thu, 15 Sep 2022 18:38:29 +0100 Subject: [PATCH] Test for proofs computed in Lagrange form --- src/kzg_proofs.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/kzg_proofs.c b/src/kzg_proofs.c index 00ccda6..cef5d0d 100644 --- a/src/kzg_proofs.c +++ b/src/kzg_proofs.c @@ -91,6 +91,7 @@ C_KZG_RET check_proof_single(bool *out, const g1_t *commitment, const g1_t *proo return C_KZG_OK; } +// TODO: I don't think this should compute the evaluation. Instead y should be a parameter C_KZG_RET compute_proof_single_l(g1_t *out, const poly_l *p, const fr_t *x0, const KZGSettings *ks) { fr_t y, tmp, tmp2; poly_l q; @@ -99,11 +100,11 @@ C_KZG_RET compute_proof_single_l(g1_t *out, const poly_l *p, const fr_t *x0, con eval_poly_l(&y, p, x0, ks->fs); new_poly_l(&q, p->length); - for (i = 0; i < q->length; i++) { + for (i = 0; i < q.length; i++) { // (p_i - y) / (ω_i - x0) fr_sub(&tmp, &p->values[i], &y); fr_sub(&tmp2, &ks->fs->expanded_roots_of_unity[i], x0); - fr_div(&q->values[i], &tmp, &tmp2); + fr_div(&q.values[i], &tmp, &tmp2); } return commit_to_poly_l(out, &q, ks); @@ -318,6 +319,58 @@ void proof_single(void) { free_poly(&p); } +void proof_single_l(void) { + // Our polynomial: degree 15, 16 coefficients + uint64_t coeffs[] = {1, 2, 3, 4, 7, 7, 7, 7, 13, 13, 13, 13, 13, 13, 13, 13}; + int poly_len = sizeof coeffs / sizeof coeffs[0]; + uint64_t secrets_len = poly_len; + + FFTSettings fs; + KZGSettings ks; + g1_t s1[secrets_len]; + g2_t s2[secrets_len]; + poly p; + poly_l p_l; + g1_t commitment, proof; + fr_t x, value; + bool result; + + // Create the polynomial + new_poly(&p, poly_len); + for (int i = 0; i < poly_len; i++) { + fr_from_uint64(&p.coeffs[i], coeffs[i]); + } + + // Initialise the secrets and data structures + generate_trusted_setup(s1, s2, &secret, secrets_len); + TEST_CHECK(C_KZG_OK == new_fft_settings(&fs, 4)); // ln_2 of poly_len + TEST_CHECK(C_KZG_OK == new_kzg_settings(&ks, s1, s2, secrets_len, &fs)); + + // Create Lagrange form + new_poly_l_from_poly(&p_l, &p, &ks); + + // Compute the proof for x = 25 + fr_from_uint64(&x, 25); + TEST_CHECK(C_KZG_OK == commit_to_poly_l(&commitment, &p_l, &ks)); + TEST_CHECK(C_KZG_OK == compute_proof_single_l(&proof, &p_l, &x, &ks)); + + eval_poly_l(&value, &p_l, &x, &fs); + + // Verify the proof that the (unknown) polynomial has y = value at x = 25 + TEST_CHECK(C_KZG_OK == check_proof_single(&result, &commitment, &proof, &x, &value, &ks)); + TEST_CHECK(true == result); + + // Change the value and check that the proof fails + fr_add(&value, &value, &fr_one); + TEST_CHECK(C_KZG_OK == check_proof_single(&result, &commitment, &proof, &x, &value, &ks)); + TEST_CHECK(false == result); + + free_fft_settings(&fs); + free_kzg_settings(&ks); + free_poly(&p); + free_poly_l(&p_l); +} + void proof_multi(void) { // Our polynomial: degree 15, 16 coefficients uint64_t coeffs[] = {1, 2, 3, 4, 7, 7, 7, 7, 13, 13, 13, 13, 13, 13, 13, 13};