Implement polynomial multi proofs

This commit is contained in:
Ben Edgington 2021-02-05 20:48:56 +00:00
parent 1ab4d08861
commit 6242338bd8
17 changed files with 352 additions and 233 deletions

View File

@ -7,7 +7,8 @@ Initially, at least, this largely follows the [go-kzg](https://github.com/protol
Done so far:
- FFT and inverse FFT over the finite field.
- FFTs over the G1 group
- Single polynomial commitment and verification
- Polynomial single commitment and verification
- Polynomial multi commitment and verification
## Installation

View File

@ -1,7 +1,6 @@
TESTS = blst_util_test fft_common_test fft_fr_test fft_g1_test \
kzg_single_proofs_test poly_test
LIB_SRC = blst_util.c fft_common.c fft_fr.c fft_g1.c kzg_common.c \
kzg_single_proofs.c poly.c
kzg_proofs_test poly_test
LIB_SRC = blst_util.c fft_common.c fft_fr.c fft_g1.c kzg_proofs.c poly.c
LIB_OBJ = $(LIB_SRC:.c=.o)
CFLAGS =

View File

@ -47,6 +47,19 @@ void fr_negate(blst_fr *out, const blst_fr *in) {
blst_fr_cneg(out, in, true);
}
void fr_pow(blst_fr *out, const blst_fr *a, uint64_t n) {
blst_fr tmp = *a;
*out = fr_one;
while (true) {
if (n & 1) {
blst_fr_mul(out, out, &tmp);
}
if ((n >>= 1) == 0) break;
blst_fr_sqr(&tmp, &tmp);
}
}
// TODO: Is there really no better way to do this?
void p1_mul(blst_p1 *out, const blst_p1 *a, const blst_fr *b) {
blst_scalar s;

View File

@ -30,6 +30,7 @@ bool fr_is_one(const blst_fr *p);
void fr_from_uint64(blst_fr *a, const uint64_t n);
bool fr_equal(const blst_fr *aa, const blst_fr *bb);
void fr_negate(blst_fr *out, const blst_fr *in);
void fr_pow(blst_fr *out, const blst_fr *a, const uint64_t n);
void p1_mul(blst_p1 *out, const blst_p1 *a, const blst_fr *b);
void p1_sub(blst_p1 *out, const blst_p1 *a, const blst_p1 *b);
void p2_mul(blst_p2 *out, const blst_p2 *a, const blst_fr *b);

View File

@ -57,6 +57,24 @@ void fr_negate_works(void) {
TEST_CHECK(fr_is_one(&res));
}
void fr_pow_works(void) {
// a^pow
uint64_t pow = 123456;
blst_fr a, expected, actual;
fr_from_uint64(&a, 197);
// Do it the slow way
expected = fr_one;
for (uint64_t i = 0; i < pow; i++) {
blst_fr_mul(&expected, &expected, &a);
}
// Do it the quick way
fr_pow(&actual, &a, pow);
TEST_CHECK(fr_equal(&expected, &actual));
}
void p1_mul_works(void) {
blst_fr minus1;
blst_p1 g1_gen, g1_gen_neg, res;
@ -167,6 +185,7 @@ TEST_LIST =
{"fr_from_uint64_works", fr_from_uint64_works},
{"fr_equal_works", fr_equal_works},
{"fr_negate_works", fr_negate_works},
{"fr_pow_works", fr_pow_works},
{"p1_mul_works", p1_mul_works},
{"p1_sub_works", p1_sub_works},
{"p2_mul_works", p2_mul_works},

View File

@ -18,7 +18,7 @@
#include "blst_util.h"
// Slow Fourier Transform (simple, good for small sizes)
void fft_fr_slow(blst_fr *out, blst_fr *in, uint64_t stride, blst_fr *roots, uint64_t roots_stride, uint64_t l) {
void fft_fr_slow(blst_fr *out, const blst_fr *in, uint64_t stride, const blst_fr *roots, uint64_t roots_stride, uint64_t l) {
blst_fr v, last, jv, r;
for (uint64_t i = 0; i < l; i++) {
blst_fr_mul(&last, &in[0], &roots[0]);
@ -33,7 +33,7 @@ void fft_fr_slow(blst_fr *out, blst_fr *in, uint64_t stride, blst_fr *roots, uin
}
// Fast Fourier Transform
void fft_fr_fast(blst_fr *out, blst_fr *in, uint64_t stride, blst_fr *roots, uint64_t roots_stride, uint64_t l) {
void fft_fr_fast(blst_fr *out, const blst_fr *in, uint64_t stride, const blst_fr *roots, uint64_t roots_stride, uint64_t l) {
uint64_t half = l / 2;
if (half > 2) { // TODO: Tunable parameter
fft_fr_fast(out, in, stride * 2, roots, roots_stride * 2, half);
@ -51,7 +51,7 @@ void fft_fr_fast(blst_fr *out, blst_fr *in, uint64_t stride, blst_fr *roots, uin
}
// The main entry point for forward and reverse FFTs
C_KZG_RET fft_fr (blst_fr *out, blst_fr *in, FFTSettings *fs, bool inv, uint64_t n) {
C_KZG_RET fft_fr (blst_fr *out, const blst_fr *in, const FFTSettings *fs, bool inv, uint64_t n) {
uint64_t stride = fs->max_width / n;
ASSERT(n <= fs->max_width, C_KZG_BADARGS);
ASSERT(is_power_of_two(n), C_KZG_BADARGS);

View File

@ -17,6 +17,6 @@
#include "c_kzg.h"
#include "fft_common.h"
void fft_fr_slow(blst_fr *out, blst_fr *in, uint64_t stride, blst_fr *roots, uint64_t roots_stride, uint64_t l);
void fft_fr_fast(blst_fr *out, blst_fr *in, uint64_t stride, blst_fr *roots, uint64_t roots_stride, uint64_t l);
C_KZG_RET fft_fr (blst_fr *out, blst_fr *in, FFTSettings *fs, bool inv, uint64_t n);
void fft_fr_slow(blst_fr *out, const blst_fr *in, uint64_t stride, const blst_fr *roots, uint64_t roots_stride, uint64_t l);
void fft_fr_fast(blst_fr *out, const blst_fr *in, uint64_t stride, const blst_fr *roots, uint64_t roots_stride, uint64_t l);
C_KZG_RET fft_fr (blst_fr *out, const blst_fr *in, const FFTSettings *fs, bool inv, uint64_t n);

View File

@ -1,28 +0,0 @@
/*
* Copyright 2021 Benjamin Edgington
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include "kzg_common.h"
C_KZG_RET new_kzg_settings(KZGSettings *ks, FFTSettings *fs, blst_p1 *secret_g1, blst_p2 *secret_g2, uint64_t length) {
ASSERT(length >= fs->max_width, C_KZG_BADARGS);
ks->fs = fs;
ks->secret_g1 = secret_g1;
ks->extended_secret_g1 = NULL;
ks->secret_g2 = secret_g2;
ks->length = length;
return C_KZG_OK;
}

View File

@ -1,28 +0,0 @@
/*
* Copyright 2021 Benjamin Edgington
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "c_kzg.h"
#include "fft_common.h"
typedef struct {
FFTSettings *fs;
blst_p1 *secret_g1;
blst_p1 *extended_secret_g1;
blst_p2 *secret_g2;
uint64_t length;
} KZGSettings;
C_KZG_RET new_kzg_settings(KZGSettings *ks, FFTSettings *fs, blst_p1 *secret_g1, blst_p2 *secret_g2, uint64_t length);

124
src/kzg_proofs.c Normal file
View File

@ -0,0 +1,124 @@
/*
* Copyright 2021 Benjamin Edgington
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "kzg_proofs.h"
C_KZG_RET new_kzg_settings(KZGSettings *ks, FFTSettings *fs, blst_p1 *secret_g1, blst_p2 *secret_g2, uint64_t length) {
ASSERT(length >= fs->max_width, C_KZG_BADARGS);
ks->fs = fs;
ks->secret_g1 = secret_g1;
ks->extended_secret_g1 = NULL;
ks->secret_g2 = secret_g2;
ks->length = length;
return C_KZG_OK;
}
void commit_to_poly(blst_p1 *out, const KZGSettings *ks, const poly *p) {
linear_combination_g1(out, ks->secret_g1, p->coeffs, p->length);
}
// Compute KZG proof for polynomial at position x0
C_KZG_RET compute_proof_single(blst_p1 *out, const KZGSettings *ks, poly *p, const blst_fr *x0) {
return compute_proof_multi(out, ks, p, x0, 1);
}
bool check_proof_single(const KZGSettings *ks, const blst_p1 *commitment, const blst_p1 *proof, const blst_fr *x, blst_fr *y) {
blst_p2 x_g2, s_minus_x;
blst_p1 y_g1, commitment_minus_y;
p2_mul(&x_g2, blst_p2_generator(), x);
p2_sub(&s_minus_x, &ks->secret_g2[1], &x_g2);
p1_mul(&y_g1, blst_p1_generator(), y);
p1_sub(&commitment_minus_y, commitment, &y_g1);
return pairings_verify(&commitment_minus_y, blst_p2_generator(), proof, &s_minus_x);
}
// Compute KZG proof for polynomial in coefficient form at positions x * w^y where w is
// an n-th root of unity (this is the proof for one data availability sample, which consists
// of several polynomial evaluations)
C_KZG_RET compute_proof_multi(blst_p1 *out, const KZGSettings *ks, poly *p, const blst_fr *x0, uint64_t n) {
poly divisor, q;
uint64_t len;
blst_fr x_pow_n;
ASSERT(p->length >= n + 1, C_KZG_BADARGS);
// Construct x^n - x0^n
init_poly(&divisor, n + 1);
// -(x0^n)
fr_pow(&x_pow_n, x0, n);
fr_negate(&divisor.coeffs[0], &x_pow_n);
// Zeros
for (uint64_t i = 1; i < n; i++) {
divisor.coeffs[i] = fr_zero;
}
// x^n
divisor.coeffs[n] = fr_one;
// Calculate q = p / (x^n - x0^n)
// Discard the return codes since we already checked above that all should be fine.
poly_quotient_length(&len, p, &divisor);
init_poly(&q, len);
poly_long_div(&q, p, &divisor);
commit_to_poly(out, ks, &q);
free_poly(q);
free_poly(divisor);
return C_KZG_OK;
}
// Check a proof for a KZG commitment for an evaluation f(x w^i) = y_i
// The ys must have a power of 2 length
bool check_proof_multi(const KZGSettings *ks, const blst_p1 *commitment, const blst_p1 *proof, const blst_fr *x, const blst_fr *ys, uint64_t n) {
poly interp;
blst_fr inv_x, inv_x_pow, x_pow;
blst_p2 xn2, xn_minus_yn;
blst_p1 is1, commit_minus_interp;
//C_KZG_RET ret; // TODO - error handling
// Interpolate at a coset.
init_poly(&interp, n);
fft_fr(interp.coeffs, ys, ks->fs, true, n);
// if (ret != C_KZG_OK) return ret;
// Because it is a coset, not the subgroup, we have to multiply the polynomial coefficients by x^i
blst_fr_eucl_inverse(&inv_x, x);
inv_x_pow = inv_x;
for (uint64_t i = 1; i < n; i++) {
blst_fr_mul(&interp.coeffs[i], &interp.coeffs[i], &inv_x_pow);
blst_fr_mul(&inv_x_pow, &inv_x_pow, &inv_x);
}
// [x^n]_2
blst_fr_eucl_inverse(&x_pow, &inv_x_pow);
p2_mul(&xn2, blst_p2_generator(), &x_pow);
// [s^n - x^n]_2
p2_sub(&xn_minus_yn, &ks->secret_g2[n], &xn2);
// [interpolation_polynomial(s)]_1
commit_to_poly(&is1, ks, &interp);
// [commitment - interpolation_polynomial(s)]_1 = [commit]_1 - [interpolation_polynomial(s)]_1
p1_sub(&commit_minus_interp, commitment, &is1);
return pairings_verify(&commit_minus_interp, blst_p2_generator(), proof, &xn_minus_yn);
}

View File

@ -15,9 +15,20 @@
*/
#include "c_kzg.h"
#include "kzg_common.h"
#include "fft_fr.h"
#include "poly.h"
typedef struct {
FFTSettings *fs;
blst_p1 *secret_g1;
blst_p1 *extended_secret_g1;
blst_p2 *secret_g2;
uint64_t length;
} KZGSettings;
C_KZG_RET new_kzg_settings(KZGSettings *ks, FFTSettings *fs, blst_p1 *secret_g1, blst_p2 *secret_g2, uint64_t length);
void commit_to_poly(blst_p1 *out, const KZGSettings *ks, const poly *p);
C_KZG_RET compute_proof_single(blst_p1 *out, const KZGSettings *ks, poly *p, const uint64_t x0);
C_KZG_RET compute_proof_single(blst_p1 *out, const KZGSettings *ks, poly *p, const blst_fr *x0);
bool check_proof_single(const KZGSettings *ks, const blst_p1 *commitment, const blst_p1 *proof, const blst_fr *x, blst_fr *y);
C_KZG_RET compute_proof_multi(blst_p1 *out, const KZGSettings *ks, poly *p, const blst_fr *x0, uint64_t n);
bool check_proof_multi(const KZGSettings *ks, const blst_p1 *commitment, const blst_p1 *proof, const blst_fr *x, const blst_fr *ys, uint64_t n);

158
src/kzg_proofs_test.c Normal file
View File

@ -0,0 +1,158 @@
/*
* Copyright 2021 Benjamin Edgington
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "../inc/acutest.h"
#include "debug_util.h"
#include "kzg_proofs.h"
// The generator for our "trusted" setup
blst_scalar secret =
{
0xa4, 0x73, 0x31, 0x95, 0x28, 0xc8, 0xb6, 0xea,
0x4d, 0x08, 0xcc, 0x53, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; // Little-endian?
void generate_setup(blst_p1 *s1, blst_p2 *s2, const blst_scalar *secret, const uint64_t n) {
blst_fr s_pow, s;
blst_fr_from_scalar(&s, secret);
s_pow = fr_one;
for (uint64_t i = 0; i < n; i++) {
p1_mul(&s1[i], blst_p1_generator(), &s_pow);
p2_mul(&s2[i], blst_p2_generator(), &s_pow);
blst_fr_mul(&s_pow, &s_pow, &s);
}
}
void title(void) {;}
void proof_single(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 + 1;
FFTSettings fs;
KZGSettings ks;
poly p;
blst_p1 commitment, proof;
blst_p1 *s1 = malloc(secrets_len * sizeof(blst_p1));
blst_p2 *s2 = malloc(secrets_len * sizeof(blst_p2));
blst_fr x, value;
// Create the polynomial
init_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_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, &fs, s1, s2, secrets_len));
// Compute the proof for x = 25
fr_from_uint64(&x, 25);
commit_to_poly(&commitment, &ks, &p);
TEST_CHECK(C_KZG_OK == compute_proof_single(&proof, &ks, &p, &x));
// Verify the proof for x = 25
eval_poly(&value, &p, &x);
TEST_CHECK(true == check_proof_single(&ks, &commitment, &proof, &x, &value));
free_fft_settings(&fs);
free_poly(p);
free(s1);
free(s2);
}
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};
int poly_len = sizeof coeffs / sizeof coeffs[0];
uint64_t secrets_len = poly_len + 1;
FFTSettings fs1, fs2;
KZGSettings ks1, ks2;
poly p;
blst_p1 commitment, proof;
blst_p1 *s1 = malloc(secrets_len * sizeof(blst_p1));
blst_p2 *s2 = malloc(secrets_len * sizeof(blst_p2));
blst_fr x, tmp;
int coset_scale = 3, coset_len = (1 << coset_scale); // Where do these come from?
blst_fr ys[coset_len];
// Create the polynomial
init_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_setup(s1, s2, &secret, secrets_len);
TEST_CHECK(C_KZG_OK == new_fft_settings(&fs1, 4)); // ln_2 of poly_len
TEST_CHECK(C_KZG_OK == new_kzg_settings(&ks1, &fs1, s1, s2, secrets_len));
// Commit to the polynomial
commit_to_poly(&commitment, &ks1, &p);
TEST_CHECK(C_KZG_OK == new_fft_settings(&fs2, coset_scale));
TEST_CHECK(C_KZG_OK == new_kzg_settings(&ks2, &fs2, s1, s2, secrets_len));
// Compute proof at the points [x * root_i] 0 <= i < coset_len
fr_from_uint64(&x, 5431);
TEST_CHECK(C_KZG_OK == compute_proof_multi(&proof, &ks2, &p, &x, coset_len));
// The ys are the values of the polynomial at the points above
for (int i = 0; i < coset_len; i++) {
blst_fr_mul(&tmp, &x, &ks2.fs->expanded_roots_of_unity[i]);
eval_poly(&ys[i], &p, &tmp);
}
// Verify the proof
TEST_CHECK(check_proof_multi(&ks2, &commitment, &proof, &x, ys, coset_len));
free_fft_settings(&fs1);
free_fft_settings(&fs2);
free_poly(p);
free(s1);
free(s2);
}
void proof_single_error(void) {
poly p;
blst_p1 proof;
KZGSettings ks;
blst_fr x;
// Check it barfs on a constant polynomial
init_poly(&p, 1);
fr_from_uint64(&x, 1234);
TEST_CHECK(C_KZG_BADARGS == compute_proof_single(&proof, &ks, &p, &x));
free_poly(p);
}
TEST_LIST =
{
{"KZG_PROOFS_TEST", title},
{"proof_single", proof_single},
{"proof_multi", proof_multi},
{"proof_single_error", proof_single},
{ NULL, NULL } /* zero record marks the end of the list */
};

View File

@ -1,60 +0,0 @@
/*
* Copyright 2021 Benjamin Edgington
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "kzg_single_proofs.h"
void commit_to_poly(blst_p1 *out, const KZGSettings *ks, const poly *p) {
linear_combination_g1(out, ks->secret_g1, p->coeffs, p->length);
}
// Compute KZG proof for polynomial at position x0
C_KZG_RET compute_proof_single(blst_p1 *out, const KZGSettings *ks, poly *p, const uint64_t x0) {
poly divisor, q;
blst_fr tmp;
uint64_t len;
ASSERT(p->length >= 2, C_KZG_BADARGS);
// The divisor is x - x0
poly_init(&divisor, 2);
fr_from_uint64(&tmp, x0);
fr_negate(&divisor.coeffs[0],&tmp);
divisor.coeffs[1] = fr_one;
// Calculate q = p / (x - x0)
// Discard the return codes since we already checked above that all should be fine.
(void) poly_quotient_length(&len, p, &divisor);
poly_init(&q, len);
(void) poly_long_div(&q, p, &divisor);
linear_combination_g1(out, ks->secret_g1, q.coeffs, q.length);
poly_free(q);
poly_free(divisor);
return C_KZG_OK;
}
bool check_proof_single(const KZGSettings *ks, const blst_p1 *commitment, const blst_p1 *proof, const blst_fr *x, blst_fr *y) {
blst_p2 x_g2, s_minus_x;
blst_p1 y_g1, commitment_minus_y;
p2_mul(&x_g2, blst_p2_generator(), x);
p2_sub(&s_minus_x, &ks->secret_g2[1], &x_g2);
p1_mul(&y_g1, blst_p1_generator(), y);
p1_sub(&commitment_minus_y, commitment, &y_g1);
return pairings_verify(&commitment_minus_y, blst_p2_generator(), proof, &s_minus_x);
}

View File

@ -1,91 +0,0 @@
/*
* Copyright 2021 Benjamin Edgington
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "../inc/acutest.h"
#include "debug_util.h"
#include "kzg_single_proofs.h"
void generate_setup(blst_p1 *s1, blst_p2 *s2, const blst_scalar *secret, const uint64_t n) {
blst_fr s_pow, s;
blst_fr_from_scalar(&s, secret);
s_pow = fr_one;
for (uint64_t i = 0; i < n; i++) {
p1_mul(&s1[i], blst_p1_generator(), &s_pow);
p2_mul(&s2[i], blst_p2_generator(), &s_pow);
blst_fr_mul(&s_pow, &s_pow, &s);
}
}
void title(void) {;}
void proof_single(void) {
FFTSettings fs;
KZGSettings ks;
poly p;
blst_p1 commitment, proof;
blst_p1 *s1 = malloc(17 * sizeof(blst_p1));
blst_p2 *s2 = malloc(17 * sizeof(blst_p2));
blst_scalar secret =
{
0xa4, 0x73, 0x31, 0x95, 0x28, 0xc8, 0xb6, 0xea,
0x4d, 0x08,0xcc, 0x53, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; // Little-endian?
uint64_t coeffs_u[16] = {1, 2, 3, 4, 7, 7, 7, 7, 13, 13, 13, 13, 13, 13, 13, 13};
blst_fr x, value;
poly_init(&p, 16);
for (int i = 0; i < 16; i++) {
fr_from_uint64(&p.coeffs[i], coeffs_u[i]);
}
generate_setup(s1, s2, &secret, 17);
new_fft_settings(&fs, 4);
new_kzg_settings(&ks, &fs, s1, s2, 17);
commit_to_poly(&commitment, &ks, &p);
TEST_CHECK(C_KZG_OK == compute_proof_single(&proof, &ks, &p, 17));
fr_from_uint64(&x, 17);
poly_eval(&value, &p, &x);
TEST_CHECK(true == check_proof_single(&ks, &commitment, &proof, &x, &value));
free(s1);
free(s2);
}
void proof_single_error(void) {
poly p;
blst_p1 proof;
KZGSettings ks;
// Check it barfs on a constant polynomial
poly_init(&p, 1);
TEST_CHECK(C_KZG_BADARGS == compute_proof_single(&proof, &ks, &p, 17));
poly_free(p);
}
TEST_LIST =
{
{"KZG_SINGLE_PRROFS_TEST", title},
{"proof_single", proof_single},
{"proof_single_error", proof_single},
{ NULL, NULL } /* zero record marks the end of the list */
};

View File

@ -21,16 +21,16 @@ static void poly_factor_div(blst_fr *out, const blst_fr *a, const blst_fr *b) {
blst_fr_mul(out, out, a);
}
void poly_init(poly *out, const uint64_t length) {
void init_poly(poly *out, const uint64_t length) {
out->length = length;
out->coeffs = malloc(length * sizeof(blst_fr));
}
void poly_free(poly p) {
void free_poly(poly p) {
free(p.coeffs);
}
void poly_eval(blst_fr *out, const poly *p, const blst_fr *x) {
void eval_poly(blst_fr *out, const poly *p, const blst_fr *x) {
blst_fr tmp;
uint64_t i;

View File

@ -23,8 +23,8 @@ typedef struct {
uint64_t length; // one more than the polynomial's degree
} poly;
void poly_init(poly *out, const uint64_t length);
void poly_free(poly p);
void poly_eval(blst_fr *out, const poly *p, const blst_fr *x);
void init_poly(poly *out, const uint64_t length);
void free_poly(poly p);
void eval_poly(blst_fr *out, const poly *p, const blst_fr *x);
C_KZG_RET poly_quotient_length(uint64_t *out, const poly *dividend, const poly *divisor);
C_KZG_RET poly_long_div(poly *out, const poly *dividend, const poly *divisor);

View File

@ -23,8 +23,8 @@ void title(void) {;}
void poly_div_length(void) {
poly a, b;
uint64_t len;
poly_init(&a, 17);
poly_init(&b, 5);
init_poly(&a, 17);
init_poly(&b, 5);
TEST_CHECK(C_KZG_OK == poly_quotient_length(&len, &a, &b));
TEST_CHECK(13 == len);
}
@ -32,8 +32,8 @@ void poly_div_length(void) {
void poly_div_length_bad(void) {
poly a, b;
uint64_t len;
poly_init(&a, 5);
poly_init(&b, 17);
init_poly(&a, 5);
init_poly(&b, 17);
TEST_CHECK(C_KZG_BADARGS == poly_quotient_length(&len, &a, &b));
}
@ -115,13 +115,13 @@ void poly_eval_check(void) {
uint64_t n = 10;
blst_fr res, expected;
poly p;
poly_init(&p, n);
init_poly(&p, n);
for (uint64_t i = 0; i < n; i++) {
fr_from_uint64(&p.coeffs[i], i + 1);
}
fr_from_uint64(&expected, n * (n + 1) / 2);
poly_eval(&res, &p, &fr_one);
eval_poly(&res, &p, &fr_one);
TEST_CHECK(fr_equal(&expected, &res));
}
@ -130,13 +130,13 @@ void poly_eval_0_check(void) {
uint64_t n = 7, a = 597;
blst_fr res, expected;
poly p;
poly_init(&p, n);
init_poly(&p, n);
for (uint64_t i = 0; i < n; i++) {
fr_from_uint64(&p.coeffs[i], i + a);
}
fr_from_uint64(&expected, a);
poly_eval(&res, &p, &fr_zero);
eval_poly(&res, &p, &fr_zero);
TEST_CHECK(fr_equal(&expected, &res));
}