Groundwork for being able to use alternative BLS libraries

This commit is contained in:
Ben Edgington 2021-02-16 18:13:20 +00:00
parent aec19b5eee
commit 66c50a49b1
35 changed files with 607 additions and 464 deletions

View File

@ -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 =

View File

@ -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;
}

View File

@ -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();

View File

@ -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(&gt_point);
}
#endif // BLST

124
src/bls12_381.h Normal file
View File

@ -0,0 +1,124 @@
/*
* Copyright 2021 Benjamin Edgington
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @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

View File

@ -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 */
};

View File

@ -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);

View File

@ -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.

View File

@ -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);
}

View File

@ -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);

View File

@ -15,7 +15,6 @@
*/
#include "../inc/acutest.h"
#include "debug_util.h"
#include "test_util.h"
#include "c_kzg_util.h"

View File

@ -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

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -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));
}

View File

@ -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);

View File

@ -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);

View File

@ -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++) {

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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++) {

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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];

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);