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 */
|
uint64_t length; /**< One more than the polynomial's degree */
|
||||||
} poly;
|
} 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);
|
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_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);
|
||||||
|
@ -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(poly *out, uint64_t length);
|
||||||
C_KZG_RET new_poly_with_coeffs(poly *out, const fr_t *coeffs, 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(poly *p);
|
||||||
|
void free_poly_l(poly_l *p);
|
||||||
|
|
||||||
//
|
//
|
||||||
// kzg_proofs.c
|
// kzg_proofs.c
|
||||||
|
@ -107,11 +113,15 @@ void free_poly(poly *p);
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const FFTSettings *fs; /**< The corresponding settings for performing FFTs */
|
const FFTSettings *fs; /**< The corresponding settings for performing FFTs */
|
||||||
g1_t *secret_g1; /**< G1 group elements from the trusted setup */
|
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 */
|
g2_t *secret_g2; /**< G2 group elements from the trusted setup */
|
||||||
uint64_t length; /**< The number of elements in secret_g1 and secret_g2 */
|
uint64_t length; /**< The number of elements in secret_g1 and secret_g2 */
|
||||||
} KZGSettings;
|
} 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(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 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,
|
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);
|
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;
|
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.
|
* 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
|
// Allocate space for the secrets
|
||||||
TRY(new_g1_array(&ks->secret_g1, ks->length));
|
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));
|
TRY(new_g2_array(&ks->secret_g2, ks->length));
|
||||||
|
|
||||||
// Populate the secrets
|
// 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;
|
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) {
|
void free_kzg_settings(KZGSettings *ks) {
|
||||||
free(ks->secret_g1);
|
free(ks->secret_g1);
|
||||||
|
free(ks->secret_g1_l);
|
||||||
free(ks->secret_g2);
|
free(ks->secret_g2);
|
||||||
ks->length = 0;
|
ks->length = 0;
|
||||||
}
|
}
|
||||||
|
@ -393,12 +402,54 @@ void commit_to_too_long_poly(void) {
|
||||||
free_kzg_settings(&ks);
|
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 = {
|
TEST_LIST = {
|
||||||
{"KZG_PROOFS_TEST", title},
|
{"KZG_PROOFS_TEST", title},
|
||||||
{"proof_single", proof_single},
|
{"proof_single", proof_single},
|
||||||
{"proof_multi", proof_multi},
|
{"proof_multi", proof_multi},
|
||||||
{"commit_to_nil_poly", commit_to_nil_poly},
|
{"commit_to_nil_poly", commit_to_nil_poly},
|
||||||
{"commit_to_too_long_poly", commit_to_too_long_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 */
|
{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);
|
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.
|
* 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;
|
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.
|
* 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
|
#ifdef KZGTEST
|
||||||
|
|
||||||
#include "../inc/acutest.h"
|
#include "../inc/acutest.h"
|
||||||
|
|
Loading…
Reference in New Issue