mirror of
https://github.com/status-im/c-kzg-4844.git
synced 2025-02-02 21:34:16 +00:00
Groundwork for being able to use alternative BLS libraries
This commit is contained in:
parent
aec19b5eee
commit
66c50a49b1
@ -1,7 +1,7 @@
|
||||
TESTS = blst_util_test c_kzg_util_test fft_common_test fft_fr_test fft_g1_test \
|
||||
TESTS = bls12_381_test c_kzg_util_test fft_common_test fft_fr_test fft_g1_test \
|
||||
fk20_proofs_test kzg_proofs_test poly_test
|
||||
BENCH = fft_fr_bench fft_g1_bench
|
||||
LIB_SRC = blst_util.c c_kzg_util.c fft_common.c fft_fr.c fft_g1.c fk20_proofs.c kzg_proofs.c poly.c
|
||||
LIB_SRC = bls12_381.c c_kzg_util.c fft_common.c fft_fr.c fft_g1.c fk20_proofs.c kzg_proofs.c poly.c
|
||||
LIB_OBJ = $(LIB_SRC:.c=.o)
|
||||
|
||||
CFLAGS =
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
#include <stdlib.h> // rand()
|
||||
#include "bench_util.h"
|
||||
#include "blst_util.h"
|
||||
|
||||
unsigned long tdiff(timespec_t start, timespec_t end) {
|
||||
return (end.tv_sec - start.tv_sec) * NANO + (end.tv_nsec - start.tv_nsec);
|
||||
@ -28,20 +27,20 @@ uint64_t rand_uint64() {
|
||||
return a << 32 | b;
|
||||
}
|
||||
|
||||
blst_fr rand_fr() {
|
||||
blst_fr ret;
|
||||
fr_t rand_fr() {
|
||||
fr_t ret;
|
||||
uint64_t a[4];
|
||||
a[0] = rand_uint64();
|
||||
a[1] = rand_uint64();
|
||||
a[2] = rand_uint64();
|
||||
a[3] = rand_uint64();
|
||||
blst_fr_from_uint64(&ret, a);
|
||||
fr_from_uint64s(&ret, a);
|
||||
return ret;
|
||||
}
|
||||
|
||||
blst_p1 rand_g1() {
|
||||
blst_p1 ret;
|
||||
blst_fr random = rand_fr();
|
||||
p1_mul(&ret, blst_p1_generator(), &random);
|
||||
g1_t rand_g1() {
|
||||
g1_t ret;
|
||||
fr_t random = rand_fr();
|
||||
g1_mul(&ret, &g1_generator, &random);
|
||||
return ret;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <time.h> // CLOCK_REALTIME, clock_gettime(), timespec
|
||||
#include "c_kzg.h"
|
||||
#include "bls12_381.h"
|
||||
|
||||
typedef struct timespec timespec_t;
|
||||
|
||||
@ -24,5 +25,5 @@ typedef struct timespec timespec_t;
|
||||
|
||||
unsigned long tdiff(timespec_t start, timespec_t end);
|
||||
uint64_t rand_uint64();
|
||||
blst_fr rand_fr();
|
||||
blst_p1 rand_g1();
|
||||
fr_t rand_fr();
|
||||
g1_t rand_g1();
|
||||
|
@ -15,13 +15,14 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file blst_util.c
|
||||
* @file bls12_381.c
|
||||
*
|
||||
* Useful utilities for dealing with field points and group elements that are not directly exposed by the Blst library.
|
||||
* Wrappers for cryptographic library functions, allowing different libraries to be supported.
|
||||
*/
|
||||
|
||||
#include "blst_util.h"
|
||||
#include "debug_util.h"
|
||||
#include "bls12_381.h"
|
||||
|
||||
#ifdef BLST
|
||||
|
||||
/**
|
||||
* Check whether the operand is zero in the finite field.
|
||||
@ -32,7 +33,7 @@
|
||||
*
|
||||
* @todo See if there is a more efficient way to check for zero in the finite field.
|
||||
*/
|
||||
bool fr_is_zero(const blst_fr *p) {
|
||||
bool fr_is_zero(const fr_t *p) {
|
||||
uint64_t a[4];
|
||||
blst_uint64_from_fr(a, p);
|
||||
return a[0] == 0 && a[1] == 0 && a[2] == 0 && a[3] == 0;
|
||||
@ -47,12 +48,32 @@ bool fr_is_zero(const blst_fr *p) {
|
||||
*
|
||||
* @todo See if there is a more efficient way to check for one in the finite field.
|
||||
*/
|
||||
bool fr_is_one(const blst_fr *p) {
|
||||
bool fr_is_one(const fr_t *p) {
|
||||
uint64_t a[4];
|
||||
blst_uint64_from_fr(a, p);
|
||||
return a[0] == 1 && a[1] == 0 && a[2] == 0 && a[3] == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a field element from a scalar, which is a little-endian sequence of bytes.
|
||||
*
|
||||
* @param[out] out The resulting field element
|
||||
* @param[in] a The scalar input, 32 bytes
|
||||
*/
|
||||
void fr_from_scalar(fr_t *out, const scalar_t *a) {
|
||||
blst_fr_from_scalar(out, a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a field element from an array of four 64-bit unsigned integers.
|
||||
*
|
||||
* @param out The field element equivalent of @p n
|
||||
* @param vals The array of 64-bit integers to be converted, little-endian ordering of the 64-bit words
|
||||
*/
|
||||
void fr_from_uint64s(fr_t *out, const uint64_t *vals) {
|
||||
blst_fr_from_uint64(out, vals);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a field element from a single 64-bit unsigned integer.
|
||||
*
|
||||
@ -61,9 +82,9 @@ bool fr_is_one(const blst_fr *p) {
|
||||
* @param out The field element equivalent of @p n
|
||||
* @param n The 64-bit integer to be converted
|
||||
*/
|
||||
void fr_from_uint64(blst_fr *out, uint64_t n) {
|
||||
void fr_from_uint64(fr_t *out, uint64_t n) {
|
||||
uint64_t vals[] = {n, 0, 0, 0};
|
||||
blst_fr_from_uint64(out, vals);
|
||||
fr_from_uint64s(out, vals);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,7 +95,7 @@ void fr_from_uint64(blst_fr *out, uint64_t n) {
|
||||
* @retval true if @p aa and @p bb are equal
|
||||
* @retval false otherwise
|
||||
*/
|
||||
bool fr_equal(const blst_fr *aa, const blst_fr *bb) {
|
||||
bool fr_equal(const fr_t *aa, const fr_t *bb) {
|
||||
uint64_t a[4], b[4];
|
||||
blst_uint64_from_fr(a, aa);
|
||||
blst_uint64_from_fr(b, bb);
|
||||
@ -87,10 +108,75 @@ bool fr_equal(const blst_fr *aa, const blst_fr *bb) {
|
||||
* @param[out] out The negation of @p in
|
||||
* @param[in] in The element to be negated
|
||||
*/
|
||||
void fr_negate(blst_fr *out, const blst_fr *in) {
|
||||
void fr_negate(fr_t *out, const fr_t *in) {
|
||||
blst_fr_cneg(out, in, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two field elements.
|
||||
*
|
||||
* @param[out] out @p a plus @p b in the field
|
||||
* @param[in] a Field element
|
||||
* @param[in] b Field element
|
||||
*/
|
||||
void fr_add(fr_t *out, const fr_t *a, const fr_t *b) {
|
||||
blst_fr_add(out, a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract one field element from another.
|
||||
*
|
||||
* @param[out] out @p a minus @p b in the field
|
||||
* @param[in] a Field element
|
||||
* @param[in] b Field element
|
||||
*/
|
||||
void fr_sub(fr_t *out, const fr_t *a, const fr_t *b) {
|
||||
blst_fr_sub(out, a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply two field elements.
|
||||
*
|
||||
* @param[out] out @p a multiplied by @p b in the field
|
||||
* @param[in] a Multiplicand
|
||||
* @param[in] b Multiplier
|
||||
*/
|
||||
void fr_mul(fr_t *out, const fr_t *a, const fr_t *b) {
|
||||
blst_fr_mul(out, a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverse of a field element.
|
||||
*
|
||||
* @param[out] out The inverse of @p a
|
||||
* @param[in] a A field element
|
||||
*/
|
||||
void fr_inv(fr_t *out, const fr_t *a) {
|
||||
blst_fr_eucl_inverse(out, a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Division of two field elements.
|
||||
*
|
||||
* @param[out] out @p a divided by @p b in the field
|
||||
* @param[in] a The dividend
|
||||
* @param[in] b The divisor
|
||||
*/
|
||||
void fr_div(fr_t *out, const fr_t *a, const fr_t *b) {
|
||||
blst_fr_eucl_inverse(out, b);
|
||||
blst_fr_mul(out, out, a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Square a field element.
|
||||
*
|
||||
* @param[out] out @p a squared
|
||||
* @param[in] a A field element
|
||||
*/
|
||||
void fr_sqr(fr_t *out, const fr_t *a) {
|
||||
blst_fr_sqr(out, a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exponentiation of a field element.
|
||||
*
|
||||
@ -102,29 +188,63 @@ void fr_negate(blst_fr *out, const blst_fr *in) {
|
||||
* @param[in] a The field element to be exponentiated
|
||||
* @param[in] n The exponent
|
||||
*/
|
||||
void fr_pow(blst_fr *out, const blst_fr *a, uint64_t n) {
|
||||
blst_fr tmp = *a;
|
||||
void fr_pow(fr_t *out, const fr_t *a, uint64_t n) {
|
||||
fr_t tmp = *a;
|
||||
*out = fr_one;
|
||||
|
||||
while (true) {
|
||||
if (n & 1) {
|
||||
blst_fr_mul(out, out, &tmp);
|
||||
fr_mul(out, out, &tmp);
|
||||
}
|
||||
if ((n >>= 1) == 0) break;
|
||||
blst_fr_sqr(&tmp, &tmp);
|
||||
fr_sqr(&tmp, &tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Division of two field elements.
|
||||
* Test G1 point for being infinity/the identity.
|
||||
*
|
||||
* @param[out] out @p a divided by @p b in the field
|
||||
* @param[in] a The dividend
|
||||
* @param[in] b The divisor
|
||||
* @param[in] a A G1 point
|
||||
* @retval true if @p a is the identity point in G1
|
||||
* @retval false otherwise
|
||||
*/
|
||||
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);
|
||||
bool g1_is_inf(const g1_t *a) {
|
||||
return blst_p1_is_inf(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Double a G1 point.
|
||||
*
|
||||
* @param[out] out @p a plus @p a in the group
|
||||
* @param[in] a G1 group point
|
||||
*/
|
||||
void g1_dbl(g1_t *out, const g1_t *a) {
|
||||
blst_p1_double(out, a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or double G1 points.
|
||||
*
|
||||
* This is safe if the two points are the same.
|
||||
*
|
||||
* @param[out] out @p a plus @p b in the group
|
||||
* @param[in] a G1 group point
|
||||
* @param[in] b G1 group point
|
||||
*/
|
||||
void g1_add_or_dbl(g1_t *out, const g1_t *a, const g1_t *b) {
|
||||
blst_p1_add_or_double(out, a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test G1 points for equality.
|
||||
*
|
||||
* @param[in] a A G1 point
|
||||
* @param[in] b A G1 point
|
||||
* @retval true if @p a and @p b are the same point
|
||||
* @retval false otherwise
|
||||
*/
|
||||
bool g1_equal(const g1_t *a, const g1_t *b) {
|
||||
return blst_p1_is_equal(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,7 +254,7 @@ void fr_div(blst_fr *out, const blst_fr *a, const blst_fr *b) {
|
||||
* @param[in] a The G1 group element
|
||||
* @param[in] b The multiplier
|
||||
*/
|
||||
void p1_mul(blst_p1 *out, const blst_p1 *a, const blst_fr *b) {
|
||||
void g1_mul(g1_t *out, const g1_t *a, const fr_t *b) {
|
||||
blst_scalar s;
|
||||
blst_scalar_from_fr(&s, b);
|
||||
blst_p1_mult(out, a, s.b, 8 * sizeof(blst_scalar));
|
||||
@ -147,12 +267,24 @@ void p1_mul(blst_p1 *out, const blst_p1 *a, const blst_fr *b) {
|
||||
* @param[in] a A G1 group element
|
||||
* @param[in] b The G1 group element to be subtracted
|
||||
*/
|
||||
void p1_sub(blst_p1 *out, const blst_p1 *a, const blst_p1 *b) {
|
||||
blst_p1 bneg = *b;
|
||||
void g1_sub(g1_t *out, const g1_t *a, const g1_t *b) {
|
||||
g1_t bneg = *b;
|
||||
blst_p1_cneg(&bneg, true);
|
||||
blst_p1_add_or_double(out, a, &bneg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test G2 points for equality.
|
||||
*
|
||||
* @param[in] a A G2 point
|
||||
* @param[in] b A G2 point
|
||||
* @retval true if @p a and @p b are the same point
|
||||
* @retval false otherwise
|
||||
*/
|
||||
bool g2_equal(const g2_t *a, const g2_t *b) {
|
||||
return blst_p2_is_equal(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply a G2 group element by a field element.
|
||||
*
|
||||
@ -160,7 +292,7 @@ void p1_sub(blst_p1 *out, const blst_p1 *a, const blst_p1 *b) {
|
||||
* @param[in] a The G2 group element
|
||||
* @param[in] b The multiplier
|
||||
*/
|
||||
void p2_mul(blst_p2 *out, const blst_p2 *a, const blst_fr *b) {
|
||||
void g2_mul(g2_t *out, const g2_t *a, const fr_t *b) {
|
||||
blst_scalar s;
|
||||
blst_scalar_from_fr(&s, b);
|
||||
blst_p2_mult(out, a, s.b, 8 * sizeof(blst_scalar));
|
||||
@ -173,12 +305,22 @@ void p2_mul(blst_p2 *out, const blst_p2 *a, const blst_fr *b) {
|
||||
* @param[in] a A G2 group element
|
||||
* @param[in] b The G2 group element to be subtracted
|
||||
*/
|
||||
void p2_sub(blst_p2 *out, const blst_p2 *a, const blst_p2 *b) {
|
||||
blst_p2 bneg = *b;
|
||||
void g2_sub(g2_t *out, const g2_t *a, const g2_t *b) {
|
||||
g2_t bneg = *b;
|
||||
blst_p2_cneg(&bneg, true);
|
||||
blst_p2_add_or_double(out, a, &bneg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Double a G2 point.
|
||||
*
|
||||
* @param[out] out @p a plus @p a in the group
|
||||
* @param[in] a G2 group point
|
||||
*/
|
||||
void g2_dbl(g2_t *out, const g2_t *a) {
|
||||
blst_p2_double(out, a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate a linear combination of G1 group elements.
|
||||
*
|
||||
@ -193,11 +335,11 @@ void p2_sub(blst_p2 *out, const blst_p2 *a, const blst_p2 *b) {
|
||||
* this is a bottleneck. (2) If so, look into optimised routines. [Notes from
|
||||
* Mamy](https://github.com/vacp2p/research/issues/7#issuecomment-690083000) on the topic.
|
||||
*/
|
||||
void linear_combination_g1(blst_p1 *out, const blst_p1 *p, const blst_fr *coeffs, const uint64_t len) {
|
||||
blst_p1 tmp;
|
||||
void g1_linear_combination(g1_t *out, const g1_t *p, const fr_t *coeffs, const uint64_t len) {
|
||||
g1_t tmp;
|
||||
*out = g1_identity;
|
||||
for (uint64_t i = 0; i < len; i++) {
|
||||
p1_mul(&tmp, &p[i], &coeffs[i]);
|
||||
g1_mul(&tmp, &p[i], &coeffs[i]);
|
||||
blst_p1_add_or_double(out, out, &tmp);
|
||||
}
|
||||
}
|
||||
@ -214,14 +356,14 @@ void linear_combination_g1(blst_p1 *out, const blst_p1 *p, const blst_fr *coeffs
|
||||
* @retval true The pairings were equal
|
||||
* @retval false The pairings were not equal
|
||||
*/
|
||||
bool pairings_verify(const blst_p1 *a1, const blst_p2 *a2, const blst_p1 *b1, const blst_p2 *b2) {
|
||||
bool pairings_verify(const g1_t *a1, const g2_t *a2, const g1_t *b1, const g2_t *b2) {
|
||||
blst_fp12 loop0, loop1, gt_point;
|
||||
blst_p1_affine aa1, bb1;
|
||||
blst_p2_affine aa2, bb2;
|
||||
|
||||
// As an optimisation, we want to invert one of the pairings,
|
||||
// so we negate one of the points.
|
||||
blst_p1 a1neg = *a1;
|
||||
g1_t a1neg = *a1;
|
||||
blst_p1_cneg(&a1neg, true);
|
||||
|
||||
blst_p1_to_affine(&aa1, &a1neg);
|
||||
@ -237,3 +379,5 @@ bool pairings_verify(const blst_p1 *a1, const blst_p2 *a2, const blst_p1 *b1, co
|
||||
|
||||
return blst_fp12_is_one(>_point);
|
||||
}
|
||||
|
||||
#endif // BLST
|
124
src/bls12_381.h
Normal file
124
src/bls12_381.h
Normal 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file bls12_381.h
|
||||
*
|
||||
* Interface for cryptographic library functions, allowing different libraries to be supported.
|
||||
*/
|
||||
|
||||
#ifndef BLS12_381_H
|
||||
#define BLS12_381_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include "c_kzg.h"
|
||||
|
||||
// BLST is our only option for now
|
||||
#ifndef BLST
|
||||
#define BLST
|
||||
#endif
|
||||
|
||||
// Settings for linking with the BLST library
|
||||
#ifdef BLST
|
||||
|
||||
#include "../inc/blst.h"
|
||||
|
||||
typedef blst_scalar scalar_t; /**< Internal scalar type */
|
||||
typedef blst_fr fr_t; /**< Internal Fr field element type */
|
||||
typedef blst_fp fp_t; /**< Internal Fp field element type (used only for debugging) */
|
||||
typedef blst_fp2 fp2_t; /**< Internal Fp2 field element type (used only for debugging) */
|
||||
typedef blst_p1 g1_t; /**< Internal G1 group element type */
|
||||
typedef blst_p2 g2_t; /**< Internal G2 group element type */
|
||||
|
||||
static const fr_t fr_zero = {0L, 0L, 0L, 0L};
|
||||
|
||||
// This is 1 in Blst's `blst_fr` limb representation. Crazy but true.
|
||||
static const fr_t fr_one = {0x00000001fffffffeL, 0x5884b7fa00034802L, 0x998c4fefecbc4ff5L, 0x1824b159acc5056fL};
|
||||
|
||||
// The G1 identity/infinity
|
||||
static const g1_t g1_identity = {{0L, 0L, 0L, 0L, 0L, 0L}, {0L, 0L, 0L, 0L, 0L, 0L}, {0L, 0L, 0L, 0L, 0L, 0L}};
|
||||
|
||||
static const g1_t g1_generator = {{0x5cb38790fd530c16L, 0x7817fc679976fff5L, 0x154f95c7143ba1c1L, 0xf0ae6acdf3d0e747L,
|
||||
0xedce6ecc21dbf440L, 0x120177419e0bfb75L},
|
||||
{0xbaac93d50ce72271L, 0x8c22631a7918fd8eL, 0xdd595f13570725ceL, 0x51ac582950405194L,
|
||||
0x0e1c8c3fad0059c0L, 0x0bbc3efc5008a26aL},
|
||||
{0x760900000002fffdL, 0xebf4000bc40c0002L, 0x5f48985753c758baL, 0x77ce585370525745L,
|
||||
0x5c071a97a256ec6dL, 0x15f65ec3fa80e493L}};
|
||||
|
||||
static const g1_t g1_negative_generator = {{0x5cb38790fd530c16L, 0x7817fc679976fff5L, 0x154f95c7143ba1c1L,
|
||||
0xf0ae6acdf3d0e747L, 0xedce6ecc21dbf440L, 0x120177419e0bfb75L},
|
||||
{0xff526c2af318883aL, 0x92899ce4383b0270L, 0x89d7738d9fa9d055L,
|
||||
0x12caf35ba344c12aL, 0x3cff1b76964b5317L, 0x0e44d2ede9774430L},
|
||||
{0x760900000002fffdL, 0xebf4000bc40c0002L, 0x5f48985753c758baL,
|
||||
0x77ce585370525745L, 0x5c071a97a256ec6dL, 0x15f65ec3fa80e493L}};
|
||||
|
||||
static const g2_t g2_generator = {{{{0xf5f28fa202940a10L, 0xb3f5fb2687b4961aL, 0xa1a893b53e2ae580L, 0x9894999d1a3caee9L,
|
||||
0x6f67b7631863366bL, 0x058191924350bcd7L},
|
||||
{0xa5a9c0759e23f606L, 0xaaa0c59dbccd60c3L, 0x3bb17e18e2867806L, 0x1b1ab6cc8541b367L,
|
||||
0xc2b6ed0ef2158547L, 0x11922a097360edf3L}}},
|
||||
{{{0x4c730af860494c4aL, 0x597cfa1f5e369c5aL, 0xe7e6856caa0a635aL, 0xbbefb5e96e0d495fL,
|
||||
0x07d3a975f0ef25a2L, 0x0083fd8e7e80dae5L},
|
||||
{0xadc0fc92df64b05dL, 0x18aa270a2b1461dcL, 0x86adac6a3be4eba0L, 0x79495c4ec93da33aL,
|
||||
0xe7175850a43ccaedL, 0x0b2bc2a163de1bf2L}}},
|
||||
{{{0x760900000002fffdL, 0xebf4000bc40c0002L, 0x5f48985753c758baL, 0x77ce585370525745L,
|
||||
0x5c071a97a256ec6dL, 0x15f65ec3fa80e493L},
|
||||
{0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L,
|
||||
0x0000000000000000L, 0x0000000000000000L}}}};
|
||||
|
||||
static const g2_t g2_negative_generator = {{{{0xf5f28fa202940a10L, 0xb3f5fb2687b4961aL, 0xa1a893b53e2ae580L,
|
||||
0x9894999d1a3caee9L, 0x6f67b7631863366bL, 0x058191924350bcd7L},
|
||||
{0xa5a9c0759e23f606L, 0xaaa0c59dbccd60c3L, 0x3bb17e18e2867806L,
|
||||
0x1b1ab6cc8541b367L, 0xc2b6ed0ef2158547L, 0x11922a097360edf3L}}},
|
||||
{{{0x6d8bf5079fb65e61L, 0xc52f05df531d63a5L, 0x7f4a4d344ca692c9L,
|
||||
0xa887959b8577c95fL, 0x4347fe40525c8734L, 0x197d145bbaff0bb5L},
|
||||
{0x0c3e036d209afa4eL, 0x0601d8f4863f9e23L, 0xe0832636bacc0a84L,
|
||||
0xeb2def362a476f84L, 0x64044f659f0ee1e9L, 0x0ed54f48d5a1caa7L}}},
|
||||
{{{0x760900000002fffdL, 0xebf4000bc40c0002L, 0x5f48985753c758baL,
|
||||
0x77ce585370525745L, 0x5c071a97a256ec6dL, 0x15f65ec3fa80e493L},
|
||||
{0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L,
|
||||
0x0000000000000000L, 0x0000000000000000L, 0x0000000000000000L}}}};
|
||||
|
||||
#endif // BLST
|
||||
|
||||
// All the functions in the interface
|
||||
bool fr_is_zero(const fr_t *p);
|
||||
bool fr_is_one(const fr_t *p);
|
||||
void fr_from_scalar(fr_t *out, const scalar_t *a);
|
||||
void fr_from_uint64s(fr_t *out, const uint64_t *vals);
|
||||
void fr_from_uint64(fr_t *out, uint64_t n);
|
||||
bool fr_equal(const fr_t *aa, const fr_t *bb);
|
||||
void fr_negate(fr_t *out, const fr_t *in);
|
||||
void fr_add(fr_t *out, const fr_t *a, const fr_t *b);
|
||||
void fr_sub(fr_t *out, const fr_t *a, const fr_t *b);
|
||||
void fr_mul(fr_t *out, const fr_t *a, const fr_t *b);
|
||||
void fr_inv(fr_t *out, const fr_t *a);
|
||||
void fr_div(fr_t *out, const fr_t *a, const fr_t *b);
|
||||
void fr_sqr(fr_t *out, const fr_t *a);
|
||||
void fr_pow(fr_t *out, const fr_t *a, uint64_t n);
|
||||
bool g1_is_inf(const g1_t *a);
|
||||
void g1_dbl(g1_t *out, const g1_t *a);
|
||||
void g1_add_or_dbl(g1_t *out, const g1_t *a, const g1_t *b);
|
||||
bool g1_equal(const g1_t *a, const g1_t *b);
|
||||
void g1_mul(g1_t *out, const g1_t *a, const fr_t *b);
|
||||
void g1_sub(g1_t *out, const g1_t *a, const g1_t *b);
|
||||
bool g2_equal(const g2_t *a, const g2_t *b);
|
||||
void g2_mul(g2_t *out, const g2_t *a, const fr_t *b);
|
||||
void g2_sub(g2_t *out, const g2_t *a, const g2_t *b);
|
||||
void g2_dbl(g2_t *out, const g2_t *a);
|
||||
void g1_linear_combination(g1_t *out, const g1_t *p, const fr_t *coeffs, const uint64_t len);
|
||||
bool pairings_verify(const g1_t *a1, const g2_t *a2, const g1_t *b1, const g2_t *b2);
|
||||
|
||||
#endif // BLS12_381_H
|
@ -15,15 +15,14 @@
|
||||
*/
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
#include "debug_util.h"
|
||||
#include "test_util.h"
|
||||
#include "blst_util.h"
|
||||
#include "bls12_381.h"
|
||||
|
||||
// This is -1 (the second root of unity)
|
||||
uint64_t m1[] = {0xffffffff00000000L, 0x53bda402fffe5bfeL, 0x3339d80809a1d805L, 0x73eda753299d7d48L};
|
||||
|
||||
void fr_is_zero_works(void) {
|
||||
blst_fr zero;
|
||||
fr_t zero;
|
||||
fr_from_uint64(&zero, 0);
|
||||
TEST_CHECK(fr_is_zero(&zero));
|
||||
}
|
||||
@ -33,7 +32,7 @@ void fr_is_one_works(void) {
|
||||
}
|
||||
|
||||
void fr_from_uint64_works(void) {
|
||||
blst_fr a;
|
||||
fr_t a;
|
||||
fr_from_uint64(&a, 1);
|
||||
TEST_CHECK(fr_is_one(&a));
|
||||
}
|
||||
@ -42,16 +41,16 @@ void fr_equal_works(void) {
|
||||
// A couple of arbitrary roots of unity
|
||||
uint64_t aa[] = {0x0001000000000000L, 0xec03000276030000L, 0x8d51ccce760304d0L, 0x0000000000000000L};
|
||||
uint64_t bb[] = {0x8dd702cb688bc087L, 0xa032824078eaa4feL, 0xa733b23a98ca5b22L, 0x3f96405d25a31660L};
|
||||
blst_fr a, b;
|
||||
blst_fr_from_uint64(&a, aa);
|
||||
blst_fr_from_uint64(&b, bb);
|
||||
fr_t a, b;
|
||||
fr_from_uint64s(&a, aa);
|
||||
fr_from_uint64s(&b, bb);
|
||||
TEST_CHECK(true == fr_equal(&a, &a));
|
||||
TEST_CHECK(false == fr_equal(&a, &b));
|
||||
}
|
||||
|
||||
void fr_negate_works(void) {
|
||||
blst_fr minus1, res;
|
||||
blst_fr_from_uint64(&minus1, m1);
|
||||
fr_t minus1, res;
|
||||
fr_from_uint64s(&minus1, m1);
|
||||
fr_negate(&res, &minus1);
|
||||
TEST_CHECK(fr_is_one(&res));
|
||||
}
|
||||
@ -59,13 +58,13 @@ void fr_negate_works(void) {
|
||||
void fr_pow_works(void) {
|
||||
// a^pow
|
||||
uint64_t pow = 123456;
|
||||
blst_fr a, expected, actual;
|
||||
fr_t 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);
|
||||
fr_mul(&expected, &expected, &a);
|
||||
}
|
||||
|
||||
// Do it the quick way
|
||||
@ -75,123 +74,101 @@ void fr_pow_works(void) {
|
||||
}
|
||||
|
||||
void fr_div_works(void) {
|
||||
blst_fr a, b, tmp, actual;
|
||||
fr_t 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);
|
||||
fr_mul(&actual, &tmp, &b);
|
||||
|
||||
TEST_CHECK(fr_equal(&a, &actual));
|
||||
}
|
||||
|
||||
void p1_mul_works(void) {
|
||||
blst_fr minus1;
|
||||
blst_p1 g1_gen, g1_gen_neg, res;
|
||||
fr_t minus1;
|
||||
g1_t res;
|
||||
|
||||
// Multiply the generator by minus one (the second root of unity)
|
||||
blst_p1_from_affine(&g1_gen, &BLS12_381_G1);
|
||||
blst_fr_from_uint64(&minus1, m1);
|
||||
p1_mul(&res, &g1_gen, &minus1);
|
||||
fr_from_uint64s(&minus1, m1);
|
||||
g1_mul(&res, &g1_generator, &minus1);
|
||||
|
||||
// We should end up with negative the generator
|
||||
blst_p1_from_affine(&g1_gen_neg, &BLS12_381_NEG_G1);
|
||||
|
||||
TEST_CHECK(blst_p1_is_equal(&res, &g1_gen_neg));
|
||||
TEST_CHECK(g1_equal(&res, &g1_negative_generator));
|
||||
}
|
||||
|
||||
void p1_sub_works(void) {
|
||||
blst_p1 g1_gen, g1_gen_neg;
|
||||
blst_p1 tmp, res;
|
||||
|
||||
blst_p1_from_affine(&g1_gen, &BLS12_381_G1);
|
||||
blst_p1_from_affine(&g1_gen_neg, &BLS12_381_NEG_G1);
|
||||
g1_t tmp, res;
|
||||
|
||||
// 2 * g1_gen = g1_gen - g1_gen_neg
|
||||
blst_p1_double(&tmp, &g1_gen);
|
||||
p1_sub(&res, &g1_gen, &g1_gen_neg);
|
||||
g1_dbl(&tmp, &g1_generator);
|
||||
g1_sub(&res, &g1_generator, &g1_negative_generator);
|
||||
|
||||
TEST_CHECK(blst_p1_is_equal(&tmp, &res));
|
||||
TEST_CHECK(g1_equal(&tmp, &res));
|
||||
}
|
||||
|
||||
void p2_mul_works(void) {
|
||||
blst_fr minus1;
|
||||
blst_p2 g2_gen, g2_gen_neg, res;
|
||||
fr_t minus1;
|
||||
g2_t res;
|
||||
|
||||
// Multiply the generator by minus one (the second root of unity)
|
||||
blst_p2_from_affine(&g2_gen, &BLS12_381_G2);
|
||||
blst_fr_from_uint64(&minus1, m1);
|
||||
p2_mul(&res, &g2_gen, &minus1);
|
||||
fr_from_uint64s(&minus1, m1);
|
||||
g2_mul(&res, &g2_generator, &minus1);
|
||||
|
||||
// We should end up with negative the generator
|
||||
blst_p2_from_affine(&g2_gen_neg, &BLS12_381_NEG_G2);
|
||||
|
||||
TEST_CHECK(blst_p2_is_equal(&res, &g2_gen_neg));
|
||||
TEST_CHECK(g2_equal(&res, &g2_negative_generator));
|
||||
}
|
||||
|
||||
void p2_sub_works(void) {
|
||||
blst_p2 g2_gen, g2_gen_neg;
|
||||
blst_p2 tmp, res;
|
||||
|
||||
blst_p2_from_affine(&g2_gen, &BLS12_381_G2);
|
||||
blst_p2_from_affine(&g2_gen_neg, &BLS12_381_NEG_G2);
|
||||
g2_t tmp, res;
|
||||
|
||||
// 2 * g2_gen = g2_gen - g2_gen_neg
|
||||
blst_p2_double(&tmp, &g2_gen);
|
||||
p2_sub(&res, &g2_gen, &g2_gen_neg);
|
||||
g2_dbl(&tmp, &g2_generator);
|
||||
g2_sub(&res, &g2_generator, &g2_negative_generator);
|
||||
|
||||
TEST_CHECK(blst_p2_is_equal(&tmp, &res));
|
||||
}
|
||||
|
||||
void g1_identity_affine_is_infinity(void) {
|
||||
blst_p1 actual;
|
||||
blst_p1_from_affine(&actual, &g1_identity_affine);
|
||||
TEST_CHECK(blst_p1_is_inf(&actual));
|
||||
TEST_CHECK(g2_equal(&tmp, &res));
|
||||
}
|
||||
|
||||
void g1_identity_is_infinity(void) {
|
||||
TEST_CHECK(blst_p1_is_inf(&g1_identity));
|
||||
TEST_CHECK(g1_is_inf(&g1_identity));
|
||||
}
|
||||
|
||||
void g1_identity_is_identity(void) {
|
||||
blst_p1 actual;
|
||||
blst_p1_add(&actual, blst_p1_generator(), &g1_identity);
|
||||
TEST_CHECK(blst_p1_is_equal(blst_p1_generator(), &actual));
|
||||
g1_t actual;
|
||||
g1_add_or_dbl(&actual, &g1_generator, &g1_identity);
|
||||
TEST_CHECK(g1_equal(&g1_generator, &actual));
|
||||
}
|
||||
|
||||
void g1_linear_combination(void) {
|
||||
void g1_make_linear_combination(void) {
|
||||
int len = 255;
|
||||
blst_fr coeffs[len], tmp;
|
||||
blst_p1 p[len], res, exp, g1_gen;
|
||||
fr_t coeffs[len], tmp;
|
||||
g1_t p[len], res, exp;
|
||||
for (int i = 0; i < len; i++) {
|
||||
fr_from_uint64(coeffs + i, i + 1);
|
||||
blst_p1_from_affine(p + i, &BLS12_381_G1);
|
||||
p[i] = g1_generator;
|
||||
}
|
||||
|
||||
// Expected result
|
||||
fr_from_uint64(&tmp, len * (len + 1) / 2);
|
||||
blst_p1_from_affine(&g1_gen, &BLS12_381_G1);
|
||||
p1_mul(&exp, &g1_gen, &tmp);
|
||||
g1_mul(&exp, &g1_generator, &tmp);
|
||||
|
||||
// Test result
|
||||
linear_combination_g1(&res, p, coeffs, len);
|
||||
TEST_CHECK(blst_p1_is_equal(&exp, &res));
|
||||
g1_linear_combination(&res, p, coeffs, len);
|
||||
TEST_CHECK(g1_equal(&exp, &res));
|
||||
}
|
||||
|
||||
void pairings_work(void) {
|
||||
// Verify that e([3]g1, [5]g2) = e([5]g1, [3]g2)
|
||||
blst_fr three, five;
|
||||
blst_p1 g1_3, g1_5;
|
||||
blst_p2 g2_3, g2_5;
|
||||
fr_t three, five;
|
||||
g1_t g1_3, g1_5;
|
||||
g2_t g2_3, g2_5;
|
||||
|
||||
// Set up
|
||||
fr_from_uint64(&three, 3);
|
||||
fr_from_uint64(&five, 5);
|
||||
p1_mul(&g1_3, blst_p1_generator(), &three);
|
||||
p1_mul(&g1_5, blst_p1_generator(), &five);
|
||||
p2_mul(&g2_3, blst_p2_generator(), &three);
|
||||
p2_mul(&g2_5, blst_p2_generator(), &five);
|
||||
g1_mul(&g1_3, &g1_generator, &three);
|
||||
g1_mul(&g1_5, &g1_generator, &five);
|
||||
g2_mul(&g2_3, &g2_generator, &three);
|
||||
g2_mul(&g2_5, &g2_generator, &five);
|
||||
|
||||
// Verify the pairing
|
||||
TEST_CHECK(true == pairings_verify(&g1_3, &g2_5, &g1_5, &g2_3));
|
||||
@ -199,7 +176,7 @@ void pairings_work(void) {
|
||||
}
|
||||
|
||||
TEST_LIST = {
|
||||
{"BLST_UTIL_TEST", title},
|
||||
{"BLS12_384_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},
|
||||
@ -211,10 +188,9 @@ TEST_LIST = {
|
||||
{"p1_sub_works", p1_sub_works},
|
||||
{"p2_mul_works", p2_mul_works},
|
||||
{"p2_sub_works", p2_sub_works},
|
||||
{"g1_identity_affine_is_infinity", g1_identity_affine_is_infinity},
|
||||
{"g1_identity_is_infinity", g1_identity_is_infinity},
|
||||
{"g1_identity_is_identity", g1_identity_is_identity},
|
||||
{"g1_linear_combination", g1_linear_combination},
|
||||
{"g1_make_linear_combination", g1_make_linear_combination},
|
||||
{"pairings_work", pairings_work},
|
||||
{NULL, NULL} /* zero record marks the end of the list */
|
||||
};
|
@ -1,44 +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.
|
||||
*/
|
||||
|
||||
/** @file blst_util.h */
|
||||
|
||||
#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 fr_one = {0x00000001fffffffeL, 0x5884b7fa00034802L, 0x998c4fefecbc4ff5L, 0x1824b159acc5056fL};
|
||||
|
||||
// The G1 identity/infinity in affine representation
|
||||
static const blst_p1_affine g1_identity_affine = {{0L, 0L, 0L, 0L, 0L, 0L}, {0L, 0L, 0L, 0L, 0L, 0L}};
|
||||
|
||||
// The G1 identity/infinity
|
||||
static const blst_p1 g1_identity = {{0L, 0L, 0L, 0L, 0L, 0L}, {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 *out, 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 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_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_sub(blst_p2 *out, const blst_p2 *a, const blst_p2 *b);
|
||||
void linear_combination_g1(blst_p1 *out, const blst_p1 *p, const blst_fr *coeffs, const uint64_t len);
|
||||
bool pairings_verify(const blst_p1 *a1, const blst_p2 *a2, const blst_p1 *b1, const blst_p2 *b2);
|
@ -20,7 +20,6 @@
|
||||
#define C_KZG_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "../inc/blst.h"
|
||||
|
||||
/**
|
||||
* The common return type for all routines in which something can go wrong.
|
||||
|
@ -40,43 +40,43 @@ C_KZG_RET c_kzg_malloc(void **x, size_t n) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate memory for an array of `blst_fr`.
|
||||
* Allocate memory for an array of field elements.
|
||||
*
|
||||
* @remark Free the space later using `free()`.
|
||||
*
|
||||
* @param[out] x Pointer to the allocated space
|
||||
* @param[in] n The number of blst_fr to be allocated
|
||||
* @param[in] n The number of field elements to be allocated
|
||||
* @retval C_CZK_OK All is well
|
||||
* @retval C_CZK_MALLOC Memory allocation failed
|
||||
*/
|
||||
C_KZG_RET new_fr(blst_fr **x, size_t n) {
|
||||
C_KZG_RET new_fr(fr_t **x, size_t n) {
|
||||
return c_kzg_malloc((void **)x, n * sizeof **x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate memory for an array of `blst_p1`.
|
||||
* Allocate memory for an array of G1 group elements.
|
||||
*
|
||||
* @remark Free the space later using `free()`.
|
||||
*
|
||||
* @param[out] x Pointer to the allocated space
|
||||
* @param[in] n The number of blst_p1 to be allocated
|
||||
* @param[in] n The number of G1 elements to be allocated
|
||||
* @retval C_CZK_OK All is well
|
||||
* @retval C_CZK_MALLOC Memory allocation failed
|
||||
*/
|
||||
C_KZG_RET new_p1(blst_p1 **x, size_t n) {
|
||||
C_KZG_RET new_p1(g1_t **x, size_t n) {
|
||||
return c_kzg_malloc((void **)x, n * sizeof **x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate memory for an array of `blst_p2`.
|
||||
* Allocate memory for an array of G2 group elements.
|
||||
*
|
||||
* @remark Free the space later using `free()`.
|
||||
*
|
||||
* @param[out] x Pointer to the allocated space
|
||||
* @param[in] n The number of blst_p2 to be allocated
|
||||
* @param[in] n The number of G2 elements to be allocated
|
||||
* @retval C_CZK_OK All is well
|
||||
* @retval C_CZK_MALLOC Memory allocation failed
|
||||
*/
|
||||
C_KZG_RET new_p2(blst_p2 **x, size_t n) {
|
||||
C_KZG_RET new_p2(g2_t **x, size_t n) {
|
||||
return c_kzg_malloc((void **)x, n * sizeof **x);
|
||||
}
|
||||
|
@ -14,12 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** @file c_kzg_util.c */
|
||||
/** @file c_kzg_util.h */
|
||||
|
||||
#include <stdlib.h> // free()
|
||||
#include "c_kzg.h"
|
||||
#include "bls12_381.h"
|
||||
|
||||
C_KZG_RET c_kzg_malloc(void **p, size_t n);
|
||||
C_KZG_RET new_fr(blst_fr **x, size_t n);
|
||||
C_KZG_RET new_p1(blst_p1 **x, size_t n);
|
||||
C_KZG_RET new_p2(blst_p2 **x, size_t n);
|
||||
C_KZG_RET new_fr(fr_t **x, size_t n);
|
||||
C_KZG_RET new_p1(g1_t **x, size_t n);
|
||||
C_KZG_RET new_p2(g2_t **x, size_t n);
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
#include "debug_util.h"
|
||||
#include "test_util.h"
|
||||
#include "c_kzg_util.h"
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
#include "debug_util.h"
|
||||
|
||||
#ifdef BLST
|
||||
|
||||
//
|
||||
// General Utilities
|
||||
//
|
||||
@ -39,8 +41,8 @@ void print_bytes_as_hex_le(byte *bytes, int start, int len) {
|
||||
//
|
||||
|
||||
// Print a `blst_fr`
|
||||
void print_fr(const blst_fr *a) {
|
||||
blst_scalar b;
|
||||
void print_fr(const fr_t *a) {
|
||||
scalar_t b;
|
||||
blst_scalar_from_fr(&b, a);
|
||||
print_bytes_as_hex_le(b.b, 0, 32);
|
||||
}
|
||||
@ -49,7 +51,7 @@ void print_fr(const blst_fr *a) {
|
||||
// Fp Utilities
|
||||
//
|
||||
|
||||
void print_limbs(const blst_fp *fp) {
|
||||
void print_limbs(const fp_t *fp) {
|
||||
printf("(%08lx, %08lx, %08lx, %08lx, %08lx, %08lx)", fp->l[0], fp->l[1], fp->l[2], fp->l[3], fp->l[4], fp->l[5]);
|
||||
}
|
||||
|
||||
@ -66,21 +68,14 @@ void print_p1_bytes(byte p1[96]) {
|
||||
}
|
||||
|
||||
/* "Pretty" print serialisation of a point in G1 */
|
||||
void print_p1(const blst_p1 *p1) {
|
||||
void print_p1(const g1_t *p1) {
|
||||
byte p1_bytes[96];
|
||||
blst_p1_serialize(p1_bytes, p1);
|
||||
print_p1_bytes(p1_bytes);
|
||||
}
|
||||
|
||||
/* "Pretty" print serialisation of an affine point in G1 */
|
||||
void print_p1_affine(const blst_p1_affine *p1) {
|
||||
byte p1_bytes[96];
|
||||
blst_p1_affine_serialize(p1_bytes, p1);
|
||||
print_p1_bytes(p1_bytes);
|
||||
}
|
||||
|
||||
/* "Pretty" print internals of a point in G1 */
|
||||
void print_p1_limbs(const blst_p1 *p1) {
|
||||
void print_p1_limbs(const g1_t *p1) {
|
||||
printf("x = ");
|
||||
print_limbs(&p1->x);
|
||||
printf(", y = ");
|
||||
@ -90,26 +85,4 @@ void print_p1_limbs(const blst_p1 *p1) {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* "Pretty" print internals of an affine point in G1 */
|
||||
void print_p1_affine_limbs(const blst_p1_affine *p1) {
|
||||
printf("x = ");
|
||||
print_limbs(&p1->x);
|
||||
printf(", y = ");
|
||||
print_limbs(&p1->y);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* "Pretty" print serialisation of an affine point in G2 */
|
||||
void print_p2_affine(const blst_p2_affine *p2) {
|
||||
byte p2_hex[192];
|
||||
blst_p2_affine_serialize(p2_hex, p2);
|
||||
printf("[(0x");
|
||||
print_bytes_as_hex(p2_hex, 0, 48);
|
||||
printf(",0x");
|
||||
print_bytes_as_hex(p2_hex, 48, 48);
|
||||
printf("),(0x");
|
||||
print_bytes_as_hex(p2_hex, 96, 48);
|
||||
printf(",0x");
|
||||
print_bytes_as_hex(p2_hex, 144, 48);
|
||||
printf(")]\n");
|
||||
}
|
||||
#endif // BLST
|
@ -14,25 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "c_kzg.h"
|
||||
|
||||
// General Utilities
|
||||
void print_bytes_as_hex(byte *bytes, int start, int len);
|
||||
void print_bytes_as_hex_le(byte *bytes, int start, int len);
|
||||
#include "bls12_381.h"
|
||||
|
||||
// Fr utilities
|
||||
void print_fr(const blst_fr *a);
|
||||
|
||||
// Fp Utilities
|
||||
void print_limbs(const blst_fp *fp);
|
||||
void print_fr(const fr_t *a);
|
||||
|
||||
// G1 and G2 utilities
|
||||
void print_p1_bytes(byte p1[96]);
|
||||
void print_p1(const blst_p1 *p1);
|
||||
void print_p1_affine(const blst_p1_affine *p1);
|
||||
void print_p1_limbs(const blst_p1 *p1);
|
||||
void print_p1_affine_limbs(const blst_p1_affine *p1);
|
||||
void print_p2_affine(const blst_p2_affine *p2);
|
||||
void print_g1_bytes(byte p1[96]);
|
||||
void print_g1(const g1_t *p1);
|
||||
void print_g1_limbs(const g1_t *p1);
|
@ -21,7 +21,6 @@
|
||||
*/
|
||||
|
||||
#include "fft_common.h"
|
||||
#include "blst_util.h"
|
||||
#include "c_kzg_util.h"
|
||||
|
||||
/**
|
||||
@ -50,13 +49,13 @@ bool is_power_of_two(uint64_t n) {
|
||||
* @retval C_CZK_OK All is well
|
||||
* @retval C_CZK_BADARGS Invalid parameters were supplied
|
||||
*/
|
||||
C_KZG_RET expand_root_of_unity(blst_fr *out, const blst_fr *root, uint64_t width) {
|
||||
C_KZG_RET expand_root_of_unity(fr_t *out, const fr_t *root, uint64_t width) {
|
||||
out[0] = fr_one;
|
||||
out[1] = *root;
|
||||
|
||||
for (uint64_t i = 2; !fr_is_one(&out[i - 1]); i++) {
|
||||
ASSERT(i <= width, C_KZG_BADARGS);
|
||||
blst_fr_mul(&out[i], &out[i - 1], root);
|
||||
fr_mul(&out[i], &out[i - 1], root);
|
||||
}
|
||||
ASSERT(fr_is_one(&out[width]), C_KZG_BADARGS);
|
||||
|
||||
@ -87,7 +86,7 @@ C_KZG_RET new_fft_settings(FFTSettings *fs, unsigned int max_scale) {
|
||||
fs->max_width = (uint64_t)1 << max_scale;
|
||||
|
||||
ASSERT((max_scale < sizeof scale2_root_of_unity / sizeof scale2_root_of_unity[0]), C_KZG_BADARGS);
|
||||
blst_fr_from_uint64(&fs->root_of_unity, scale2_root_of_unity[max_scale]);
|
||||
fr_from_uint64s(&fs->root_of_unity, scale2_root_of_unity[max_scale]);
|
||||
|
||||
// Allocate space for the roots of unity
|
||||
TRY(new_fr(&fs->expanded_roots_of_unity, fs->max_width + 1));
|
||||
|
@ -20,12 +20,13 @@
|
||||
#define FFT_COMMON
|
||||
|
||||
#include "c_kzg.h"
|
||||
#include "bls12_381.h"
|
||||
|
||||
/**
|
||||
* The first 32 roots of unity in the finite field F_r.
|
||||
*
|
||||
* For element `{A, B, C, D}`, the field element value is `A + B * 2^64 + C * 2^128 + D * 2^192`. This format may be
|
||||
* converted to a `blst_fr` type via the blst_fr_from_uint64() library function.
|
||||
* converted to an `fr_t` type via the #fr_from_uint64s library function.
|
||||
*
|
||||
* The decimal values may be calculated with the following Python code:
|
||||
* @code{.py}
|
||||
@ -74,14 +75,14 @@ static const uint64_t scale2_root_of_unity[][4] = {
|
||||
* Initialise with #new_fft_settings. Free after use with #free_fft_settings.
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t max_width; /**< The maximum size of FFT these settings support, a power of 2. */
|
||||
blst_fr root_of_unity; /**< The root of unity used to generate the lists in the structure. */
|
||||
blst_fr *expanded_roots_of_unity; /**< Ascending powers of the root of unity, size `width + 1`. */
|
||||
blst_fr *reverse_roots_of_unity; /**< Descending powers of the root of unity, size `width + 1`. */
|
||||
uint64_t max_width; /**< The maximum size of FFT these settings support, a power of 2. */
|
||||
fr_t root_of_unity; /**< The root of unity used to generate the lists in the structure. */
|
||||
fr_t *expanded_roots_of_unity; /**< Ascending powers of the root of unity, size `width + 1`. */
|
||||
fr_t *reverse_roots_of_unity; /**< Descending powers of the root of unity, size `width + 1`. */
|
||||
} FFTSettings;
|
||||
|
||||
bool is_power_of_two(uint64_t n);
|
||||
C_KZG_RET expand_root_of_unity(blst_fr *out, const blst_fr *root, uint64_t width);
|
||||
C_KZG_RET expand_root_of_unity(fr_t *out, const fr_t *root, uint64_t width);
|
||||
C_KZG_RET new_fft_settings(FFTSettings *s, unsigned int max_scale);
|
||||
void free_fft_settings(FFTSettings *s);
|
||||
|
||||
|
@ -15,10 +15,8 @@
|
||||
*/
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
#include "debug_util.h"
|
||||
#include "test_util.h"
|
||||
#include "fft_common.h"
|
||||
#include "blst_util.h"
|
||||
|
||||
#define NUM_ROOTS 32
|
||||
|
||||
@ -32,11 +30,11 @@ void roots_of_unity_out_of_bounds_fails(void) {
|
||||
}
|
||||
|
||||
void roots_of_unity_are_plausible(void) {
|
||||
blst_fr r;
|
||||
fr_t r;
|
||||
for (int i = 0; i < NUM_ROOTS; i++) {
|
||||
blst_fr_from_uint64(&r, scale2_root_of_unity[i]);
|
||||
fr_from_uint64s(&r, scale2_root_of_unity[i]);
|
||||
for (int j = 0; j < i; j++) {
|
||||
blst_fr_sqr(&r, &r);
|
||||
fr_sqr(&r, &r);
|
||||
}
|
||||
TEST_CHECK(true == fr_is_one(&r));
|
||||
TEST_MSG("Root %d failed", i);
|
||||
@ -47,17 +45,17 @@ void expand_roots_is_plausible(void) {
|
||||
// Just test one (largeish) value of scale
|
||||
unsigned int scale = 15;
|
||||
unsigned int width = 1 << scale;
|
||||
blst_fr root, expanded[width + 1], prod;
|
||||
fr_t root, expanded[width + 1], prod;
|
||||
|
||||
// Initialise
|
||||
blst_fr_from_uint64(&root, scale2_root_of_unity[scale]);
|
||||
fr_from_uint64s(&root, scale2_root_of_unity[scale]);
|
||||
TEST_CHECK(expand_root_of_unity(expanded, &root, width) == C_KZG_OK);
|
||||
|
||||
// Verify - each pair should multiply to one
|
||||
TEST_CHECK(true == fr_is_one(expanded + 0));
|
||||
TEST_CHECK(true == fr_is_one(expanded + width));
|
||||
for (unsigned int i = 1; i <= width / 2; i++) {
|
||||
blst_fr_mul(&prod, expanded + i, expanded + width - i);
|
||||
fr_mul(&prod, expanded + i, expanded + width - i);
|
||||
TEST_CHECK(true == fr_is_one(&prod));
|
||||
}
|
||||
}
|
||||
@ -66,14 +64,14 @@ void new_fft_settings_is_plausible(void) {
|
||||
// Just test one (largeish) value of scale
|
||||
int scale = 21;
|
||||
unsigned int width = 1 << scale;
|
||||
blst_fr prod;
|
||||
fr_t prod;
|
||||
FFTSettings s;
|
||||
|
||||
TEST_CHECK(new_fft_settings(&s, scale) == C_KZG_OK);
|
||||
|
||||
// Verify - each pair should multiply to one
|
||||
for (unsigned int i = 1; i <= width; i++) {
|
||||
blst_fr_mul(&prod, s.expanded_roots_of_unity + i, s.reverse_roots_of_unity + i);
|
||||
fr_mul(&prod, s.expanded_roots_of_unity + i, s.reverse_roots_of_unity + i);
|
||||
TEST_CHECK(true == fr_is_one(&prod));
|
||||
}
|
||||
|
||||
|
31
src/fft_fr.c
31
src/fft_fr.c
@ -26,7 +26,6 @@
|
||||
*/
|
||||
|
||||
#include "fft_fr.h"
|
||||
#include "blst_util.h"
|
||||
#include "c_kzg_util.h"
|
||||
|
||||
/**
|
||||
@ -41,16 +40,15 @@
|
||||
* @param[in] roots_stride The stride interval among the roots of unity
|
||||
* @param[in] n Length of the FFT, must be a power of two
|
||||
*/
|
||||
void fft_fr_slow(blst_fr *out, const blst_fr *in, uint64_t stride, const blst_fr *roots, uint64_t roots_stride,
|
||||
uint64_t n) {
|
||||
blst_fr v, last, jv, r;
|
||||
void fft_fr_slow(fr_t *out, const fr_t *in, uint64_t stride, const fr_t *roots, uint64_t roots_stride, uint64_t n) {
|
||||
fr_t v, last, jv, r;
|
||||
for (uint64_t i = 0; i < n; i++) {
|
||||
blst_fr_mul(&last, &in[0], &roots[0]);
|
||||
fr_mul(&last, &in[0], &roots[0]);
|
||||
for (uint64_t j = 1; j < n; j++) {
|
||||
jv = in[j * stride];
|
||||
r = roots[((i * j) % n) * roots_stride];
|
||||
blst_fr_mul(&v, &jv, &r);
|
||||
blst_fr_add(&last, &last, &v);
|
||||
fr_mul(&v, &jv, &r);
|
||||
fr_add(&last, &last, &v);
|
||||
}
|
||||
out[i] = last;
|
||||
}
|
||||
@ -68,17 +66,16 @@ void fft_fr_slow(blst_fr *out, const blst_fr *in, uint64_t stride, const blst_fr
|
||||
* @param[in] roots_stride The stride interval among the roots of unity
|
||||
* @param[in] n Length of the FFT, must be a power of two
|
||||
*/
|
||||
void fft_fr_fast(blst_fr *out, const blst_fr *in, uint64_t stride, const blst_fr *roots, uint64_t roots_stride,
|
||||
uint64_t n) {
|
||||
void fft_fr_fast(fr_t *out, const fr_t *in, uint64_t stride, const fr_t *roots, uint64_t roots_stride, uint64_t n) {
|
||||
uint64_t half = n / 2;
|
||||
if (half > 0) { // Tunable parameter
|
||||
fft_fr_fast(out, in, stride * 2, roots, roots_stride * 2, half);
|
||||
fft_fr_fast(out + half, in + stride, stride * 2, roots, roots_stride * 2, half);
|
||||
for (uint64_t i = 0; i < half; i++) {
|
||||
blst_fr y_times_root;
|
||||
blst_fr_mul(&y_times_root, &out[i + half], &roots[i * roots_stride]);
|
||||
blst_fr_sub(&out[i + half], &out[i], &y_times_root);
|
||||
blst_fr_add(&out[i], &out[i], &y_times_root);
|
||||
fr_t y_times_root;
|
||||
fr_mul(&y_times_root, &out[i + half], &roots[i * roots_stride]);
|
||||
fr_sub(&out[i + half], &out[i], &y_times_root);
|
||||
fr_add(&out[i], &out[i], &y_times_root);
|
||||
}
|
||||
} else {
|
||||
fft_fr_slow(out, in, stride, roots, roots_stride, n);
|
||||
@ -96,17 +93,17 @@ void fft_fr_fast(blst_fr *out, const blst_fr *in, uint64_t stride, const blst_fr
|
||||
* @retval C_CZK_OK All is well
|
||||
* @retval C_CZK_BADARGS Invalid parameters were supplied
|
||||
*/
|
||||
C_KZG_RET fft_fr(blst_fr *out, const blst_fr *in, bool inverse, uint64_t n, const FFTSettings *fs) {
|
||||
C_KZG_RET fft_fr(fr_t *out, const fr_t *in, bool inverse, uint64_t n, const FFTSettings *fs) {
|
||||
uint64_t stride = fs->max_width / n;
|
||||
ASSERT(n <= fs->max_width, C_KZG_BADARGS);
|
||||
ASSERT(is_power_of_two(n), C_KZG_BADARGS);
|
||||
if (inverse) {
|
||||
blst_fr inv_len;
|
||||
fr_t inv_len;
|
||||
fr_from_uint64(&inv_len, n);
|
||||
blst_fr_eucl_inverse(&inv_len, &inv_len);
|
||||
fr_inv(&inv_len, &inv_len);
|
||||
fft_fr_fast(out, in, 1, fs->reverse_roots_of_unity, stride, n);
|
||||
for (uint64_t i = 0; i < n; i++) {
|
||||
blst_fr_mul(&out[i], &out[i], &inv_len);
|
||||
fr_mul(&out[i], &out[i], &inv_len);
|
||||
}
|
||||
} else {
|
||||
fft_fr_fast(out, in, 1, fs->expanded_roots_of_unity, stride, n);
|
||||
|
@ -18,8 +18,6 @@
|
||||
|
||||
#include "fft_common.h"
|
||||
|
||||
void fft_fr_slow(blst_fr *out, const blst_fr *in, uint64_t stride, const blst_fr *roots, uint64_t roots_stride,
|
||||
uint64_t n);
|
||||
void fft_fr_fast(blst_fr *out, const blst_fr *in, uint64_t stride, const blst_fr *roots, uint64_t roots_stride,
|
||||
uint64_t n);
|
||||
C_KZG_RET fft_fr(blst_fr *out, const blst_fr *in, bool inverse, uint64_t n, const FFTSettings *fs);
|
||||
void fft_fr_slow(fr_t *out, const fr_t *in, uint64_t stride, const fr_t *roots, uint64_t roots_stride, uint64_t n);
|
||||
void fft_fr_fast(fr_t *out, const fr_t *in, uint64_t stride, const fr_t *roots, uint64_t roots_stride, uint64_t n);
|
||||
C_KZG_RET fft_fr(fr_t *out, const fr_t *in, bool inverse, uint64_t n, const FFTSettings *fs);
|
||||
|
@ -30,9 +30,9 @@ long run_bench(int scale, int max_seconds) {
|
||||
assert(C_KZG_OK == new_fft_settings(&fs, scale));
|
||||
|
||||
// Allocate on the heap to avoid stack overflow for large sizes
|
||||
blst_fr *data, *out;
|
||||
data = malloc(fs.max_width * sizeof(blst_fr));
|
||||
out = malloc(fs.max_width * sizeof(blst_fr));
|
||||
fr_t *data, *out;
|
||||
data = malloc(fs.max_width * sizeof(fr_t));
|
||||
out = malloc(fs.max_width * sizeof(fr_t));
|
||||
|
||||
// Fill with randomness
|
||||
for (uint64_t i = 0; i < fs.max_width; i++) {
|
||||
|
@ -15,10 +15,8 @@
|
||||
*/
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
#include "debug_util.h"
|
||||
#include "test_util.h"
|
||||
#include "fft_fr.h"
|
||||
#include "blst_util.h"
|
||||
|
||||
const uint64_t inv_fft_expected[][4] = {
|
||||
{0x7fffffff80000008L, 0xa9ded2017fff2dffL, 0x199cec0404d0ec02L, 0x39f6d3a994cebea4L},
|
||||
@ -43,7 +41,7 @@ void compare_sft_fft(void) {
|
||||
unsigned int size = 12;
|
||||
FFTSettings fs;
|
||||
TEST_CHECK(new_fft_settings(&fs, size) == C_KZG_OK);
|
||||
blst_fr data[fs.max_width], out0[fs.max_width], out1[fs.max_width];
|
||||
fr_t data[fs.max_width], out0[fs.max_width], out1[fs.max_width];
|
||||
for (int i = 0; i < fs.max_width; i++) {
|
||||
fr_from_uint64(data + i, i);
|
||||
}
|
||||
@ -65,7 +63,7 @@ void roundtrip_fft(void) {
|
||||
unsigned int size = 12;
|
||||
FFTSettings fs;
|
||||
TEST_CHECK(new_fft_settings(&fs, size) == C_KZG_OK);
|
||||
blst_fr data[fs.max_width], coeffs[fs.max_width];
|
||||
fr_t data[fs.max_width], coeffs[fs.max_width];
|
||||
for (int i = 0; i < fs.max_width; i++) {
|
||||
fr_from_uint64(data + i, i);
|
||||
}
|
||||
@ -76,7 +74,7 @@ void roundtrip_fft(void) {
|
||||
|
||||
// Verify that the result is still ascending values of i
|
||||
for (int i = 0; i < fs.max_width; i++) {
|
||||
blst_fr tmp;
|
||||
fr_t tmp;
|
||||
fr_from_uint64(&tmp, i);
|
||||
TEST_CHECK(fr_equal(&tmp, data + i));
|
||||
}
|
||||
@ -88,7 +86,7 @@ void inverse_fft(void) {
|
||||
// Initialise: ascending values of i
|
||||
FFTSettings fs;
|
||||
TEST_CHECK(new_fft_settings(&fs, 4) == C_KZG_OK);
|
||||
blst_fr data[fs.max_width], out[fs.max_width];
|
||||
fr_t data[fs.max_width], out[fs.max_width];
|
||||
for (int i = 0; i < fs.max_width; i++) {
|
||||
fr_from_uint64(&data[i], i);
|
||||
}
|
||||
@ -100,8 +98,8 @@ void inverse_fft(void) {
|
||||
int n = sizeof inv_fft_expected / sizeof inv_fft_expected[0];
|
||||
TEST_CHECK(n == fs.max_width);
|
||||
for (int i = 0; i < n; i++) {
|
||||
blst_fr expected;
|
||||
blst_fr_from_uint64(&expected, inv_fft_expected[i]);
|
||||
fr_t expected;
|
||||
fr_from_uint64s(&expected, inv_fft_expected[i]);
|
||||
TEST_CHECK(fr_equal(&expected, &out[i]));
|
||||
}
|
||||
|
||||
@ -114,7 +112,7 @@ void stride_fft(void) {
|
||||
FFTSettings fs1, fs2;
|
||||
TEST_CHECK(new_fft_settings(&fs1, size1) == C_KZG_OK);
|
||||
TEST_CHECK(new_fft_settings(&fs2, size2) == C_KZG_OK);
|
||||
blst_fr data[width], coeffs1[width], coeffs2[width];
|
||||
fr_t data[width], coeffs1[width], coeffs2[width];
|
||||
for (int i = 0; i < width; i++) {
|
||||
fr_from_uint64(data + i, i);
|
||||
}
|
||||
|
33
src/fft_g1.c
33
src/fft_g1.c
@ -26,7 +26,6 @@
|
||||
*/
|
||||
|
||||
#include "fft_g1.h"
|
||||
#include "blst_util.h"
|
||||
#include "c_kzg_util.h"
|
||||
|
||||
/**
|
||||
@ -41,17 +40,16 @@
|
||||
* @param[in] roots_stride The stride interval among the roots of unity
|
||||
* @param[in] n Length of the FFT, must be a power of two
|
||||
*/
|
||||
void fft_g1_slow(blst_p1 *out, const blst_p1 *in, uint64_t stride, const blst_fr *roots, uint64_t roots_stride,
|
||||
uint64_t n) {
|
||||
blst_p1 v, last, jv;
|
||||
blst_fr r;
|
||||
void fft_g1_slow(g1_t *out, const g1_t *in, uint64_t stride, const fr_t *roots, uint64_t roots_stride, uint64_t n) {
|
||||
g1_t v, last, jv;
|
||||
fr_t r;
|
||||
for (uint64_t i = 0; i < n; i++) {
|
||||
p1_mul(&last, &in[0], &roots[0]);
|
||||
g1_mul(&last, &in[0], &roots[0]);
|
||||
for (uint64_t j = 1; j < n; j++) {
|
||||
jv = in[j * stride];
|
||||
r = roots[((i * j) % n) * roots_stride];
|
||||
p1_mul(&v, &jv, &r);
|
||||
blst_p1_add_or_double(&last, &last, &v);
|
||||
g1_mul(&v, &jv, &r);
|
||||
g1_add_or_dbl(&last, &last, &v);
|
||||
}
|
||||
out[i] = last;
|
||||
}
|
||||
@ -69,17 +67,16 @@ void fft_g1_slow(blst_p1 *out, const blst_p1 *in, uint64_t stride, const blst_fr
|
||||
* @param[in] roots_stride The stride interval among the roots of unity
|
||||
* @param[in] n Length of the FFT, must be a power of two
|
||||
*/
|
||||
void fft_g1_fast(blst_p1 *out, const blst_p1 *in, uint64_t stride, const blst_fr *roots, uint64_t roots_stride,
|
||||
uint64_t n) {
|
||||
void fft_g1_fast(g1_t *out, const g1_t *in, uint64_t stride, const fr_t *roots, uint64_t roots_stride, uint64_t n) {
|
||||
uint64_t half = n / 2;
|
||||
if (half > 0) { // Tunable parameter
|
||||
fft_g1_fast(out, in, stride * 2, roots, roots_stride * 2, half);
|
||||
fft_g1_fast(out + half, in + stride, stride * 2, roots, roots_stride * 2, half);
|
||||
for (uint64_t i = 0; i < half; i++) {
|
||||
blst_p1 y_times_root;
|
||||
p1_mul(&y_times_root, &out[i + half], &roots[i * roots_stride]);
|
||||
p1_sub(&out[i + half], &out[i], &y_times_root);
|
||||
blst_p1_add_or_double(&out[i], &out[i], &y_times_root);
|
||||
g1_t y_times_root;
|
||||
g1_mul(&y_times_root, &out[i + half], &roots[i * roots_stride]);
|
||||
g1_sub(&out[i + half], &out[i], &y_times_root);
|
||||
g1_add_or_dbl(&out[i], &out[i], &y_times_root);
|
||||
}
|
||||
} else {
|
||||
fft_g1_slow(out, in, stride, roots, roots_stride, n);
|
||||
@ -97,17 +94,17 @@ void fft_g1_fast(blst_p1 *out, const blst_p1 *in, uint64_t stride, const blst_fr
|
||||
* @retval C_CZK_OK All is well
|
||||
* @retval C_CZK_BADARGS Invalid parameters were supplied
|
||||
*/
|
||||
C_KZG_RET fft_g1(blst_p1 *out, const blst_p1 *in, bool inverse, uint64_t n, const FFTSettings *fs) {
|
||||
C_KZG_RET fft_g1(g1_t *out, const g1_t *in, bool inverse, uint64_t n, const FFTSettings *fs) {
|
||||
uint64_t stride = fs->max_width / n;
|
||||
ASSERT(n <= fs->max_width, C_KZG_BADARGS);
|
||||
ASSERT(is_power_of_two(n), C_KZG_BADARGS);
|
||||
if (inverse) {
|
||||
blst_fr inv_len;
|
||||
fr_t inv_len;
|
||||
fr_from_uint64(&inv_len, n);
|
||||
blst_fr_eucl_inverse(&inv_len, &inv_len);
|
||||
fr_inv(&inv_len, &inv_len);
|
||||
fft_g1_fast(out, in, 1, fs->reverse_roots_of_unity, stride, n);
|
||||
for (uint64_t i = 0; i < n; i++) {
|
||||
p1_mul(&out[i], &out[i], &inv_len);
|
||||
g1_mul(&out[i], &out[i], &inv_len);
|
||||
}
|
||||
} else {
|
||||
fft_g1_fast(out, in, 1, fs->expanded_roots_of_unity, stride, n);
|
||||
|
@ -18,8 +18,6 @@
|
||||
|
||||
#include "fft_common.h"
|
||||
|
||||
void fft_g1_slow(blst_p1 *out, const blst_p1 *in, uint64_t stride, const blst_fr *roots, uint64_t roots_stride,
|
||||
uint64_t n);
|
||||
void fft_g1_fast(blst_p1 *out, const blst_p1 *in, uint64_t stride, const blst_fr *roots, uint64_t roots_stride,
|
||||
uint64_t n);
|
||||
C_KZG_RET fft_g1(blst_p1 *out, const blst_p1 *in, bool inverse, uint64_t n, const FFTSettings *fs);
|
||||
void fft_g1_slow(g1_t *out, const g1_t *in, uint64_t stride, const fr_t *roots, uint64_t roots_stride, uint64_t n);
|
||||
void fft_g1_fast(g1_t *out, const g1_t *in, uint64_t stride, const fr_t *roots, uint64_t roots_stride, uint64_t n);
|
||||
C_KZG_RET fft_g1(g1_t *out, const g1_t *in, bool inverse, uint64_t n, const FFTSettings *fs);
|
||||
|
@ -30,9 +30,9 @@ long run_bench(int scale, int max_seconds) {
|
||||
assert(C_KZG_OK == new_fft_settings(&fs, scale));
|
||||
|
||||
// Allocate on the heap to avoid stack overflow for large sizes
|
||||
blst_p1 *data, *out;
|
||||
data = malloc(fs.max_width * sizeof(blst_p1));
|
||||
out = malloc(fs.max_width * sizeof(blst_p1));
|
||||
g1_t *data, *out;
|
||||
data = malloc(fs.max_width * sizeof(g1_t));
|
||||
out = malloc(fs.max_width * sizeof(g1_t));
|
||||
|
||||
// Fill with randomness
|
||||
for (uint64_t i = 0; i < fs.max_width; i++) {
|
||||
|
@ -15,16 +15,15 @@
|
||||
*/
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
#include "debug_util.h"
|
||||
#include "test_util.h"
|
||||
#include "fft_g1.h"
|
||||
|
||||
void make_data(blst_p1 *out, uint64_t n) {
|
||||
void make_data(g1_t *out, uint64_t n) {
|
||||
// Multiples of g1_gen
|
||||
if (n == 0) return;
|
||||
blst_p1_from_affine(out + 0, &BLS12_381_G1);
|
||||
*out = g1_generator;
|
||||
for (int i = 1; i < n; i++) {
|
||||
blst_p1_add_or_double_affine(out + i, out + i - 1, &BLS12_381_G1);
|
||||
g1_add_or_dbl(out + i, out + i - 1, &g1_generator);
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,7 +32,7 @@ void compare_sft_fft(void) {
|
||||
unsigned int size = 6;
|
||||
FFTSettings fs;
|
||||
TEST_CHECK(new_fft_settings(&fs, size) == C_KZG_OK);
|
||||
blst_p1 data[fs.max_width], slow[fs.max_width], fast[fs.max_width];
|
||||
g1_t data[fs.max_width], slow[fs.max_width], fast[fs.max_width];
|
||||
make_data(data, fs.max_width);
|
||||
|
||||
// Do both fast and slow transforms
|
||||
@ -42,7 +41,7 @@ void compare_sft_fft(void) {
|
||||
|
||||
// Verify the results are identical
|
||||
for (int i = 0; i < fs.max_width; i++) {
|
||||
TEST_CHECK(blst_p1_is_equal(slow + i, fast + i));
|
||||
TEST_CHECK(g1_equal(slow + i, fast + i));
|
||||
}
|
||||
|
||||
free_fft_settings(&fs);
|
||||
@ -53,7 +52,7 @@ void roundtrip_fft(void) {
|
||||
unsigned int size = 10;
|
||||
FFTSettings fs;
|
||||
TEST_CHECK(new_fft_settings(&fs, size) == C_KZG_OK);
|
||||
blst_p1 expected[fs.max_width], data[fs.max_width], coeffs[fs.max_width];
|
||||
g1_t expected[fs.max_width], data[fs.max_width], coeffs[fs.max_width];
|
||||
make_data(expected, fs.max_width);
|
||||
make_data(data, fs.max_width);
|
||||
|
||||
@ -63,7 +62,7 @@ void roundtrip_fft(void) {
|
||||
|
||||
// Verify that the result is still ascending values of i
|
||||
for (int i = 0; i < fs.max_width; i++) {
|
||||
TEST_CHECK(blst_p1_is_equal(expected + i, data + i));
|
||||
TEST_CHECK(g1_equal(expected + i, data + i));
|
||||
}
|
||||
|
||||
free_fft_settings(&fs);
|
||||
@ -75,14 +74,14 @@ void stride_fft(void) {
|
||||
FFTSettings fs1, fs2;
|
||||
TEST_CHECK(new_fft_settings(&fs1, size1) == C_KZG_OK);
|
||||
TEST_CHECK(new_fft_settings(&fs2, size2) == C_KZG_OK);
|
||||
blst_p1 data[width], coeffs1[width], coeffs2[width];
|
||||
g1_t data[width], coeffs1[width], coeffs2[width];
|
||||
make_data(data, width);
|
||||
|
||||
TEST_CHECK(fft_g1(coeffs1, data, false, width, &fs1) == C_KZG_OK);
|
||||
TEST_CHECK(fft_g1(coeffs2, data, false, width, &fs2) == C_KZG_OK);
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
TEST_CHECK(blst_p1_is_equal(coeffs1 + i, coeffs2 + i));
|
||||
TEST_CHECK(g1_equal(coeffs1 + i, coeffs2 + i));
|
||||
}
|
||||
|
||||
free_fft_settings(&fs1);
|
||||
|
@ -118,9 +118,9 @@ C_KZG_RET reverse_bit_order(void *values, size_t size, uint64_t n) {
|
||||
* @retval C_CZK_ERROR An internal error occurred
|
||||
* @retval C_CZK_MALLOC Memory allocation failed
|
||||
*/
|
||||
C_KZG_RET toeplitz_part_1(blst_p1 *out, const blst_p1 *x, uint64_t n, const FFTSettings *fs) {
|
||||
C_KZG_RET toeplitz_part_1(g1_t *out, const g1_t *x, uint64_t n, const FFTSettings *fs) {
|
||||
uint64_t n2 = n * 2;
|
||||
blst_p1 *x_ext;
|
||||
g1_t *x_ext;
|
||||
|
||||
TRY(new_p1(&x_ext, n2));
|
||||
for (uint64_t i = 0; i < n; i++) {
|
||||
@ -148,8 +148,8 @@ C_KZG_RET toeplitz_part_1(blst_p1 *out, const blst_p1 *x, uint64_t n, const FFTS
|
||||
* @retval C_CZK_ERROR An internal error occurred
|
||||
* @retval C_CZK_MALLOC Memory allocation failed
|
||||
*/
|
||||
C_KZG_RET toeplitz_part_2(blst_p1 *out, const poly *toeplitz_coeffs, const blst_p1 *x_ext_fft, const FFTSettings *fs) {
|
||||
blst_fr *toeplitz_coeffs_fft;
|
||||
C_KZG_RET toeplitz_part_2(g1_t *out, const poly *toeplitz_coeffs, const g1_t *x_ext_fft, const FFTSettings *fs) {
|
||||
fr_t *toeplitz_coeffs_fft;
|
||||
|
||||
// ASSERT(toeplitz_coeffs->length == fk->x_ext_fft_len, C_KZG_BADARGS); // TODO: how to implement?
|
||||
|
||||
@ -157,7 +157,7 @@ C_KZG_RET toeplitz_part_2(blst_p1 *out, const poly *toeplitz_coeffs, const blst_
|
||||
TRY(fft_fr(toeplitz_coeffs_fft, toeplitz_coeffs->coeffs, false, toeplitz_coeffs->length, fs));
|
||||
|
||||
for (uint64_t i = 0; i < toeplitz_coeffs->length; i++) {
|
||||
p1_mul(&out[i], &x_ext_fft[i], &toeplitz_coeffs_fft[i]);
|
||||
g1_mul(&out[i], &x_ext_fft[i], &toeplitz_coeffs_fft[i]);
|
||||
}
|
||||
|
||||
free(toeplitz_coeffs_fft);
|
||||
@ -174,7 +174,7 @@ C_KZG_RET toeplitz_part_2(blst_p1 *out, const poly *toeplitz_coeffs, const blst_
|
||||
* @retval C_CZK_OK All is well
|
||||
* @retval C_CZK_ERROR An internal error occurred
|
||||
*/
|
||||
C_KZG_RET toeplitz_part_3(blst_p1 *out, const blst_p1 *h_ext_fft, uint64_t n2, const FFTSettings *fs) {
|
||||
C_KZG_RET toeplitz_part_3(g1_t *out, const g1_t *h_ext_fft, uint64_t n2, const FFTSettings *fs) {
|
||||
uint64_t n = n2 / 2;
|
||||
|
||||
TRY(fft_g1(out, h_ext_fft, true, n2, fs));
|
||||
@ -252,9 +252,9 @@ C_KZG_RET toeplitz_coeffs_step(poly *out, const poly *in) {
|
||||
* @retval C_CZK_ERROR An internal error occurred
|
||||
* @retval C_CZK_MALLOC Memory allocation failed
|
||||
*/
|
||||
C_KZG_RET fk20_single_da_opt(blst_p1 *out, const poly *p, const FK20SingleSettings *fk) {
|
||||
C_KZG_RET fk20_single_da_opt(g1_t *out, const poly *p, const FK20SingleSettings *fk) {
|
||||
uint64_t n = p->length, n2 = n * 2;
|
||||
blst_p1 *h, *h_ext_fft;
|
||||
g1_t *h, *h_ext_fft;
|
||||
poly toeplitz_coeffs;
|
||||
|
||||
ASSERT(n2 <= fk->ks->fs->max_width, C_KZG_BADARGS);
|
||||
@ -293,7 +293,7 @@ C_KZG_RET fk20_single_da_opt(blst_p1 *out, const poly *p, const FK20SingleSettin
|
||||
* @retval C_CZK_BADARGS Invalid parameters were supplied
|
||||
* @retval C_CZK_ERROR An internal error occurred
|
||||
*/
|
||||
C_KZG_RET da_using_fk20_single(blst_p1 *out, const poly *p, const FK20SingleSettings *fk) {
|
||||
C_KZG_RET da_using_fk20_single(g1_t *out, const poly *p, const FK20SingleSettings *fk) {
|
||||
uint64_t n = p->length, n2 = n * 2;
|
||||
|
||||
ASSERT(n2 <= fk->ks->fs->max_width, C_KZG_BADARGS);
|
||||
@ -324,9 +324,9 @@ C_KZG_RET da_using_fk20_single(blst_p1 *out, const poly *p, const FK20SingleSett
|
||||
* @param[in] p The polynomial
|
||||
* @param[in] fk FK20 multi settings previously initialised by #new_fk20_multi_settings
|
||||
*/
|
||||
C_KZG_RET fk20_compute_proof_multi(blst_p1 *out, const poly *p, const FK20MultiSettings *fk) {
|
||||
C_KZG_RET fk20_compute_proof_multi(g1_t *out, const poly *p, const FK20MultiSettings *fk) {
|
||||
uint64_t n = p->length, n2 = n * 2;
|
||||
blst_p1 *h_ext_fft, *h_ext_fft_file, *h;
|
||||
g1_t *h_ext_fft, *h_ext_fft_file, *h;
|
||||
poly toeplitz_coeffs;
|
||||
|
||||
ASSERT(fk->ks->fs->max_width >= n2, C_KZG_BADARGS);
|
||||
@ -342,7 +342,7 @@ C_KZG_RET fk20_compute_proof_multi(blst_p1 *out, const poly *p, const FK20MultiS
|
||||
TRY(toeplitz_coeffs_step(&toeplitz_coeffs, p));
|
||||
TRY(toeplitz_part_2(h_ext_fft_file, &toeplitz_coeffs, fk->x_ext_fft_files[i], fk->ks->fs));
|
||||
for (uint64_t j = 0; j < n2; j++) {
|
||||
blst_p1_add(&h_ext_fft[j], &h_ext_fft[j], &h_ext_fft_file[j]);
|
||||
g1_add_or_dbl(&h_ext_fft[j], &h_ext_fft[j], &h_ext_fft_file[j]);
|
||||
}
|
||||
}
|
||||
free_poly(&toeplitz_coeffs);
|
||||
@ -369,9 +369,9 @@ C_KZG_RET fk20_compute_proof_multi(blst_p1 *out, const poly *p, const FK20MultiS
|
||||
* @param[in] p The polynomial, length `n`
|
||||
* @param[in] fk FK20 multi settings previously initialised by #new_fk20_multi_settings
|
||||
*/
|
||||
C_KZG_RET fk20_multi_da_opt(blst_p1 *out, const poly *p, const FK20MultiSettings *fk) {
|
||||
C_KZG_RET fk20_multi_da_opt(g1_t *out, const poly *p, const FK20MultiSettings *fk) {
|
||||
uint64_t n = p->length, n2 = n * 2, k, k2;
|
||||
blst_p1 *h_ext_fft, *h_ext_fft_file, *h;
|
||||
g1_t *h_ext_fft, *h_ext_fft_file, *h;
|
||||
poly toeplitz_coeffs;
|
||||
|
||||
ASSERT(n2 <= fk->ks->fs->max_width, C_KZG_BADARGS);
|
||||
@ -392,7 +392,7 @@ C_KZG_RET fk20_multi_da_opt(blst_p1 *out, const poly *p, const FK20MultiSettings
|
||||
TRY(toeplitz_coeffs_stride(&toeplitz_coeffs, p, i, fk->chunk_len));
|
||||
TRY(toeplitz_part_2(h_ext_fft_file, &toeplitz_coeffs, fk->x_ext_fft_files[i], fk->ks->fs));
|
||||
for (uint64_t j = 0; j < k2; j++) {
|
||||
blst_p1_add(&h_ext_fft[j], &h_ext_fft[j], &h_ext_fft_file[j]);
|
||||
g1_add_or_dbl(&h_ext_fft[j], &h_ext_fft[j], &h_ext_fft_file[j]);
|
||||
}
|
||||
}
|
||||
free_poly(&toeplitz_coeffs);
|
||||
@ -421,7 +421,7 @@ C_KZG_RET fk20_multi_da_opt(blst_p1 *out, const poly *p, const FK20MultiSettings
|
||||
* This involves sampling on the double domain and reordering according to reverse bit order.
|
||||
*
|
||||
*/
|
||||
C_KZG_RET da_using_fk20_multi(blst_p1 *out, const poly *p, const FK20MultiSettings *fk) {
|
||||
C_KZG_RET da_using_fk20_multi(g1_t *out, const poly *p, const FK20MultiSettings *fk) {
|
||||
uint64_t n = p->length, n2 = n * 2;
|
||||
|
||||
ASSERT(n2 <= fk->ks->fs->max_width, C_KZG_BADARGS);
|
||||
@ -449,7 +449,7 @@ C_KZG_RET da_using_fk20_multi(blst_p1 *out, const poly *p, const FK20MultiSettin
|
||||
*/
|
||||
C_KZG_RET new_fk20_single_settings(FK20SingleSettings *fk, uint64_t n2, const KZGSettings *ks) {
|
||||
int n = n2 / 2;
|
||||
blst_p1 *x;
|
||||
g1_t *x;
|
||||
|
||||
ASSERT(n2 <= ks->fs->max_width, C_KZG_BADARGS);
|
||||
ASSERT(is_power_of_two(n2), C_KZG_BADARGS);
|
||||
@ -488,7 +488,7 @@ C_KZG_RET new_fk20_single_settings(FK20SingleSettings *fk, uint64_t n2, const KZ
|
||||
*/
|
||||
C_KZG_RET new_fk20_multi_settings(FK20MultiSettings *fk, uint64_t n2, uint64_t chunk_len, const KZGSettings *ks) {
|
||||
uint64_t n, k;
|
||||
blst_p1 *x;
|
||||
g1_t *x;
|
||||
|
||||
ASSERT(n2 <= ks->fs->max_width, C_KZG_BADARGS);
|
||||
ASSERT(is_power_of_two(n2), C_KZG_BADARGS);
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
/** @file fk20_proofs.h */
|
||||
|
||||
#include "c_kzg.h"
|
||||
#include "kzg_proofs.h"
|
||||
|
||||
/**
|
||||
@ -46,7 +45,7 @@
|
||||
*/
|
||||
typedef struct {
|
||||
const KZGSettings *ks; /**< The corresponding settings for performing KZG proofs */
|
||||
blst_p1 *x_ext_fft; /**< The output of the first part of the Toeplitz process */
|
||||
g1_t *x_ext_fft; /**< The output of the first part of the Toeplitz process */
|
||||
uint64_t x_ext_fft_len; /**< The length of the `x_ext_fft_len` array (TODO - do we need this?)*/
|
||||
} FK20SingleSettings;
|
||||
|
||||
@ -54,25 +53,25 @@ typedef struct {
|
||||
* Stores the setup and parameters needed for computing FK20 multi proofs.
|
||||
*/
|
||||
typedef struct {
|
||||
const KZGSettings *ks; /**< The corresponding settings for performing KZG proofs */
|
||||
uint64_t chunk_len; /**< TODO */
|
||||
blst_p1 **x_ext_fft_files; /**< TODO */
|
||||
uint64_t length; /**< TODO */
|
||||
const KZGSettings *ks; /**< The corresponding settings for performing KZG proofs */
|
||||
uint64_t chunk_len; /**< TODO */
|
||||
g1_t **x_ext_fft_files; /**< TODO */
|
||||
uint64_t length; /**< TODO */
|
||||
} FK20MultiSettings;
|
||||
|
||||
int log2_pow2(uint32_t n);
|
||||
uint32_t reverse_bits(uint32_t a);
|
||||
uint32_t reverse_bits_limited(uint32_t n, uint32_t value);
|
||||
C_KZG_RET reverse_bit_order(void *values, size_t size, uint64_t n);
|
||||
C_KZG_RET toeplitz_part_1(blst_p1 *out, const blst_p1 *x, uint64_t n, const FFTSettings *fs);
|
||||
C_KZG_RET toeplitz_part_2(blst_p1 *out, const poly *toeplitz_coeffs, const blst_p1 *x_ext_fft, const FFTSettings *fs);
|
||||
C_KZG_RET toeplitz_part_3(blst_p1 *out, const blst_p1 *h_ext_fft, uint64_t n2, const FFTSettings *fs);
|
||||
C_KZG_RET toeplitz_part_1(g1_t *out, const g1_t *x, uint64_t n, const FFTSettings *fs);
|
||||
C_KZG_RET toeplitz_part_2(g1_t *out, const poly *toeplitz_coeffs, const g1_t *x_ext_fft, const FFTSettings *fs);
|
||||
C_KZG_RET toeplitz_part_3(g1_t *out, const g1_t *h_ext_fft, uint64_t n2, const FFTSettings *fs);
|
||||
C_KZG_RET toeplitz_coeffs_stride(poly *out, const poly *in, uint64_t offset, uint64_t stride);
|
||||
C_KZG_RET toeplitz_coeffs_step(poly *out, const poly *in);
|
||||
C_KZG_RET fk20_single_da_opt(blst_p1 *out, const poly *p, const FK20SingleSettings *fk);
|
||||
C_KZG_RET da_using_fk20_single(blst_p1 *out, const poly *p, const FK20SingleSettings *fk);
|
||||
C_KZG_RET fk20_multi_da_opt(blst_p1 *out, const poly *p, const FK20MultiSettings *fk);
|
||||
C_KZG_RET da_using_fk20_multi(blst_p1 *out, const poly *p, const FK20MultiSettings *fk);
|
||||
C_KZG_RET fk20_single_da_opt(g1_t *out, const poly *p, const FK20SingleSettings *fk);
|
||||
C_KZG_RET da_using_fk20_single(g1_t *out, const poly *p, const FK20SingleSettings *fk);
|
||||
C_KZG_RET fk20_multi_da_opt(g1_t *out, const poly *p, const FK20MultiSettings *fk);
|
||||
C_KZG_RET da_using_fk20_multi(g1_t *out, const poly *p, const FK20MultiSettings *fk);
|
||||
C_KZG_RET new_fk20_single_settings(FK20SingleSettings *fk, uint64_t n2, const KZGSettings *ks);
|
||||
C_KZG_RET new_fk20_multi_settings(FK20MultiSettings *fk, uint64_t n2, uint64_t chunk_len, const KZGSettings *ks);
|
||||
void free_fk20_single_settings(FK20SingleSettings *fk);
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
#include "debug_util.h"
|
||||
#include "test_util.h"
|
||||
#include "fk20_proofs.h"
|
||||
#include "c_kzg_util.h"
|
||||
@ -53,36 +52,36 @@ void test_log2_pow2(void) {
|
||||
|
||||
void test_reverse_bit_order_g1(void) {
|
||||
int size = 10, n = 1 << size;
|
||||
blst_p1 a[n], b[n];
|
||||
blst_fr tmp;
|
||||
g1_t a[n], b[n];
|
||||
fr_t tmp;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
fr_from_uint64(&tmp, i);
|
||||
p1_mul(&a[i], blst_p1_generator(), &tmp);
|
||||
g1_mul(&a[i], &g1_generator, &tmp);
|
||||
b[i] = a[i];
|
||||
}
|
||||
|
||||
TEST_CHECK(C_KZG_OK == reverse_bit_order(a, sizeof(blst_p1), n));
|
||||
TEST_CHECK(C_KZG_OK == reverse_bit_order(a, sizeof(g1_t), n));
|
||||
for (int i = 0; i < n; i++) {
|
||||
TEST_CHECK(true == blst_p1_is_equal(&b[reverse_bits(i) >> (32 - size)], &a[i]));
|
||||
TEST_CHECK(true == g1_equal(&b[reverse_bits(i) >> (32 - size)], &a[i]));
|
||||
}
|
||||
|
||||
// Hand check a few select values
|
||||
TEST_CHECK(true == blst_p1_is_equal(&b[0], &a[0]));
|
||||
TEST_CHECK(false == blst_p1_is_equal(&b[1], &a[1]));
|
||||
TEST_CHECK(true == blst_p1_is_equal(&b[n - 1], &a[n - 1]));
|
||||
TEST_CHECK(true == g1_equal(&b[0], &a[0]));
|
||||
TEST_CHECK(false == g1_equal(&b[1], &a[1]));
|
||||
TEST_CHECK(true == g1_equal(&b[n - 1], &a[n - 1]));
|
||||
}
|
||||
|
||||
void test_reverse_bit_order_fr(void) {
|
||||
int size = 12, n = 1 << size;
|
||||
blst_fr a[n], b[n];
|
||||
fr_t a[n], b[n];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
fr_from_uint64(&a[i], i);
|
||||
b[i] = a[i];
|
||||
}
|
||||
|
||||
TEST_CHECK(C_KZG_OK == reverse_bit_order(a, sizeof(blst_fr), n));
|
||||
TEST_CHECK(C_KZG_OK == reverse_bit_order(a, sizeof(fr_t), n));
|
||||
for (int i = 0; i < n; i++) {
|
||||
TEST_CHECK(true == fr_equal(&b[reverse_bits(i) >> (32 - size)], &a[i]));
|
||||
}
|
||||
@ -105,11 +104,11 @@ void fk_single(void) {
|
||||
KZGSettings ks;
|
||||
FK20SingleSettings fk;
|
||||
uint64_t secrets_len = n_len + 1;
|
||||
blst_p1 s1[secrets_len];
|
||||
blst_p2 s2[secrets_len];
|
||||
g1_t s1[secrets_len];
|
||||
g2_t s2[secrets_len];
|
||||
poly p;
|
||||
blst_p1 commitment, all_proofs[2 * poly_len], proof;
|
||||
blst_fr x, y;
|
||||
g1_t commitment, all_proofs[2 * poly_len], proof;
|
||||
fr_t x, y;
|
||||
bool result;
|
||||
|
||||
TEST_CHECK(n_len >= 2 * poly_len);
|
||||
@ -178,11 +177,11 @@ void fk_single_strided(void) {
|
||||
KZGSettings ks;
|
||||
FK20SingleSettings fk;
|
||||
uint64_t secrets_len = n_len + 1;
|
||||
blst_p1 s1[secrets_len];
|
||||
blst_p2 s2[secrets_len];
|
||||
g1_t s1[secrets_len];
|
||||
g2_t s2[secrets_len];
|
||||
poly p;
|
||||
blst_p1 commitment, all_proofs[2 * poly_len], proof;
|
||||
blst_fr x, y;
|
||||
g1_t commitment, all_proofs[2 * poly_len], proof;
|
||||
fr_t x, y;
|
||||
bool result;
|
||||
|
||||
TEST_CHECK(n_len >= 2 * poly_len);
|
||||
@ -226,8 +225,8 @@ void fk_multi_settings(void) {
|
||||
FK20MultiSettings fk;
|
||||
uint64_t n = 5;
|
||||
uint64_t secrets_len = 33;
|
||||
blst_p1 s1[secrets_len];
|
||||
blst_p2 s2[secrets_len];
|
||||
g1_t s1[secrets_len];
|
||||
g2_t s2[secrets_len];
|
||||
|
||||
// Initialise the secrets and data structures
|
||||
generate_trusted_setup(s1, s2, &secret, secrets_len);
|
||||
@ -248,14 +247,14 @@ void fk_multi_0(void) {
|
||||
FK20MultiSettings fk;
|
||||
uint64_t n, chunk_len, chunk_count;
|
||||
uint64_t secrets_len;
|
||||
blst_p1 *s1;
|
||||
blst_p2 *s2;
|
||||
g1_t *s1;
|
||||
g2_t *s2;
|
||||
poly p;
|
||||
uint64_t vv[] = {1, 2, 3, 4, 7, 8, 9, 10, 13, 14, 1, 15, 1, 1000, 134, 33};
|
||||
blst_p1 commitment;
|
||||
blst_p1 *all_proofs;
|
||||
blst_fr *extended_coeffs, *extended_coeffs_fft;
|
||||
blst_fr *ys, *ys2;
|
||||
g1_t commitment;
|
||||
g1_t *all_proofs;
|
||||
fr_t *extended_coeffs, *extended_coeffs_fft;
|
||||
fr_t *ys, *ys2;
|
||||
uint64_t domain_stride;
|
||||
|
||||
chunk_len = 16;
|
||||
@ -308,7 +307,7 @@ void fk_multi_0(void) {
|
||||
domain_stride = fs.max_width / (2 * n);
|
||||
for (uint64_t pos = 0; pos < 2 * chunk_count; pos++) {
|
||||
uint64_t domain_pos, stride;
|
||||
blst_fr x;
|
||||
fr_t x;
|
||||
bool result;
|
||||
|
||||
domain_pos = reverse_bits_limited(2 * chunk_count, pos);
|
||||
@ -323,8 +322,8 @@ void fk_multi_0(void) {
|
||||
// Now recreate the ys by evaluating the polynomial in the sub-domain range
|
||||
stride = fs.max_width / chunk_len;
|
||||
for (uint64_t i = 0; i < chunk_len; i++) {
|
||||
blst_fr z;
|
||||
blst_fr_mul(&z, &x, &fs.expanded_roots_of_unity[i * stride]);
|
||||
fr_t z;
|
||||
fr_mul(&z, &x, &fs.expanded_roots_of_unity[i * stride]);
|
||||
eval_poly(&ys2[i], &p, &z);
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,8 @@
|
||||
* @param[in] p The polynomial to be committed to
|
||||
* @param[in] ks The settings containing the secrets, previously initialised with #new_kzg_settings
|
||||
*/
|
||||
void commit_to_poly(blst_p1 *out, const poly *p, const KZGSettings *ks) {
|
||||
linear_combination_g1(out, ks->secret_g1, p->coeffs, p->length);
|
||||
void commit_to_poly(g1_t *out, const poly *p, const KZGSettings *ks) {
|
||||
g1_linear_combination(out, ks->secret_g1, p->coeffs, p->length);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,7 +49,7 @@ void commit_to_poly(blst_p1 *out, const poly *p, const KZGSettings *ks) {
|
||||
* @retval C_CZK_ERROR An internal error occurred
|
||||
* @retval C_CZK_MALLOC Memory allocation failed
|
||||
*/
|
||||
C_KZG_RET compute_proof_single(blst_p1 *out, const poly *p, const blst_fr *x0, const KZGSettings *ks) {
|
||||
C_KZG_RET compute_proof_single(g1_t *out, const poly *p, const fr_t *x0, const KZGSettings *ks) {
|
||||
return compute_proof_multi(out, p, x0, 1, ks);
|
||||
}
|
||||
|
||||
@ -66,16 +66,16 @@ C_KZG_RET compute_proof_single(blst_p1 *out, const poly *p, const blst_fr *x0, c
|
||||
* @param[in] ks The settings containing the secrets, previously initialised with #new_kzg_settings
|
||||
* @retval C_CZK_OK All is well
|
||||
*/
|
||||
C_KZG_RET check_proof_single(bool *out, const blst_p1 *commitment, const blst_p1 *proof, const blst_fr *x, blst_fr *y,
|
||||
C_KZG_RET check_proof_single(bool *out, const g1_t *commitment, const g1_t *proof, const fr_t *x, fr_t *y,
|
||||
const KZGSettings *ks) {
|
||||
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);
|
||||
g2_t x_g2, s_minus_x;
|
||||
g1_t y_g1, commitment_minus_y;
|
||||
g2_mul(&x_g2, &g2_generator, x);
|
||||
g2_sub(&s_minus_x, &ks->secret_g2[1], &x_g2);
|
||||
g1_mul(&y_g1, &g1_generator, y);
|
||||
g1_sub(&commitment_minus_y, commitment, &y_g1);
|
||||
|
||||
*out = pairings_verify(&commitment_minus_y, blst_p2_generator(), proof, &s_minus_x);
|
||||
*out = pairings_verify(&commitment_minus_y, &g2_generator, proof, &s_minus_x);
|
||||
|
||||
return C_KZG_OK;
|
||||
}
|
||||
@ -96,9 +96,9 @@ C_KZG_RET check_proof_single(bool *out, const blst_p1 *commitment, const blst_p1
|
||||
* @retval C_CZK_ERROR An internal error occurred
|
||||
* @retval C_CZK_MALLOC Memory allocation failed
|
||||
*/
|
||||
C_KZG_RET compute_proof_multi(blst_p1 *out, const poly *p, const blst_fr *x0, uint64_t n, const KZGSettings *ks) {
|
||||
C_KZG_RET compute_proof_multi(g1_t *out, const poly *p, const fr_t *x0, uint64_t n, const KZGSettings *ks) {
|
||||
poly divisor, q;
|
||||
blst_fr x_pow_n;
|
||||
fr_t x_pow_n;
|
||||
|
||||
ASSERT(is_power_of_two(n), C_KZG_BADARGS);
|
||||
|
||||
@ -146,12 +146,12 @@ C_KZG_RET compute_proof_multi(blst_p1 *out, const poly *p, const blst_fr *x0, ui
|
||||
* @retval C_CZK_ERROR An internal error occurred
|
||||
* @retval C_CZK_MALLOC Memory allocation failed
|
||||
*/
|
||||
C_KZG_RET check_proof_multi(bool *out, const blst_p1 *commitment, const blst_p1 *proof, const blst_fr *x,
|
||||
const blst_fr *ys, uint64_t n, const KZGSettings *ks) {
|
||||
C_KZG_RET check_proof_multi(bool *out, const g1_t *commitment, const g1_t *proof, const fr_t *x, const fr_t *ys,
|
||||
uint64_t n, const KZGSettings *ks) {
|
||||
poly interp;
|
||||
blst_fr inv_x, inv_x_pow, x_pow;
|
||||
blst_p2 xn2, xn_minus_yn;
|
||||
blst_p1 is1, commit_minus_interp;
|
||||
fr_t inv_x, inv_x_pow, x_pow;
|
||||
g2_t xn2, xn_minus_yn;
|
||||
g1_t is1, commit_minus_interp;
|
||||
|
||||
ASSERT(is_power_of_two(n), C_KZG_BADARGS);
|
||||
|
||||
@ -160,27 +160,27 @@ C_KZG_RET check_proof_multi(bool *out, const blst_p1 *commitment, const blst_p1
|
||||
TRY(fft_fr(interp.coeffs, ys, true, n, ks->fs));
|
||||
|
||||
// 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);
|
||||
fr_inv(&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);
|
||||
fr_mul(&interp.coeffs[i], &interp.coeffs[i], &inv_x_pow);
|
||||
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);
|
||||
fr_inv(&x_pow, &inv_x_pow);
|
||||
g2_mul(&xn2, &g2_generator, &x_pow);
|
||||
|
||||
// [s^n - x^n]_2
|
||||
p2_sub(&xn_minus_yn, &ks->secret_g2[n], &xn2);
|
||||
g2_sub(&xn_minus_yn, &ks->secret_g2[n], &xn2);
|
||||
|
||||
// [interpolation_polynomial(s)]_1
|
||||
commit_to_poly(&is1, &interp, ks);
|
||||
|
||||
// [commitment - interpolation_polynomial(s)]_1 = [commit]_1 - [interpolation_polynomial(s)]_1
|
||||
p1_sub(&commit_minus_interp, commitment, &is1);
|
||||
g1_sub(&commit_minus_interp, commitment, &is1);
|
||||
|
||||
*out = pairings_verify(&commit_minus_interp, blst_p2_generator(), proof, &xn_minus_yn);
|
||||
*out = pairings_verify(&commit_minus_interp, &g2_generator, proof, &xn_minus_yn);
|
||||
|
||||
free_poly(&interp);
|
||||
return C_KZG_OK;
|
||||
@ -203,7 +203,7 @@ C_KZG_RET check_proof_multi(bool *out, const blst_p1 *commitment, const blst_p1
|
||||
* @retval C_CZK_BADARGS Invalid parameters were supplied
|
||||
* @retval C_CZK_MALLOC Memory allocation failed
|
||||
*/
|
||||
C_KZG_RET new_kzg_settings(KZGSettings *ks, const blst_p1 *secret_g1, const blst_p2 *secret_g2, uint64_t length,
|
||||
C_KZG_RET new_kzg_settings(KZGSettings *ks, const g1_t *secret_g1, const g2_t *secret_g2, uint64_t length,
|
||||
FFTSettings const *fs) {
|
||||
|
||||
ASSERT(length >= fs->max_width, C_KZG_BADARGS);
|
||||
|
@ -27,18 +27,18 @@
|
||||
*/
|
||||
typedef struct {
|
||||
const FFTSettings *fs; /**< The corresponding settings for performing FFTs */
|
||||
blst_p1 *secret_g1; /**< G1 group elements from the trusted setup */
|
||||
blst_p2 *secret_g2; /**< G2 group elements from the trusted setup */
|
||||
g1_t *secret_g1; /**< G1 group elements from the trusted setup */
|
||||
g2_t *secret_g2; /**< G2 group elements from the trusted setup */
|
||||
uint64_t length; /**< The number of elements in secret_g1 and secret_g2 */
|
||||
} KZGSettings;
|
||||
|
||||
void commit_to_poly(blst_p1 *out, const poly *p, const KZGSettings *ks);
|
||||
C_KZG_RET compute_proof_single(blst_p1 *out, const poly *p, const blst_fr *x0, const KZGSettings *ks);
|
||||
C_KZG_RET check_proof_single(bool *out, const blst_p1 *commitment, const blst_p1 *proof, const blst_fr *x, blst_fr *y,
|
||||
void commit_to_poly(g1_t *out, const poly *p, const KZGSettings *ks);
|
||||
C_KZG_RET compute_proof_single(g1_t *out, const poly *p, const fr_t *x0, const KZGSettings *ks);
|
||||
C_KZG_RET check_proof_single(bool *out, const g1_t *commitment, const g1_t *proof, const fr_t *x, fr_t *y,
|
||||
const KZGSettings *ks);
|
||||
C_KZG_RET compute_proof_multi(blst_p1 *out, const poly *p, const blst_fr *x0, uint64_t n, const KZGSettings *ks);
|
||||
C_KZG_RET check_proof_multi(bool *out, const blst_p1 *commitment, const blst_p1 *proof, const blst_fr *x,
|
||||
const blst_fr *ys, uint64_t n, const KZGSettings *ks);
|
||||
C_KZG_RET new_kzg_settings(KZGSettings *ks, const blst_p1 *secret_g1, const blst_p2 *secret_g2, uint64_t length,
|
||||
C_KZG_RET compute_proof_multi(g1_t *out, const poly *p, const fr_t *x0, uint64_t n, const KZGSettings *ks);
|
||||
C_KZG_RET check_proof_multi(bool *out, const g1_t *commitment, const g1_t *proof, const fr_t *x, const fr_t *ys,
|
||||
uint64_t n, const KZGSettings *ks);
|
||||
C_KZG_RET new_kzg_settings(KZGSettings *ks, const g1_t *secret_g1, const g2_t *secret_g2, uint64_t length,
|
||||
const FFTSettings *fs);
|
||||
void free_kzg_settings(KZGSettings *ks);
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
#include "debug_util.h"
|
||||
#include "test_util.h"
|
||||
#include "kzg_proofs.h"
|
||||
|
||||
@ -27,11 +26,11 @@ void proof_single(void) {
|
||||
|
||||
FFTSettings fs;
|
||||
KZGSettings ks;
|
||||
blst_p1 s1[secrets_len];
|
||||
blst_p2 s2[secrets_len];
|
||||
g1_t s1[secrets_len];
|
||||
g2_t s2[secrets_len];
|
||||
poly p;
|
||||
blst_p1 commitment, proof;
|
||||
blst_fr x, value;
|
||||
g1_t commitment, proof;
|
||||
fr_t x, value;
|
||||
bool result;
|
||||
|
||||
// Create the polynomial
|
||||
@ -57,7 +56,7 @@ void proof_single(void) {
|
||||
TEST_CHECK(true == result);
|
||||
|
||||
// Change the value and check that the proof fails
|
||||
blst_fr_add(&value, &value, &fr_one);
|
||||
fr_add(&value, &value, &fr_one);
|
||||
TEST_CHECK(C_KZG_OK == check_proof_single(&result, &commitment, &proof, &x, &value, &ks));
|
||||
TEST_CHECK(false == result);
|
||||
|
||||
@ -74,17 +73,17 @@ void proof_multi(void) {
|
||||
FFTSettings fs1, fs2;
|
||||
KZGSettings ks1, ks2;
|
||||
poly p;
|
||||
blst_p1 commitment, proof;
|
||||
blst_fr x, tmp;
|
||||
g1_t commitment, proof;
|
||||
fr_t x, tmp;
|
||||
bool result;
|
||||
|
||||
// Compute proof at 2^coset_scale points
|
||||
int coset_scale = 7, coset_len = (1 << coset_scale);
|
||||
blst_fr y[coset_len];
|
||||
fr_t y[coset_len];
|
||||
|
||||
uint64_t secrets_len = poly_len > coset_len ? poly_len + 1 : coset_len + 1;
|
||||
blst_p1 s1[secrets_len];
|
||||
blst_p2 s2[secrets_len];
|
||||
g1_t s1[secrets_len];
|
||||
g2_t s2[secrets_len];
|
||||
|
||||
// Create the polynomial
|
||||
new_poly(&p, poly_len);
|
||||
@ -109,7 +108,7 @@ void proof_multi(void) {
|
||||
|
||||
// y_i is the value of the polynomial at each x_i
|
||||
for (int i = 0; i < coset_len; i++) {
|
||||
blst_fr_mul(&tmp, &x, &ks2.fs->expanded_roots_of_unity[i]);
|
||||
fr_mul(&tmp, &x, &ks2.fs->expanded_roots_of_unity[i]);
|
||||
eval_poly(&y[i], &p, &tmp);
|
||||
}
|
||||
|
||||
@ -118,7 +117,7 @@ void proof_multi(void) {
|
||||
TEST_CHECK(true == result);
|
||||
|
||||
// Change a value and check that the proof fails
|
||||
blst_fr_add(y + coset_len / 2, y + coset_len / 2, &fr_one);
|
||||
fr_add(y + coset_len / 2, y + coset_len / 2, &fr_one);
|
||||
TEST_CHECK(C_KZG_OK == check_proof_multi(&result, &commitment, &proof, &x, y, coset_len, &ks2));
|
||||
TEST_CHECK(false == result);
|
||||
|
||||
@ -134,9 +133,9 @@ void commit_to_nil_poly(void) {
|
||||
FFTSettings fs;
|
||||
KZGSettings ks;
|
||||
uint64_t secrets_len = 16;
|
||||
blst_p1 s1[secrets_len];
|
||||
blst_p2 s2[secrets_len];
|
||||
blst_p1 result;
|
||||
g1_t s1[secrets_len];
|
||||
g2_t s2[secrets_len];
|
||||
g1_t result;
|
||||
|
||||
// Initialise the (arbitrary) secrets and data structures
|
||||
generate_trusted_setup(s1, s2, &secret, secrets_len);
|
||||
@ -145,7 +144,7 @@ void commit_to_nil_poly(void) {
|
||||
|
||||
new_poly(&a, 0);
|
||||
commit_to_poly(&result, &a, &ks);
|
||||
TEST_CHECK(blst_p1_is_equal(&g1_identity, &result));
|
||||
TEST_CHECK(g1_equal(&g1_identity, &result));
|
||||
|
||||
free_fft_settings(&fs);
|
||||
free_kzg_settings(&ks);
|
||||
|
18
src/poly.c
18
src/poly.c
@ -41,8 +41,8 @@ static uint64_t poly_quotient_length(const poly *dividend, const poly *divisor)
|
||||
* @param[in] p The polynomial
|
||||
* @param[in] x The x-coordinate to be evaluated
|
||||
*/
|
||||
void eval_poly(blst_fr *out, const poly *p, const blst_fr *x) {
|
||||
blst_fr tmp;
|
||||
void eval_poly(fr_t *out, const poly *p, const fr_t *x) {
|
||||
fr_t tmp;
|
||||
uint64_t i;
|
||||
|
||||
if (p->length == 0) {
|
||||
@ -59,8 +59,8 @@ void eval_poly(blst_fr *out, const poly *p, const blst_fr *x) {
|
||||
*out = p->coeffs[p->length - 1];
|
||||
i = p->length - 2;
|
||||
while (true) {
|
||||
blst_fr_mul(&tmp, out, x);
|
||||
blst_fr_add(out, &tmp, &p->coeffs[i]);
|
||||
fr_mul(&tmp, out, x);
|
||||
fr_add(out, &tmp, &p->coeffs[i]);
|
||||
if (i == 0) break;
|
||||
--i;
|
||||
}
|
||||
@ -85,7 +85,7 @@ C_KZG_RET new_poly_long_div(poly *out, const poly *dividend, const poly *divisor
|
||||
uint64_t a_pos = dividend->length - 1;
|
||||
uint64_t b_pos = divisor->length - 1;
|
||||
uint64_t diff = a_pos - b_pos;
|
||||
blst_fr a[dividend->length];
|
||||
fr_t a[dividend->length];
|
||||
|
||||
// Dividing by zero is undefined
|
||||
ASSERT(divisor->length > 0, C_KZG_BADARGS);
|
||||
@ -103,10 +103,10 @@ C_KZG_RET new_poly_long_div(poly *out, const poly *dividend, const poly *divisor
|
||||
while (diff > 0) {
|
||||
fr_div(&out->coeffs[diff], &a[a_pos], &divisor->coeffs[b_pos]);
|
||||
for (uint64_t i = 0; i <= b_pos; i++) {
|
||||
blst_fr tmp;
|
||||
fr_t tmp;
|
||||
// a[diff + i] -= b[i] * quot
|
||||
blst_fr_mul(&tmp, &out->coeffs[diff], &divisor->coeffs[i]);
|
||||
blst_fr_sub(&a[diff + i], &a[diff + i], &tmp);
|
||||
fr_mul(&tmp, &out->coeffs[diff], &divisor->coeffs[i]);
|
||||
fr_sub(&a[diff + i], &a[diff + i], &tmp);
|
||||
}
|
||||
--diff;
|
||||
--a_pos;
|
||||
@ -144,7 +144,7 @@ C_KZG_RET new_poly(poly *out, uint64_t length) {
|
||||
*
|
||||
* @todo This is likely not useful. Remove?
|
||||
*/
|
||||
C_KZG_RET new_poly_with_coeffs(poly *out, const blst_fr *coeffs, uint64_t length) {
|
||||
C_KZG_RET new_poly_with_coeffs(poly *out, const fr_t *coeffs, uint64_t length) {
|
||||
TRY(new_poly(out, length));
|
||||
for (uint64_t i = 0; i < length; i++) {
|
||||
out->coeffs[i] = coeffs[i];
|
||||
|
@ -17,7 +17,7 @@
|
||||
/** @file poly.h */
|
||||
|
||||
#include "c_kzg.h"
|
||||
#include "blst_util.h"
|
||||
#include "bls12_381.h"
|
||||
|
||||
/**
|
||||
* Defines a polynomial whose coefficients are members of the finite field F_r.
|
||||
@ -25,12 +25,12 @@
|
||||
* Initialise the storage with #new_poly. After use, free the storage with #free_poly.
|
||||
*/
|
||||
typedef struct {
|
||||
blst_fr *coeffs; /**< `coeffs[i]` is the coefficient of the `x^i` term of the polynomial. */
|
||||
fr_t *coeffs; /**< `coeffs[i]` is the coefficient of the `x^i` term of the polynomial. */
|
||||
uint64_t length; /**< One more than the polynomial's degree */
|
||||
} poly;
|
||||
|
||||
void eval_poly(blst_fr *out, const poly *p, const blst_fr *x);
|
||||
void eval_poly(fr_t *out, const poly *p, const fr_t *x);
|
||||
C_KZG_RET new_poly_long_div(poly *out, const poly *dividend, const poly *divisor);
|
||||
C_KZG_RET new_poly(poly *out, uint64_t length);
|
||||
C_KZG_RET new_poly_with_coeffs(poly *out, const blst_fr *coeffs, uint64_t length);
|
||||
C_KZG_RET new_poly_with_coeffs(poly *out, const fr_t *coeffs, uint64_t length);
|
||||
void free_poly(poly *p);
|
||||
|
@ -15,12 +15,11 @@
|
||||
*/
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
#include "debug_util.h"
|
||||
#include "test_util.h"
|
||||
#include "poly.h"
|
||||
|
||||
void poly_div_0(void) {
|
||||
blst_fr a[3], b[2], expected[2];
|
||||
fr_t a[3], b[2], expected[2];
|
||||
poly dividend, divisor, actual;
|
||||
|
||||
// Calculate (x^2 - 1) / (x + 1) = x - 1
|
||||
@ -52,7 +51,7 @@ void poly_div_0(void) {
|
||||
}
|
||||
|
||||
void poly_div_1(void) {
|
||||
blst_fr a[4], b[2], expected[3];
|
||||
fr_t a[4], b[2], expected[3];
|
||||
poly dividend, divisor, actual;
|
||||
|
||||
// Calculate (12x^3 - 11x^2 + 9x + 18) / (4x + 3) = 3x^2 - 5x + 6
|
||||
@ -87,7 +86,7 @@ void poly_div_1(void) {
|
||||
}
|
||||
|
||||
void poly_div_2(void) {
|
||||
blst_fr a[2], b[3];
|
||||
fr_t a[2], b[3];
|
||||
poly dividend, divisor, actual;
|
||||
|
||||
// Calculate (x + 1) / (x^2 - 1) = nil
|
||||
@ -113,7 +112,7 @@ void poly_div_2(void) {
|
||||
}
|
||||
|
||||
void poly_div_by_zero(void) {
|
||||
blst_fr a[2];
|
||||
fr_t a[2];
|
||||
poly dividend, divisor, dummy;
|
||||
|
||||
// Calculate (x + 1) / 0 = FAIL
|
||||
@ -132,7 +131,7 @@ void poly_div_by_zero(void) {
|
||||
|
||||
void poly_eval_check(void) {
|
||||
uint64_t n = 10;
|
||||
blst_fr actual, expected;
|
||||
fr_t actual, expected;
|
||||
poly p;
|
||||
new_poly(&p, n);
|
||||
for (uint64_t i = 0; i < n; i++) {
|
||||
@ -149,7 +148,7 @@ void poly_eval_check(void) {
|
||||
|
||||
void poly_eval_0_check(void) {
|
||||
uint64_t n = 7, a = 597;
|
||||
blst_fr actual, expected;
|
||||
fr_t actual, expected;
|
||||
poly p;
|
||||
new_poly(&p, n);
|
||||
for (uint64_t i = 0; i < n; i++) {
|
||||
@ -166,7 +165,7 @@ void poly_eval_0_check(void) {
|
||||
|
||||
void poly_eval_nil_check(void) {
|
||||
uint64_t n = 0;
|
||||
blst_fr actual;
|
||||
fr_t actual;
|
||||
poly p;
|
||||
new_poly(&p, n);
|
||||
|
||||
|
@ -16,17 +16,17 @@
|
||||
|
||||
#include <stdlib.h> // malloc()
|
||||
#include "test_util.h"
|
||||
#include "blst_util.h"
|
||||
#include "bls12_381.h"
|
||||
|
||||
void generate_trusted_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);
|
||||
void generate_trusted_setup(g1_t *s1, g2_t *s2, const scalar_t *secret, const uint64_t n) {
|
||||
fr_t s_pow, s;
|
||||
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);
|
||||
g1_mul(s1 + i, &g1_generator, &s_pow);
|
||||
g2_mul(s2 + i, &g2_generator, &s_pow);
|
||||
fr_mul(&s_pow, &s_pow, &s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,11 +15,12 @@
|
||||
*/
|
||||
|
||||
#include "c_kzg.h"
|
||||
#include "bls12_381.h"
|
||||
|
||||
// The generator for our "trusted" setup
|
||||
static const 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?
|
||||
static const scalar_t 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};
|
||||
|
||||
void generate_trusted_setup(blst_p1 *s1, blst_p2 *s2, const blst_scalar *secret, const uint64_t n);
|
||||
void generate_trusted_setup(g1_t *s1, g2_t *s2, const scalar_t *secret, const uint64_t n);
|
||||
void title(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user