Add Lagrange form, with a test
This commit is contained in:
parent
6b5140af66
commit
56e0769ce4
10
src/c_kzg.h
10
src/c_kzg.h
|
@ -86,6 +86,11 @@ typedef struct {
|
|||
uint64_t length; /**< One more than the polynomial's degree */
|
||||
} poly;
|
||||
|
||||
typedef struct {
|
||||
fr_t *values; /**< `values[i]` is value of the polynomial at `ω^i`. */
|
||||
uint64_t length; /**< One more than the polynomial's degree */
|
||||
} poly_l; // Lagrange form
|
||||
|
||||
void eval_poly(fr_t *out, const poly *p, const fr_t *x);
|
||||
C_KZG_RET poly_inverse(poly *out, poly *b);
|
||||
C_KZG_RET poly_mul(poly *out, const poly *a, const poly *b);
|
||||
|
@ -94,6 +99,7 @@ C_KZG_RET new_poly_div(poly *out, const poly *dividend, const poly *divisor);
|
|||
C_KZG_RET new_poly(poly *out, uint64_t length);
|
||||
C_KZG_RET new_poly_with_coeffs(poly *out, const fr_t *coeffs, uint64_t length);
|
||||
void free_poly(poly *p);
|
||||
void free_poly_l(poly_l *p);
|
||||
|
||||
//
|
||||
// kzg_proofs.c
|
||||
|
@ -107,11 +113,15 @@ void free_poly(poly *p);
|
|||
typedef struct {
|
||||
const FFTSettings *fs; /**< The corresponding settings for performing FFTs */
|
||||
g1_t *secret_g1; /**< G1 group elements from the trusted setup */
|
||||
g1_t *secret_g1_l; /**< secret_g1 in Lagrange form */
|
||||
g2_t *secret_g2; /**< G2 group elements from the trusted setup */
|
||||
uint64_t length; /**< The number of elements in secret_g1 and secret_g2 */
|
||||
} KZGSettings;
|
||||
|
||||
C_KZG_RET new_poly_l_from_poly(poly_l *out, const poly *in, const KZGSettings *ks);
|
||||
|
||||
C_KZG_RET commit_to_poly(g1_t *out, const poly *p, const KZGSettings *ks);
|
||||
C_KZG_RET commit_to_poly_l(g1_t *out, const poly_l *p, const KZGSettings *ks);
|
||||
C_KZG_RET compute_proof_single(g1_t *out, const poly *p, const fr_t *x0, const KZGSettings *ks);
|
||||
C_KZG_RET check_proof_single(bool *out, const g1_t *commitment, const g1_t *proof, const fr_t *x, fr_t *y,
|
||||
const KZGSettings *ks);
|
||||
|
|
|
@ -43,6 +43,12 @@ C_KZG_RET commit_to_poly(g1_t *out, const poly *p, const KZGSettings *ks) {
|
|||
return C_KZG_OK;
|
||||
}
|
||||
|
||||
C_KZG_RET commit_to_poly_l(g1_t *out, const poly_l *p_l, const KZGSettings *ks) {
|
||||
CHECK(p_l->length <= ks->length);
|
||||
g1_linear_combination(out, ks->secret_g1_l, p_l->values, p_l->length);
|
||||
return C_KZG_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute KZG proof for polynomial at position x0.
|
||||
*
|
||||
|
@ -216,6 +222,7 @@ C_KZG_RET new_kzg_settings(KZGSettings *ks, const g1_t *secret_g1, const g2_t *s
|
|||
|
||||
// Allocate space for the secrets
|
||||
TRY(new_g1_array(&ks->secret_g1, ks->length));
|
||||
TRY(new_g1_array(&ks->secret_g1_l, ks->length));
|
||||
TRY(new_g2_array(&ks->secret_g2, ks->length));
|
||||
|
||||
// Populate the secrets
|
||||
|
@ -225,7 +232,8 @@ C_KZG_RET new_kzg_settings(KZGSettings *ks, const g1_t *secret_g1, const g2_t *s
|
|||
}
|
||||
ks->fs = fs;
|
||||
|
||||
return C_KZG_OK;
|
||||
// Add Lagrange form (and return its success)
|
||||
return fft_g1(ks->secret_g1_l, ks->secret_g1, true, length, fs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -235,6 +243,7 @@ C_KZG_RET new_kzg_settings(KZGSettings *ks, const g1_t *secret_g1, const g2_t *s
|
|||
*/
|
||||
void free_kzg_settings(KZGSettings *ks) {
|
||||
free(ks->secret_g1);
|
||||
free(ks->secret_g1_l);
|
||||
free(ks->secret_g2);
|
||||
ks->length = 0;
|
||||
}
|
||||
|
@ -393,12 +402,54 @@ void commit_to_too_long_poly(void) {
|
|||
free_kzg_settings(&ks);
|
||||
}
|
||||
|
||||
void commit_to_poly_lagrange(void) {
|
||||
// Our polynomial: degree 15, 16 coefficients
|
||||
uint64_t coeffs[] = {12, 2, 8, 4, 7, 9, 1337, 227, 3, 13, 13, 130, 13, 13111, 13, 12223};
|
||||
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, commitment_l;
|
||||
|
||||
// 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 commitments
|
||||
TEST_CHECK(C_KZG_OK == commit_to_poly(&commitment, &p, &ks));
|
||||
TEST_CHECK(C_KZG_OK == commit_to_poly_l(&commitment_l, &p_l, &ks));
|
||||
|
||||
// Check commitments are equal
|
||||
TEST_CHECK(g1_equal(&commitment, &commitment_l));
|
||||
|
||||
free_fft_settings(&fs);
|
||||
free_kzg_settings(&ks);
|
||||
free_poly(&p);
|
||||
free_poly_l(&p_l);
|
||||
}
|
||||
|
||||
TEST_LIST = {
|
||||
{"KZG_PROOFS_TEST", title},
|
||||
{"proof_single", proof_single},
|
||||
{"proof_multi", proof_multi},
|
||||
{"commit_to_nil_poly", commit_to_nil_poly},
|
||||
{"commit_to_too_long_poly", commit_to_too_long_poly},
|
||||
{"commit_to_poly_lagrange", commit_to_poly_lagrange},
|
||||
{NULL, NULL} /* zero record marks the end of the list */
|
||||
};
|
||||
|
||||
|
|
16
src/poly.c
16
src/poly.c
|
@ -541,6 +541,11 @@ C_KZG_RET new_poly(poly *out, uint64_t length) {
|
|||
return new_fr_array(&out->coeffs, length);
|
||||
}
|
||||
|
||||
C_KZG_RET new_poly_l(poly_l *out, uint64_t length) {
|
||||
out->length = length;
|
||||
return new_fr_array(&out->values, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise a polynomial of the given size with the given coefficients.
|
||||
*
|
||||
|
@ -562,6 +567,11 @@ C_KZG_RET new_poly_with_coeffs(poly *out, const fr_t *coeffs, uint64_t length) {
|
|||
return C_KZG_OK;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reclaim the memory used by a polynomial.
|
||||
*
|
||||
|
@ -576,6 +586,12 @@ void free_poly(poly *p) {
|
|||
}
|
||||
}
|
||||
|
||||
void free_poly_l(poly_l *p) {
|
||||
if (p->values != NULL) {
|
||||
free(p->values);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KZGTEST
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
|
|
Loading…
Reference in New Issue