Move field element division to blst_util

This commit is contained in:
Ben Edgington 2021-02-11 20:01:57 +00:00
parent 167a39cc4c
commit ef4be2309d
5 changed files with 50 additions and 31 deletions

View File

@ -62,6 +62,11 @@ void fr_pow(blst_fr *out, const blst_fr *a, uint64_t n) {
} }
} }
void fr_div(blst_fr *out, const blst_fr *a, const blst_fr *b) {
blst_fr_eucl_inverse(out, b);
blst_fr_mul(out, out, a);
}
void p1_mul(blst_p1 *out, const blst_p1 *a, const blst_fr *b) { void p1_mul(blst_p1 *out, const blst_p1 *a, const blst_fr *b) {
blst_scalar s; blst_scalar s;
blst_scalar_from_fr(&s, b); blst_scalar_from_fr(&s, b);

View File

@ -32,6 +32,7 @@ void fr_from_uint64(blst_fr *a, const uint64_t n);
bool fr_equal(const blst_fr *aa, const blst_fr *bb); bool fr_equal(const blst_fr *aa, const blst_fr *bb);
void fr_negate(blst_fr *out, const blst_fr *in); 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 fr_pow(blst_fr *out, const blst_fr *a, const uint64_t n);
void fr_div(blst_fr *out, const blst_fr *a, const blst_fr *b);
void p1_mul(blst_p1 *out, const blst_p1 *a, const blst_fr *b); 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 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); void p2_mul(blst_p2 *out, const blst_p2 *a, const blst_fr *b);

View File

@ -74,6 +74,18 @@ void fr_pow_works(void) {
TEST_CHECK(fr_equal(&expected, &actual)); TEST_CHECK(fr_equal(&expected, &actual));
} }
void fr_div_works(void) {
blst_fr a, b, tmp, actual;
fr_from_uint64(&a, 197);
fr_from_uint64(&b, 123456);
fr_div(&tmp, &a, &b);
blst_fr_mul(&actual, &tmp, &b);
TEST_CHECK(fr_equal(&a, &actual));
}
void p1_mul_works(void) { void p1_mul_works(void) {
blst_fr minus1; blst_fr minus1;
blst_p1 g1_gen, g1_gen_neg, res; blst_p1 g1_gen, g1_gen_neg, res;
@ -184,6 +196,7 @@ TEST_LIST = {
{"fr_equal_works", fr_equal_works}, {"fr_equal_works", fr_equal_works},
{"fr_negate_works", fr_negate_works}, {"fr_negate_works", fr_negate_works},
{"fr_pow_works", fr_pow_works}, {"fr_pow_works", fr_pow_works},
{"fr_div_works", fr_div_works},
{"p1_mul_works", p1_mul_works}, {"p1_mul_works", p1_mul_works},
{"p1_sub_works", p1_sub_works}, {"p1_sub_works", p1_sub_works},
{"p2_mul_works", p2_mul_works}, {"p2_mul_works", p2_mul_works},

View File

@ -20,30 +20,6 @@
#include "c_kzg_util.h" #include "c_kzg_util.h"
#include "poly.h" #include "poly.h"
static void poly_factor_div(blst_fr *out, const blst_fr *a, const blst_fr *b) {
blst_fr_eucl_inverse(out, b);
blst_fr_mul(out, out, a);
}
C_KZG_RET init_poly(poly *out, const uint64_t length) {
out->length = length;
return c_kzg_malloc((void **)&out->coeffs, length * sizeof *out->coeffs);
}
C_KZG_RET init_poly_with_coeffs(poly *out, const uint64_t *coeffs, const uint64_t length) {
ASSERT(init_poly(out, length) == C_KZG_OK, C_KZG_MALLOC);
for (uint64_t i = 0; i < length; i++) {
fr_from_uint64(&out->coeffs[i], coeffs[i]);
}
return C_KZG_OK;
}
void free_poly(poly *p) {
if (p->coeffs != NULL) {
free(p->coeffs);
}
}
void eval_poly(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; blst_fr tmp;
uint64_t i; uint64_t i;
@ -96,7 +72,7 @@ C_KZG_RET poly_long_div(poly *out, const poly *dividend, const poly *divisor) {
} }
while (diff > 0) { while (diff > 0) {
poly_factor_div(&out->coeffs[diff], &a[a_pos], &divisor->coeffs[b_pos]); fr_div(&out->coeffs[diff], &a[a_pos], &divisor->coeffs[b_pos]);
for (uint64_t i = 0; i <= b_pos; i++) { for (uint64_t i = 0; i <= b_pos; i++) {
blst_fr tmp; blst_fr tmp;
// a[diff + i] -= b[i] * quot // a[diff + i] -= b[i] * quot
@ -106,7 +82,26 @@ C_KZG_RET poly_long_div(poly *out, const poly *dividend, const poly *divisor) {
--diff; --diff;
--a_pos; --a_pos;
} }
poly_factor_div(&out->coeffs[0], &a[a_pos], &divisor->coeffs[b_pos]); fr_div(&out->coeffs[0], &a[a_pos], &divisor->coeffs[b_pos]);
return C_KZG_OK; return C_KZG_OK;
} }
C_KZG_RET init_poly_with_coeffs(poly *out, const uint64_t *coeffs, const uint64_t length) {
ASSERT(init_poly(out, length) == C_KZG_OK, C_KZG_MALLOC);
for (uint64_t i = 0; i < length; i++) {
fr_from_uint64(&out->coeffs[i], coeffs[i]);
}
return C_KZG_OK;
}
C_KZG_RET init_poly(poly *out, const uint64_t length) {
out->length = length;
return c_kzg_malloc((void **)&out->coeffs, length * sizeof *out->coeffs);
}
void free_poly(poly *p) {
if (p->coeffs != NULL) {
free(p->coeffs);
}
}

View File

@ -19,14 +19,19 @@
#include "c_kzg.h" #include "c_kzg.h"
#include "blst_util.h" #include "blst_util.h"
/**
* Defines a polynomial whose coefficients are members of the finite field F_r.
*
* Initialise the storage with #init_poly. After use, free the storage with #free_poly.
*/
typedef struct { typedef struct {
blst_fr *coeffs; // coeffs[i] is the x^i term blst_fr *coeffs; /**< `coeffs[i]` is the coefficient of the `x^i` term of the polynomial. */
uint64_t length; // one more than the polynomial's degree uint64_t length; /**< One more than the polynomial's degree */
} poly; } poly;
C_KZG_RET init_poly(poly *out, const uint64_t length);
C_KZG_RET init_poly_with_coeffs(poly *out, const uint64_t *coeffs, const uint64_t length);
void free_poly(poly *p);
void eval_poly(blst_fr *out, const poly *p, const blst_fr *x); void eval_poly(blst_fr *out, const poly *p, const blst_fr *x);
uint64_t poly_quotient_length(const poly *dividend, const poly *divisor); uint64_t poly_quotient_length(const poly *dividend, const poly *divisor);
C_KZG_RET poly_long_div(poly *out, const poly *dividend, const poly *divisor); C_KZG_RET poly_long_div(poly *out, const poly *dividend, const poly *divisor);
C_KZG_RET init_poly_with_coeffs(poly *out, const uint64_t *coeffs, const uint64_t length);
C_KZG_RET init_poly(poly *out, const uint64_t length);
void free_poly(poly *p);