Shortcut polynomial evaluation for x = 0
This commit is contained in:
parent
abe417019f
commit
ddecf22708
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue