Add evaluation of Lagrange poly

This commit is contained in:
Ramana Kumar 2022-09-15 18:09:10 +01:00
parent 56e0769ce4
commit 15f2b9eef9
No known key found for this signature in database
GPG Key ID: ED471C788B900433
3 changed files with 77 additions and 1 deletions

View File

@ -92,6 +92,7 @@ typedef struct {
} poly_l; // Lagrange form
void eval_poly(fr_t *out, const poly *p, const fr_t *x);
void eval_poly_l(fr_t *out, const poly_l *p, const fr_t *x, const FFTSettings *fs);
C_KZG_RET poly_inverse(poly *out, poly *b);
C_KZG_RET poly_mul(poly *out, const poly *a, const poly *b);
C_KZG_RET poly_mul_(poly *out, const poly *a, const poly *b, FFTSettings *fs);

View File

@ -443,8 +443,46 @@ void commit_to_poly_lagrange(void) {
free_poly_l(&p_l);
}
void poly_eval_l_check(void) {
uint64_t n = 10;
fr_t actual, expected;
poly p;
new_poly(&p, n);
for (uint64_t i = 0; i < n; i++) {
fr_from_uint64(&p.coeffs[i], i + 1);
}
fr_t x;
fr_from_uint64(&x, 39);
// x = fr_one;
eval_poly(&expected, &p, &x);
poly_l p_l;
FFTSettings fs;
KZGSettings ks;
uint64_t secrets_len = 16;
g1_t s1[secrets_len];
g2_t s2[secrets_len];
g1_t result;
generate_trusted_setup(s1, s2, &secret, secrets_len);
TEST_CHECK(C_KZG_OK == new_fft_settings(&fs, 4)); // log_2(secrets_len)
TEST_CHECK(C_KZG_OK == new_kzg_settings(&ks, s1, s2, secrets_len, &fs));
TEST_CHECK(C_KZG_OK == new_poly_l_from_poly(&p_l, &p, &ks));
eval_poly_l(&actual, &p_l, &x, &fs);
TEST_CHECK(fr_equal(&expected, &actual));
free_fft_settings(&fs);
free_kzg_settings(&ks);
free_poly(&p);
free_poly_l(&p_l);
}
TEST_LIST = {
{"KZG_PROOFS_TEST", title},
{"poly_eval_l_check", poly_eval_l_check},
{"proof_single", proof_single},
{"proof_multi", proof_multi},
{"commit_to_nil_poly", commit_to_nil_poly},

View File

@ -102,6 +102,29 @@ void eval_poly(fr_t *out, const poly *p, const fr_t *x) {
}
}
// TODO: optimize via batch inversion
void eval_poly_l(fr_t *out, const poly_l *p, const fr_t *x, const FFTSettings *fs) {
fr_t tmp, tmp2, tmp3;
uint64_t i;
const uint64_t stride = fs->max_width / p->length;
*out = fr_zero;
for (i = 0; i < p->length; i++) {
fr_sub(&tmp, x, &fs->expanded_roots_of_unity[i * stride]);
fr_inv(&tmp2, &tmp);
fr_mul(&tmp, &tmp2, &fs->expanded_roots_of_unity[i * stride]);
fr_mul(&tmp2, &tmp, &p->values[i]);
fr_add(out, out, &tmp2);
}
fr_negate(&tmp3, &fr_one);
fr_pow(&tmp2, x, p->length);
fr_sub(&tmp, &tmp2, &fr_one);
fr_from_uint64(&tmp2, p->length);
fr_div(&tmp3, &tmp, &tmp2);
tmp2 = *out;
fr_mul(out, &tmp2, &tmp3);
}
/**
* Polynomial division in the finite field via long division.
*
@ -569,7 +592,21 @@ C_KZG_RET new_poly_with_coeffs(poly *out, const fr_t *coeffs, uint64_t length) {
C_KZG_RET new_poly_l_from_poly(poly_l *out, const poly *in, const KZGSettings *ks) {
TRY(new_poly_l(out, ks->length));
return fft_fr(out->values, in->coeffs, false, out->length, ks->fs);
if (out->length <= in->length) {
return fft_fr(out->values, in->coeffs, false, out->length, ks->fs);
}
else {
int i;
fr_t *coeffs;
TRY(new_fr_array(&coeffs, out->length));
for (i = 0; i < in->length; i++) {
coeffs[i] = in->coeffs[i];
}
for (; i < out->length; i++) {
coeffs[i] = fr_zero;
}
return fft_fr(out->values, coeffs, false, out->length, ks->fs);
}
}
/**