Initial work on switch to new simplified API
This commit is contained in:
parent
db402fcdd4
commit
14d5c8e6f8
|
@ -712,7 +712,6 @@ static void free_fft_settings(FFTSettings *fs) {
|
||||||
static void free_kzg_settings(KZGSettings *ks) {
|
static void free_kzg_settings(KZGSettings *ks) {
|
||||||
free(ks->g1_values);
|
free(ks->g1_values);
|
||||||
free(ks->g2_values);
|
free(ks->g2_values);
|
||||||
ks->length = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -765,36 +764,29 @@ C_KZG_RET bytes_to_g1(g1_t* out, const uint8_t bytes[48]) {
|
||||||
return C_KZG_OK;
|
return C_KZG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uint64s_from_BLSFieldElement(uint64_t out[4], const BLSFieldElement *in) {
|
|
||||||
blst_uint64_from_fr(out, in);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bytes_from_bls_field(uint8_t out[32], const BLSFieldElement *in) {
|
void bytes_from_bls_field(uint8_t out[32], const BLSFieldElement *in) {
|
||||||
blst_scalar_from_fr((blst_scalar*)out, in);
|
blst_scalar_from_fr((blst_scalar*)out, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
C_KZG_RET load_trusted_setup(KZGSettings *out, FILE *in) {
|
C_KZG_RET load_trusted_setup(KZGSettings *out, FILE *in) {
|
||||||
uint64_t n2, i;
|
uint64_t i;
|
||||||
int j; uint8_t c[96];
|
int j; uint8_t c[96];
|
||||||
blst_p2_affine g2_affine;
|
blst_p2_affine g2_affine;
|
||||||
g1_t *g1_projective;
|
g1_t *g1_projective;
|
||||||
|
|
||||||
fscanf(in, "%" SCNu64, &out->length);
|
TRY(new_g1_array(&out->g1_values, FIELD_ELEMENTS_PER_BLOB));
|
||||||
fscanf(in, "%" SCNu64, &n2);
|
TRY(new_g2_array(&out->g2_values, FIELD_ELEMENTS_PER_BLOB));
|
||||||
|
|
||||||
TRY(new_g1_array(&out->g1_values, out->length));
|
TRY(new_g1_array(&g1_projective, FIELD_ELEMENTS_PER_BLOB));
|
||||||
TRY(new_g2_array(&out->g2_values, n2));
|
|
||||||
|
|
||||||
TRY(new_g1_array(&g1_projective, out->length));
|
for (i = 0; i < FIELD_ELEMENTS_PER_BLOB; i++) {
|
||||||
|
|
||||||
for (i = 0; i < out->length; i++) {
|
|
||||||
for (j = 0; j < 48; j++) {
|
for (j = 0; j < 48; j++) {
|
||||||
fscanf(in, "%2hhx", &c[j]);
|
fscanf(in, "%2hhx", &c[j]);
|
||||||
}
|
}
|
||||||
bytes_to_g1(&g1_projective[i], c);
|
bytes_to_g1(&g1_projective[i], c);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < n2; i++) {
|
for (i = 0; i < FIELD_ELEMENTS_PER_BLOB; i++) {
|
||||||
for (j = 0; j < 96; j++) {
|
for (j = 0; j < 96; j++) {
|
||||||
fscanf(in, "%2hhx", &c[j]);
|
fscanf(in, "%2hhx", &c[j]);
|
||||||
}
|
}
|
||||||
|
@ -802,16 +794,17 @@ C_KZG_RET load_trusted_setup(KZGSettings *out, FILE *in) {
|
||||||
blst_p2_from_affine(&out->g2_values[i], &g2_affine);
|
blst_p2_from_affine(&out->g2_values[i], &g2_affine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: precompute
|
||||||
unsigned int max_scale = 0;
|
unsigned int max_scale = 0;
|
||||||
while (((uint64_t)1 << max_scale) < out->length) max_scale++;
|
while (((uint64_t)1 << max_scale) < FIELD_ELEMENTS_PER_BLOB) max_scale++;
|
||||||
|
|
||||||
out->fs = (FFTSettings*)malloc(sizeof(FFTSettings));
|
out->fs = (FFTSettings*)malloc(sizeof(FFTSettings));
|
||||||
|
|
||||||
TRY(new_fft_settings((FFTSettings*)out->fs, max_scale));
|
TRY(new_fft_settings((FFTSettings*)out->fs, max_scale));
|
||||||
|
|
||||||
TRY(fft_g1(out->g1_values, g1_projective, true, out->length, out->fs));
|
TRY(fft_g1(out->g1_values, g1_projective, true, FIELD_ELEMENTS_PER_BLOB, out->fs));
|
||||||
|
|
||||||
TRY(reverse_bit_order(out->g1_values, sizeof(g1_t), out->length));
|
TRY(reverse_bit_order(out->g1_values, sizeof(g1_t), FIELD_ELEMENTS_PER_BLOB));
|
||||||
|
|
||||||
free(g1_projective);
|
free(g1_projective);
|
||||||
|
|
||||||
|
@ -823,10 +816,10 @@ void free_trusted_setup(KZGSettings *s) {
|
||||||
free_kzg_settings(s);
|
free_kzg_settings(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void compute_powers(fr_t out[], const fr_t *x, uint64_t n) {
|
static void compute_powers(fr_t out[], uint64_t n) {
|
||||||
uint64_t i = 0;
|
uint64_t i = 0;
|
||||||
out[i] = fr_one;
|
out[++i] = fr_one;
|
||||||
while (++i < n) fr_mul(&out[i], &out[i-1], x);
|
while (++i < n) fr_mul(&out[i], &out[i-1], &out[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bytes_to_bls_field(BLSFieldElement *out, const uint8_t bytes[32]) {
|
void bytes_to_bls_field(BLSFieldElement *out, const uint8_t bytes[32]) {
|
||||||
|
@ -835,17 +828,14 @@ void bytes_to_bls_field(BLSFieldElement *out, const uint8_t bytes[32]) {
|
||||||
blst_fr_from_scalar(out, &tmp);
|
blst_fr_from_scalar(out, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void vector_lincomb(Polynomial out, const Polynomial vectors[], const fr_t scalars[], uint64_t n) {
|
||||||
* Compute linear combinations of a sequence of vectors with some scalars
|
|
||||||
*/
|
|
||||||
void vector_lincomb(fr_t out[], const fr_t vectors[], const fr_t scalars[], uint64_t n, uint64_t m) {
|
|
||||||
fr_t tmp;
|
fr_t tmp;
|
||||||
uint64_t i, j;
|
uint64_t i, j;
|
||||||
for (j = 0; j < m; j++)
|
for (j = 0; j < FIELD_ELEMENTS_PER_BLOB; j++)
|
||||||
out[j] = fr_zero;
|
out[j] = fr_zero;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
for (j = 0; j < m; j++) {
|
for (j = 0; j < FIELD_ELEMENTS_PER_BLOB; j++) {
|
||||||
fr_mul(&tmp, &scalars[i], &vectors[i * m + j]);
|
fr_mul(&tmp, &scalars[i], &vectors[i][j]);
|
||||||
fr_add(&out[j], &out[j], &tmp);
|
fr_add(&out[j], &out[j], &tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -871,7 +861,7 @@ void vector_lincomb(fr_t out[], const fr_t vectors[], const fr_t scalars[], uint
|
||||||
*
|
*
|
||||||
* We do the second of these to save memory here.
|
* We do the second of these to save memory here.
|
||||||
*/
|
*/
|
||||||
void g1_lincomb(g1_t *out, const g1_t *p, const fr_t *coeffs, const uint64_t len) {
|
static void g1_lincomb(g1_t *out, const g1_t *p, const fr_t *coeffs, const uint64_t len) {
|
||||||
if (len < 8) { // Tunable parameter: must be at least 2 since Blst fails for 0 or 1
|
if (len < 8) { // Tunable parameter: must be at least 2 since Blst fails for 0 or 1
|
||||||
// Direct approach
|
// Direct approach
|
||||||
g1_t tmp;
|
g1_t tmp;
|
||||||
|
@ -907,8 +897,8 @@ void g1_lincomb(g1_t *out, const g1_t *p, const fr_t *coeffs, const uint64_t len
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void blob_to_kzg_commitment(KZGCommitment *out, const BLSFieldElement blob[], const KZGSettings *s) {
|
void blob_to_kzg_commitment(KZGCommitment *out, const Polynomial blob, const KZGSettings *s) {
|
||||||
g1_lincomb(out, s->g1_values, blob, s->length);
|
g1_lincomb(out, s->g1_values, blob, FIELD_ELEMENTS_PER_BLOB);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -924,8 +914,8 @@ void blob_to_kzg_commitment(KZGCommitment *out, const BLSFieldElement blob[], co
|
||||||
* @param[in] ks The settings containing the secrets, previously initialised with #new_kzg_settings
|
* @param[in] ks The settings containing the secrets, previously initialised with #new_kzg_settings
|
||||||
* @retval C_CZK_OK All is well
|
* @retval C_CZK_OK All is well
|
||||||
*/
|
*/
|
||||||
C_KZG_RET verify_kzg_proof(bool *out, const g1_t *commitment, const fr_t *x, const fr_t *y,
|
static C_KZG_RET verify_kzg_proof(bool *out, const g1_t *commitment, const fr_t *x, const fr_t *y,
|
||||||
const g1_t *proof, const KZGSettings *ks) {
|
const g1_t *proof, const KZGSettings *ks) {
|
||||||
g2_t x_g2, s_minus_x;
|
g2_t x_g2, s_minus_x;
|
||||||
g1_t y_g1, commitment_minus_y;
|
g1_t y_g1, commitment_minus_y;
|
||||||
g2_mul(&x_g2, &g2_generator, x);
|
g2_mul(&x_g2, &g2_generator, x);
|
||||||
|
@ -938,14 +928,40 @@ C_KZG_RET verify_kzg_proof(bool *out, const g1_t *commitment, const fr_t *x, con
|
||||||
return C_KZG_OK;
|
return C_KZG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
C_KZG_RET alloc_polynomial(PolynomialEvalForm *out, uint64_t length) {
|
static C_KZG_RET evaluate_polynomial_in_evaluation_form(BLSFieldElement *out, const Polynomial p, const BLSFieldElement *x, const KZGSettings *s) {
|
||||||
out->length = length;
|
fr_t tmp, *inverses_in, *inverses;
|
||||||
return new_fr_array(&out->values, length);
|
uint64_t i;
|
||||||
}
|
const fr_t *roots_of_unity = s->fs->roots_of_unity;
|
||||||
|
|
||||||
void free_polynomial(PolynomialEvalForm *p) {
|
TRY(new_fr_array(&inverses_in, FIELD_ELEMENTS_PER_BLOB));
|
||||||
p->length = 0;
|
TRY(new_fr_array(&inverses, FIELD_ELEMENTS_PER_BLOB));
|
||||||
free(p->values);
|
for (i = 0; i < FIELD_ELEMENTS_PER_BLOB; i++) {
|
||||||
|
if (fr_equal(x, &roots_of_unity[i])) {
|
||||||
|
*out = p[i];
|
||||||
|
free(inverses_in);
|
||||||
|
free(inverses);
|
||||||
|
return C_KZG_OK;
|
||||||
|
}
|
||||||
|
fr_sub(&inverses_in[i], x, &roots_of_unity[i]);
|
||||||
|
}
|
||||||
|
TRY(fr_batch_inv(inverses, inverses_in, FIELD_ELEMENTS_PER_BLOB));
|
||||||
|
|
||||||
|
*out = fr_zero;
|
||||||
|
for (i = 0; i < FIELD_ELEMENTS_PER_BLOB; i++) {
|
||||||
|
fr_mul(&tmp, &inverses[i], &roots_of_unity[i]);
|
||||||
|
fr_mul(&tmp, &tmp, &p[i]);
|
||||||
|
fr_add(out, out, &tmp);
|
||||||
|
}
|
||||||
|
fr_from_uint64(&tmp, FIELD_ELEMENTS_PER_BLOB);
|
||||||
|
fr_div(out, out, &tmp);
|
||||||
|
fr_pow(&tmp, x, FIELD_ELEMENTS_PER_BLOB);
|
||||||
|
fr_sub(&tmp, &tmp, &fr_one);
|
||||||
|
fr_mul(out, out, &tmp);
|
||||||
|
|
||||||
|
free(inverses_in);
|
||||||
|
free(inverses);
|
||||||
|
|
||||||
|
return C_KZG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -959,97 +975,142 @@ void free_polynomial(PolynomialEvalForm *p) {
|
||||||
* @retval C_KZG_ERROR An internal error occurred
|
* @retval C_KZG_ERROR An internal error occurred
|
||||||
* @retval C_KZG_MALLOC Memory allocation failed
|
* @retval C_KZG_MALLOC Memory allocation failed
|
||||||
*/
|
*/
|
||||||
C_KZG_RET compute_kzg_proof(KZGProof *out, const PolynomialEvalForm *p, const BLSFieldElement *x, const KZGSettings *s) {
|
static C_KZG_RET compute_kzg_proof(KZGProof *out, const Polynomial p, const BLSFieldElement *x, const KZGSettings *s) {
|
||||||
CHECK(p->length <= s->length);
|
|
||||||
|
|
||||||
BLSFieldElement y;
|
BLSFieldElement y;
|
||||||
TRY(evaluate_polynomial_in_evaluation_form(&y, p, x, s));
|
TRY(evaluate_polynomial_in_evaluation_form(&y, p, x, s));
|
||||||
|
|
||||||
fr_t tmp;
|
fr_t tmp;
|
||||||
PolynomialEvalForm q;
|
Polynomial q;
|
||||||
const fr_t *roots_of_unity = s->fs->roots_of_unity;
|
const fr_t *roots_of_unity = s->fs->roots_of_unity;
|
||||||
uint64_t i, m = 0;
|
uint64_t i, m = 0;
|
||||||
|
|
||||||
TRY(alloc_polynomial(&q, p->length));
|
|
||||||
|
|
||||||
fr_t *inverses_in, *inverses;
|
fr_t *inverses_in, *inverses;
|
||||||
|
|
||||||
TRY(new_fr_array(&inverses_in, p->length));
|
TRY(new_fr_array(&inverses_in, FIELD_ELEMENTS_PER_BLOB));
|
||||||
TRY(new_fr_array(&inverses, p->length));
|
TRY(new_fr_array(&inverses, FIELD_ELEMENTS_PER_BLOB));
|
||||||
|
|
||||||
for (i = 0; i < q.length; i++) {
|
for (i = 0; i < FIELD_ELEMENTS_PER_BLOB; i++) {
|
||||||
if (fr_equal(x, &roots_of_unity[i])) {
|
if (fr_equal(x, &roots_of_unity[i])) {
|
||||||
m = i + 1;
|
m = i + 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// (p_i - y) / (ω_i - x)
|
// (p_i - y) / (ω_i - x)
|
||||||
fr_sub(&q.values[i], &p->values[i], &y);
|
fr_sub(&q[i], &p[i], &y);
|
||||||
fr_sub(&inverses_in[i], &roots_of_unity[i], x);
|
fr_sub(&inverses_in[i], &roots_of_unity[i], x);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRY(fr_batch_inv(inverses, inverses_in, q.length));
|
TRY(fr_batch_inv(inverses, inverses_in, FIELD_ELEMENTS_PER_BLOB));
|
||||||
|
|
||||||
for (i = 0; i < q.length; i++) {
|
for (i = 0; i < FIELD_ELEMENTS_PER_BLOB; i++) {
|
||||||
fr_mul(&q.values[i], &q.values[i], &inverses[i]);
|
fr_mul(&q[i], &q[i], &inverses[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m) { // ω_m == x
|
if (m) { // ω_m == x
|
||||||
q.values[--m] = fr_zero;
|
q[--m] = fr_zero;
|
||||||
for (i = 0; i < q.length; i++) {
|
for (i = 0; i < FIELD_ELEMENTS_PER_BLOB; i++) {
|
||||||
if (i == m) continue;
|
if (i == m) continue;
|
||||||
// (p_i - y) * ω_i / (x * (x - ω_i))
|
// (p_i - y) * ω_i / (x * (x - ω_i))
|
||||||
fr_sub(&tmp, x, &roots_of_unity[i]);
|
fr_sub(&tmp, x, &roots_of_unity[i]);
|
||||||
fr_mul(&inverses_in[i], &tmp, x);
|
fr_mul(&inverses_in[i], &tmp, x);
|
||||||
}
|
}
|
||||||
TRY(fr_batch_inv(inverses, inverses_in, q.length));
|
TRY(fr_batch_inv(inverses, inverses_in, FIELD_ELEMENTS_PER_BLOB));
|
||||||
for (i = 0; i < q.length; i++) {
|
for (i = 0; i < FIELD_ELEMENTS_PER_BLOB; i++) {
|
||||||
fr_sub(&tmp, &p->values[i], &y);
|
fr_sub(&tmp, &p[i], &y);
|
||||||
fr_mul(&tmp, &tmp, &roots_of_unity[i]);
|
fr_mul(&tmp, &tmp, &roots_of_unity[i]);
|
||||||
fr_mul(&tmp, &tmp, &inverses[i]);
|
fr_mul(&tmp, &tmp, &inverses[i]);
|
||||||
fr_add(&q.values[m], &q.values[m], &tmp);
|
fr_add(&q[m], &q[m], &tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(inverses_in);
|
free(inverses_in);
|
||||||
free(inverses);
|
free(inverses);
|
||||||
|
|
||||||
g1_lincomb(out, s->g1_values, q.values, q.length);
|
g1_lincomb(out, s->g1_values, q, FIELD_ELEMENTS_PER_BLOB);
|
||||||
|
|
||||||
return C_KZG_OK;
|
return C_KZG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
C_KZG_RET evaluate_polynomial_in_evaluation_form(BLSFieldElement *out, const PolynomialEvalForm *p, const BLSFieldElement *x, const KZGSettings *s) {
|
typedef struct {
|
||||||
fr_t tmp, *inverses_in, *inverses;
|
unsigned int h[8];
|
||||||
uint64_t i;
|
unsigned long long N;
|
||||||
const fr_t *roots_of_unity = s->fs->roots_of_unity;
|
unsigned char buf[64];
|
||||||
|
size_t off;
|
||||||
|
} SHA256_CTX;
|
||||||
|
|
||||||
TRY(new_fr_array(&inverses_in, p->length));
|
extern void sha256_init(SHA256_CTX *ctx);
|
||||||
TRY(new_fr_array(&inverses, p->length));
|
extern void sha256_update(SHA256_CTX *ctx, const void *_inp, size_t len);
|
||||||
for (i = 0; i < p->length; i++) {
|
extern void sha256_final(unsigned char md[32], SHA256_CTX *ctx);
|
||||||
if (fr_equal(x, &roots_of_unity[i])) {
|
|
||||||
*out = p->values[i];
|
|
||||||
free(inverses_in);
|
|
||||||
free(inverses);
|
|
||||||
return C_KZG_OK;
|
|
||||||
}
|
|
||||||
fr_sub(&inverses_in[i], x, &roots_of_unity[i]);
|
|
||||||
}
|
|
||||||
TRY(fr_batch_inv(inverses, inverses_in, p->length));
|
|
||||||
|
|
||||||
*out = fr_zero;
|
static void hash(uint8_t md[32], uint8_t input[], size_t n) {
|
||||||
for (i = 0; i < p->length; i++) {
|
SHA256_CTX ctx;
|
||||||
fr_mul(&tmp, &inverses[i], &roots_of_unity[i]);
|
sha256_init(&ctx);
|
||||||
fr_mul(&tmp, &tmp, &p->values[i]);
|
sha256_update(&ctx, input, n);
|
||||||
fr_add(out, out, &tmp);
|
sha256_final(md, &ctx);
|
||||||
}
|
}
|
||||||
fr_from_uint64(&tmp, p->length);
|
|
||||||
fr_div(out, out, &tmp);
|
static void hash_to_bls_field(BLSFieldElement *out, const Polynomial polys[], const KZGCommitment comms[], size_t n) {
|
||||||
fr_pow(&tmp, x, p->length);
|
size_t i, np = n * FIELD_ELEMENTS_PER_BLOB * 32;
|
||||||
fr_sub(&tmp, &tmp, &fr_one);
|
uint64_t j; uint8_t h[32];
|
||||||
fr_mul(out, out, &tmp);
|
|
||||||
|
uint8_t bytes[np + n * 48];
|
||||||
free(inverses_in);
|
|
||||||
free(inverses);
|
for(i = 0; i < n; i++)
|
||||||
|
for(j = 0; j < FIELD_ELEMENTS_PER_BLOB; j++)
|
||||||
return C_KZG_OK;
|
bytes_from_bls_field(&bytes[i * 32], &polys[i][j]);
|
||||||
|
|
||||||
|
for(i = 0; i < n; i++)
|
||||||
|
bytes_from_g1(&bytes[np + i * 48], &comms[i]);
|
||||||
|
|
||||||
|
hash(h, bytes, np + n * 48);
|
||||||
|
|
||||||
|
bytes_to_bls_field(out, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void compute_aggregated_poly_and_commitment(Polynomial poly_out, KZGCommitment *comm_out,
|
||||||
|
const Polynomial blobs[],
|
||||||
|
const KZGCommitment kzg_commitments[],
|
||||||
|
size_t n) {
|
||||||
|
BLSFieldElement r_powers[n];
|
||||||
|
|
||||||
|
hash_to_bls_field(&r_powers[1], blobs, kzg_commitments, n);
|
||||||
|
|
||||||
|
compute_powers(r_powers, n);
|
||||||
|
|
||||||
|
vector_lincomb(poly_out, blobs, r_powers, n);
|
||||||
|
|
||||||
|
g1_lincomb(comm_out, kzg_commitments, r_powers, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
C_KZG_RET compute_aggregate_kzg_proof(KZGProof *out,
|
||||||
|
const Polynomial blobs[],
|
||||||
|
size_t n,
|
||||||
|
const KZGSettings *s) {
|
||||||
|
KZGCommitment commitments[n];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < n; i++)
|
||||||
|
blob_to_kzg_commitment(&commitments[i], blobs[i], s);
|
||||||
|
|
||||||
|
Polynomial aggregated_poly;
|
||||||
|
KZGCommitment aggregated_poly_commitment;
|
||||||
|
compute_aggregated_poly_and_commitment(aggregated_poly, &aggregated_poly_commitment, blobs, commitments, n);
|
||||||
|
|
||||||
|
BLSFieldElement x;
|
||||||
|
hash_to_bls_field(&x, &aggregated_poly, &aggregated_poly_commitment, 1);
|
||||||
|
|
||||||
|
return compute_kzg_proof(out, aggregated_poly, &x, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
C_KZG_RET verify_aggregate_kzg_proof(bool *out,
|
||||||
|
const Polynomial blobs[],
|
||||||
|
const KZGCommitment expected_kzg_commitments[],
|
||||||
|
size_t n,
|
||||||
|
const KZGProof *kzg_aggregated_proof,
|
||||||
|
const KZGSettings *s) {
|
||||||
|
Polynomial aggregated_poly;
|
||||||
|
KZGCommitment aggregated_poly_commitment;
|
||||||
|
compute_aggregated_poly_and_commitment(aggregated_poly, &aggregated_poly_commitment, blobs, expected_kzg_commitments, n);
|
||||||
|
BLSFieldElement x, y;
|
||||||
|
hash_to_bls_field(&x, &aggregated_poly, &aggregated_poly_commitment, 1);
|
||||||
|
TRY(evaluate_polynomial_in_evaluation_form(&y, aggregated_poly, &x, s));
|
||||||
|
return verify_kzg_proof(out, &aggregated_poly_commitment, &x, &y, kzg_aggregated_proof, s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
#include "blst.h"
|
#include "blst.h"
|
||||||
|
|
||||||
|
#define FIELD_ELEMENTS_PER_BLOB 4096
|
||||||
|
|
||||||
typedef blst_p1 g1_t; /**< Internal G1 group element type */
|
typedef blst_p1 g1_t; /**< Internal G1 group element type */
|
||||||
typedef blst_p2 g2_t; /**< Internal G2 group element type */
|
typedef blst_p2 g2_t; /**< Internal G2 group element type */
|
||||||
typedef blst_fr fr_t; /**< Internal Fr field element type */
|
typedef blst_fr fr_t; /**< Internal Fr field element type */
|
||||||
|
@ -36,6 +38,7 @@ typedef blst_fr fr_t; /**< Internal Fr field element type */
|
||||||
typedef g1_t KZGCommitment;
|
typedef g1_t KZGCommitment;
|
||||||
typedef g1_t KZGProof;
|
typedef g1_t KZGProof;
|
||||||
typedef fr_t BLSFieldElement;
|
typedef fr_t BLSFieldElement;
|
||||||
|
typedef BLSFieldElement Polynomial[FIELD_ELEMENTS_PER_BLOB];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The common return type for all routines in which something can go wrong.
|
* The common return type for all routines in which something can go wrong.
|
||||||
|
@ -58,14 +61,10 @@ void bytes_from_g1(uint8_t out[48], const g1_t*);
|
||||||
C_KZG_RET bytes_to_g1(g1_t* out, const uint8_t[48]);
|
C_KZG_RET bytes_to_g1(g1_t* out, const uint8_t[48]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BLSFieldElements are communicated directly to/from clients,
|
* BLSFieldElements can be recovered as 32 bytes
|
||||||
* so we need to expose the functions for translating between this
|
|
||||||
* type and uint256. BLST represents uint256 as uint64[4].
|
|
||||||
* TODO: remove the uint64s version?
|
|
||||||
* For conversion to BLSFieldElement use bytes_to_bls_field.
|
|
||||||
*/
|
*/
|
||||||
void uint64s_from_BLSFieldElement(uint64_t out[4], const BLSFieldElement*);
|
|
||||||
void bytes_from_bls_field(uint8_t out[32], const BLSFieldElement*);
|
void bytes_from_bls_field(uint8_t out[32], const BLSFieldElement*);
|
||||||
|
void bytes_to_bls_field(BLSFieldElement *out, const uint8_t bytes[32]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the setup and parameters needed for performing FFTs.
|
* Stores the setup and parameters needed for performing FFTs.
|
||||||
|
@ -83,44 +82,33 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const FFTSettings *fs; /**< The corresponding settings for performing FFTs */
|
const FFTSettings *fs; /**< The corresponding settings for performing FFTs */
|
||||||
g1_t *g1_values; /**< G1 group elements from the trusted setup, in Lagrange form bit-reversal permutation */
|
g1_t *g1_values; /**< G1 group elements from the trusted setup, in Lagrange form bit-reversal permutation */
|
||||||
g2_t *g2_values; /**< G2 group elements from the trusted setup */
|
g2_t *g2_values; /**< G2 group elements from the trusted setup; both arrays have FIELD_ELEMENTS_PER_BLOB elements */
|
||||||
uint64_t length; /**< The number of elements in g1_values */
|
|
||||||
} KZGSettings;
|
} KZGSettings;
|
||||||
|
|
||||||
/**
|
|
||||||
* Lagrange form polynomial, with values under the bit-reversal permutation
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
fr_t *values; /**< `values[i]` is value of the polynomial at `ω^brp(i)` */
|
|
||||||
uint64_t length; /**< One more than the polynomial's degree */
|
|
||||||
} PolynomialEvalForm;
|
|
||||||
|
|
||||||
C_KZG_RET alloc_polynomial(PolynomialEvalForm *out, uint64_t length);
|
|
||||||
void free_polynomial(PolynomialEvalForm *p);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface functions
|
* Interface functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
C_KZG_RET load_trusted_setup(KZGSettings *out, FILE *in);
|
C_KZG_RET load_trusted_setup(KZGSettings *out,
|
||||||
|
FILE *in);
|
||||||
|
|
||||||
void free_trusted_setup(KZGSettings *s);
|
void free_trusted_setup(
|
||||||
|
KZGSettings *s);
|
||||||
|
|
||||||
void bytes_to_bls_field(BLSFieldElement *out, const uint8_t bytes[32]);
|
C_KZG_RET compute_aggregate_kzg_proof(KZGProof *out,
|
||||||
|
const Polynomial blobs[],
|
||||||
|
size_t n,
|
||||||
|
const KZGSettings *s);
|
||||||
|
|
||||||
void vector_lincomb(BLSFieldElement out[], const BLSFieldElement vectors[], const BLSFieldElement scalars[], uint64_t num_vectors, uint64_t vector_len);
|
C_KZG_RET verify_aggregate_kzg_proof(bool *out,
|
||||||
|
const Polynomial blobs[],
|
||||||
|
const KZGCommitment expected_kzg_commitments[],
|
||||||
|
size_t n,
|
||||||
|
const KZGProof *kzg_aggregated_proof,
|
||||||
|
const KZGSettings *s);
|
||||||
|
|
||||||
void g1_lincomb(KZGCommitment *out, const KZGCommitment points[], const BLSFieldElement scalars[], uint64_t num_points);
|
void blob_to_kzg_commitment(KZGCommitment *out,
|
||||||
|
const Polynomial blob,
|
||||||
void blob_to_kzg_commitment(KZGCommitment *out, const BLSFieldElement blob[], const KZGSettings *s);
|
const KZGSettings *s);
|
||||||
|
|
||||||
C_KZG_RET verify_kzg_proof(bool *out, const KZGCommitment *polynomial_kzg, const BLSFieldElement *z, const BLSFieldElement *y, const KZGProof *kzg_proof, const KZGSettings *s);
|
|
||||||
|
|
||||||
C_KZG_RET compute_kzg_proof(KZGProof *out, const PolynomialEvalForm *polynomial, const BLSFieldElement *z, const KZGSettings *s);
|
|
||||||
|
|
||||||
C_KZG_RET evaluate_polynomial_in_evaluation_form(BLSFieldElement *out, const PolynomialEvalForm *polynomial, const BLSFieldElement *z, const KZGSettings *s);
|
|
||||||
|
|
||||||
void compute_powers(BLSFieldElement out[], const BLSFieldElement *x, uint64_t n);
|
|
||||||
|
|
||||||
#endif // C_KZG_4844_H
|
#endif // C_KZG_4844_H
|
||||||
|
|
Loading…
Reference in New Issue