diff --git a/src/blst_util.c b/src/blst_util.c index 04c5fa9..5c948b1 100644 --- a/src/blst_util.c +++ b/src/blst_util.c @@ -17,6 +17,14 @@ #include "blst_util.h" #include "debug_util.h" +// TODO - find a better way to do this +bool fr_is_zero(const blst_fr *p) { + uint64_t a[4]; + blst_uint64_from_fr(a, p); + return a[0] == 0 && a[1] == 0 && a[2] == 0 && a[3] == 0; +} + +// TODO - find a better way to do this bool fr_is_one(const blst_fr *p) { uint64_t a[4]; blst_uint64_from_fr(a, p); diff --git a/src/blst_util.h b/src/blst_util.h index a8a5641..912376e 100644 --- a/src/blst_util.h +++ b/src/blst_util.h @@ -16,13 +16,16 @@ #include "c_kzg.h" +static const blst_fr fr_zero = {0L, 0L, 0L, 0L}; + // This is 1 in Blst's `blst_fr` limb representation. Crazy but true. -static const blst_fr one = +static const blst_fr fr_one = {0x00000001fffffffeL, 0x5884b7fa00034802L, 0x998c4fefecbc4ff5L, 0x1824b159acc5056fL}; // The G1 identity/infinity in affine representation -static const blst_p1_affine identity_g1_affine = {{0,0,0,0,0,0},{0,0,0,0,0,0}}; +static const blst_p1_affine identity_g1_affine = {{0L,0L,0L,0L,0L,0L},{0L,0L,0L,0L,0L,0L}}; +bool fr_is_zero(const blst_fr *p); 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); diff --git a/src/blst_util_test.c b/src/blst_util_test.c index 3c036bc..f889b4e 100644 --- a/src/blst_util_test.c +++ b/src/blst_util_test.c @@ -23,14 +23,20 @@ uint64_t m1[] = {0xffffffff00000000L, 0x53bda402fffe5bfeL, 0x3339d80809a1d805L, void title(void) {;} +void fr_is_zero_works(void) { + blst_fr zero; + fr_from_uint64(&zero, 0); + TEST_CHECK(fr_is_zero(&zero)); +} + void fr_is_one_works(void) { - TEST_CHECK(true == fr_is_one(&one)); + TEST_CHECK(fr_is_one(&fr_one)); } void fr_from_uint64_works(void) { blst_fr a; fr_from_uint64(&a, 1); - TEST_CHECK(true == fr_is_one(&a)); + TEST_CHECK(fr_is_one(&a)); } void fr_equal_works(void) { @@ -156,6 +162,7 @@ void pairings_work(void) { TEST_LIST = { {"BLST_UTIL_TEST", title}, + {"fr_is_zero_works", fr_is_zero_works }, {"fr_is_one_works", fr_is_one_works }, {"fr_from_uint64_works", fr_from_uint64_works}, {"fr_equal_works", fr_equal_works}, diff --git a/src/fft_common.c b/src/fft_common.c index bb2c79e..6727266 100644 --- a/src/fft_common.c +++ b/src/fft_common.c @@ -25,7 +25,7 @@ bool is_power_of_two(const uint64_t n) { // Create an array of powers of the root of unity // The `out` array must be of size `width + 1` C_KZG_RET expand_root_of_unity(blst_fr *roots, const blst_fr *root_of_unity, const uint64_t width) { - roots[0] = one; + roots[0] = fr_one; roots[1] = *root_of_unity; for (int i = 2; !fr_is_one(&roots[i - 1]); i++) { diff --git a/src/fft_common_test.c b/src/fft_common_test.c index 2bd2ea7..57c4a60 100644 --- a/src/fft_common_test.c +++ b/src/fft_common_test.c @@ -46,9 +46,9 @@ void reverse_works(void) { blst_fr diff; // Initialise - increasing values - arr[0] = one; + arr[0] = fr_one; for (int i = 1; i <= n; i++) { - blst_fr_add(arr + i, arr + i - 1, &one); + blst_fr_add(arr + i, arr + i - 1, &fr_one); } // Reverse diff --git a/src/kzg_single_proofs.c b/src/kzg_single_proofs.c index fc9911c..0ad3524 100644 --- a/src/kzg_single_proofs.c +++ b/src/kzg_single_proofs.c @@ -32,7 +32,7 @@ C_KZG_RET compute_proof_single(blst_p1 *out, const KZGSettings *ks, poly *p, con poly_init(&divisor, 2); fr_from_uint64(&tmp, x0); fr_negate(&divisor.coeffs[0],&tmp); - divisor.coeffs[1] = one; + divisor.coeffs[1] = fr_one; // Calculate q = p / (x - x0) // Discard the return codes since we already checked above that all should be fine. diff --git a/src/kzg_single_proofs_test.c b/src/kzg_single_proofs_test.c index d28f745..3e9f450 100644 --- a/src/kzg_single_proofs_test.c +++ b/src/kzg_single_proofs_test.c @@ -21,7 +21,7 @@ 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 = one; + 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); diff --git a/src/poly.c b/src/poly.c index bbd64f2..46acee1 100644 --- a/src/poly.c +++ b/src/poly.c @@ -36,7 +36,9 @@ void poly_eval(blst_fr *out, const poly *p, const blst_fr *x) { if (p->length == 0) { fr_from_uint64(out, 0); } - // TODO x = 0 case + if (fr_is_zero(x)) { + *out = p->coeffs[0]; + } // Horner's method *out = p->coeffs[p->length - 1]; diff --git a/src/poly_test.c b/src/poly_test.c index cf40779..2700e10 100644 --- a/src/poly_test.c +++ b/src/poly_test.c @@ -121,7 +121,22 @@ void poly_eval_check(void) { } fr_from_uint64(&expected, n * (n + 1) / 2); - poly_eval(&res, &p, &one); + poly_eval(&res, &p, &fr_one); + + TEST_CHECK(fr_equal(&expected, &res)); +} + +void poly_eval_0_check(void) { + uint64_t n = 7, a = 597; + blst_fr res, expected; + poly p; + poly_init(&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); TEST_CHECK(fr_equal(&expected, &res)); } @@ -135,5 +150,6 @@ TEST_LIST = {"poly_div_1", poly_div_1}, {"poly_wrong_size", poly_wrong_size}, {"poly_eval_check", poly_eval_check}, + {"poly_eval_0_check", poly_eval_0_check}, { NULL, NULL } /* zero record marks the end of the list */ };