Refactor in preparation for next steps
This commit is contained in:
parent
6bf6e675b3
commit
10d5def069
10
src/Makefile
10
src/Makefile
|
@ -1,19 +1,19 @@
|
|||
TESTS = fft_util_test fft_fr_test fft_g1_test
|
||||
LIB_SRC = fft_util.c fft_fr.c fft_g1.c
|
||||
TESTS = blst_util_test fft_util_test fft_fr_test fft_g1_test
|
||||
LIB_SRC = blst_util.c fft_util.c fft_fr.c fft_g1.c
|
||||
LIB_OBJ = $(LIB_SRC:.c=.o)
|
||||
|
||||
CFLAGS =
|
||||
|
||||
.PRECIOUS: %.o
|
||||
|
||||
%.o: %.c %.h c-kzg.h Makefile
|
||||
%.o: %.c %.h c_kzg.h Makefile
|
||||
clang -Wall $(CFLAGS) -c $*.c
|
||||
|
||||
libckzg.a: $(LIB_OBJ) Makefile
|
||||
ar rc libckzg.a $(LIB_OBJ)
|
||||
|
||||
%_test: %_test.c test_util.o libckzg.a Makefile
|
||||
clang -Wall $(CFLAGS) -o $@ $@.c test_util.o libckzg.a -L../lib -lblst
|
||||
%_test: %_test.c debug_util.o libckzg.a Makefile
|
||||
clang -Wall $(CFLAGS) -o $@ $@.c debug_util.o libckzg.a -L../lib -lblst
|
||||
./$@
|
||||
|
||||
lib: clean libckzg.a
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "blst_util.h"
|
||||
|
||||
bool fr_is_one(const blst_fr *fr_p) {
|
||||
uint64_t a[4];
|
||||
blst_uint64_from_fr(a, fr_p);
|
||||
return a[0] == 1 && a[1] == 0 && a[2] == 0 && a[3] == 0;
|
||||
}
|
||||
|
||||
void fr_from_uint64(blst_fr *a, uint64_t n) {
|
||||
uint64_t vals[] = {n, 0, 0, 0};
|
||||
blst_fr_from_uint64(a, vals);
|
||||
}
|
||||
|
||||
bool fr_equal(blst_fr *aa, blst_fr *bb) {
|
||||
uint64_t a[4], b[4];
|
||||
blst_uint64_from_fr(a, aa);
|
||||
blst_uint64_from_fr(b, bb);
|
||||
return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3];
|
||||
}
|
||||
|
||||
void p1_mul(blst_p1 *out, const blst_p1 *a, const blst_fr *b) {
|
||||
blst_scalar s;
|
||||
blst_scalar_from_fr(&s, b);
|
||||
blst_p1_mult(out, a, s.b, 8 * sizeof(blst_scalar));
|
||||
}
|
||||
|
||||
void p1_sub(blst_p1 *out, const blst_p1 *a, const blst_p1 *b) {
|
||||
blst_p1 bneg = *b;
|
||||
blst_p1_cneg(&bneg, true);
|
||||
blst_p1_add_or_double(out, a, &bneg);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "c_kzg.h"
|
||||
|
||||
// This is 1 in Blst's `blst_fr` limb representation. Crazy but true.
|
||||
static const blst_fr one =
|
||||
{0x00000001fffffffeL, 0x5884b7fa00034802L, 0x998c4fefecbc4ff5L, 0x1824b159acc5056fL};
|
||||
|
||||
bool fr_is_one(const blst_fr *fr_p);
|
||||
void fr_from_uint64(blst_fr *a, uint64_t n);
|
||||
bool fr_equal(blst_fr *aa, blst_fr *bb);
|
||||
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);
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
#include "debug_util.h"
|
||||
#include "blst_util.h"
|
||||
|
||||
void fr_is_one_works(void) {
|
||||
TEST_CHECK(true == fr_is_one(&one));
|
||||
}
|
||||
|
||||
void fr_from_uint64_works(void) {
|
||||
blst_fr a;
|
||||
fr_from_uint64(&a, 1);
|
||||
TEST_CHECK(true == fr_is_one(&a));
|
||||
}
|
||||
|
||||
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);
|
||||
TEST_CHECK(true == fr_equal(&a, &a));
|
||||
TEST_CHECK(false == fr_equal(&a, &b));
|
||||
}
|
||||
|
||||
void p1_mul_works(void) {
|
||||
// This is -1 (the second root of unity)
|
||||
uint64_t m1[] = {0xffffffff00000000L, 0x53bda402fffe5bfeL, 0x3339d80809a1d805L, 0x73eda753299d7d48L};
|
||||
blst_fr minus1;
|
||||
blst_p1 g1_gen, g1_gen_neg, 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);
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// 2 * g1_gen = g1_gen - g1_gen_neg
|
||||
blst_p1_double(&tmp, &g1_gen);
|
||||
p1_sub(&res, &g1_gen, &g1_gen_neg);
|
||||
|
||||
TEST_CHECK(blst_p1_is_equal(&tmp, &res));
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_LIST =
|
||||
{
|
||||
{"fr_is_one_works", fr_is_one_works },
|
||||
{"fr_from_uint64_works", fr_from_uint64_works},
|
||||
{"fr_equal_works", fr_equal_works},
|
||||
{"p1_mul_works", p1_mul_works},
|
||||
{"p1_sub_works", p1_sub_works},
|
||||
{ NULL, NULL } /* zero record marks the end of the list */
|
||||
};
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "test_util.h"
|
||||
#include "debug_util.h"
|
||||
|
||||
//
|
||||
// General Utilities
|
||||
|
@ -45,13 +45,6 @@ void print_fr(const blst_fr *a) {
|
|||
print_bytes_as_hex_le(b.b, 0, 32);
|
||||
}
|
||||
|
||||
bool fr_equal(blst_fr *aa, blst_fr *bb) {
|
||||
uint64_t a[4], b[4];
|
||||
blst_uint64_from_fr(a, aa);
|
||||
blst_uint64_from_fr(b, bb);
|
||||
return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3];
|
||||
}
|
||||
|
||||
//
|
||||
// G1 and G2 utilities
|
||||
//
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "../inc/blst.h"
|
||||
#include "c_kzg.h"
|
||||
|
||||
// General Utilities
|
||||
void print_bytes_as_hex(byte *bytes, int start, int len);
|
||||
|
@ -24,7 +24,6 @@ void print_bytes_as_hex_le(byte *bytes, int start, int len);
|
|||
|
||||
// Fr utilities
|
||||
void print_fr(const blst_fr *a);
|
||||
bool fr_equal(blst_fr *aa, blst_fr *bb);
|
||||
|
||||
// G1 and G2 utilities
|
||||
void print_p1_bytes(byte p1[96]);
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "c-kzg.h"
|
||||
#include "c_kzg.h"
|
||||
#include "fft_util.h"
|
||||
|
||||
void fft_fr_slow(blst_fr *out, blst_fr *in, uint64_t stride, blst_fr *roots, uint64_t roots_stride, uint64_t l);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
#include "test_util.h"
|
||||
#include "debug_util.h"
|
||||
#include "fft_fr.h"
|
||||
|
||||
const uint64_t inv_fft_expected[][4] =
|
||||
|
|
12
src/fft_g1.c
12
src/fft_g1.c
|
@ -16,18 +16,6 @@
|
|||
|
||||
#include "fft_g1.h"
|
||||
|
||||
void p1_mul(blst_p1 *out, const blst_p1 *a, const blst_fr *b) {
|
||||
blst_scalar s;
|
||||
blst_scalar_from_fr(&s, b);
|
||||
blst_p1_mult(out, a, s.b, 8 * sizeof(blst_scalar));
|
||||
}
|
||||
|
||||
void p1_sub(blst_p1 *out, const blst_p1 *a, const blst_p1 *b) {
|
||||
blst_p1 bneg = *b;
|
||||
blst_p1_cneg(&bneg, true);
|
||||
blst_p1_add_or_double(out, a, &bneg);
|
||||
}
|
||||
|
||||
// Slow Fourier Transform (simple, good for small sizes)
|
||||
void fft_g1_slow(blst_p1 *out, blst_p1 *in, uint64_t stride, blst_fr *roots, uint64_t roots_stride, uint64_t l) {
|
||||
blst_p1 v, last, jv;
|
||||
|
|
|
@ -14,11 +14,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "c-kzg.h"
|
||||
#include "c_kzg.h"
|
||||
#include "fft_util.h"
|
||||
|
||||
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 fft_g1_slow(blst_p1 *out, blst_p1 *in, uint64_t stride, blst_fr *roots, uint64_t roots_stride, uint64_t l);
|
||||
void fft_g1_fast(blst_p1 *out, blst_p1 *in, uint64_t stride, blst_fr *roots, uint64_t roots_stride, uint64_t l);
|
||||
C_KZG_RET fft_g1 (blst_p1 *out, blst_p1 *in, FFTSettings *fs, bool inv, uint64_t n);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
#include "test_util.h"
|
||||
#include "debug_util.h"
|
||||
#include "fft_g1.h"
|
||||
|
||||
void make_data(blst_p1 *out, uint64_t n) {
|
||||
|
@ -27,35 +27,6 @@ void make_data(blst_p1 *out, uint64_t n) {
|
|||
}
|
||||
}
|
||||
|
||||
void p1_mul_works(void) {
|
||||
blst_fr minus1;
|
||||
blst_p1 g1_gen, g1_gen_neg, 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, scale2_root_of_unity[1]);
|
||||
p1_mul(&res, &g1_gen, &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));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// 2 * g1_gen = g1_gen - g1_gen_neg
|
||||
blst_p1_double(&tmp, &g1_gen);
|
||||
p1_sub(&res, &g1_gen, &g1_gen_neg);
|
||||
|
||||
TEST_CHECK(blst_p1_is_equal(&tmp, &res));
|
||||
}
|
||||
|
||||
void compare_sft_fft(void) {
|
||||
// Initialise: arbitrary size
|
||||
unsigned int size = 6;
|
||||
|
@ -99,8 +70,6 @@ void roundtrip_fft(void) {
|
|||
|
||||
TEST_LIST =
|
||||
{
|
||||
{"p1_mul_works", p1_mul_works},
|
||||
{"p1_sub_works", p1_sub_works},
|
||||
{"compare_sft_fft", compare_sft_fft},
|
||||
{"roundtrip_fft", roundtrip_fft},
|
||||
{ NULL, NULL } /* zero record marks the end of the list */
|
||||
|
|
|
@ -16,32 +16,21 @@
|
|||
|
||||
#include "fft_util.h"
|
||||
|
||||
bool is_one(const blst_fr *fr_p) {
|
||||
uint64_t a[4];
|
||||
blst_uint64_from_fr(a, fr_p);
|
||||
return a[0] == 1 && a[1] == 0 && a[2] == 0 && a[3] == 0;
|
||||
}
|
||||
|
||||
bool is_power_of_two(uint64_t n) {
|
||||
return (n & (n - 1)) == 0;
|
||||
}
|
||||
|
||||
void fr_from_uint64(blst_fr *a, uint64_t n) {
|
||||
uint64_t vals[] = {n, 0, 0, 0};
|
||||
blst_fr_from_uint64(a, vals);
|
||||
}
|
||||
|
||||
// Create an array of powers of the root of unity
|
||||
// The `out` array must be of size `width + 1`
|
||||
C_KZG_RET expand_root_of_unity(blst_fr *roots, blst_fr *root_of_unity, uint64_t width) {
|
||||
roots[0] = one;
|
||||
roots[1] = *root_of_unity;
|
||||
|
||||
for (int i = 2; !is_one(&roots[i - 1]); i++) {
|
||||
for (int i = 2; !fr_is_one(&roots[i - 1]); i++) {
|
||||
ASSERT(i <= width, C_KZG_ERROR);
|
||||
blst_fr_mul(&roots[i], &roots[i - 1], root_of_unity);
|
||||
}
|
||||
ASSERT(is_one(&roots[width]), C_KZG_ERROR);
|
||||
ASSERT(fr_is_one(&roots[width]), C_KZG_ERROR);
|
||||
|
||||
return C_KZG_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -15,11 +15,8 @@
|
|||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "c-kzg.h"
|
||||
|
||||
// This is 1 in Blst's `blst_fr` limb representation. Crazy but true.
|
||||
static const blst_fr one =
|
||||
{0x00000001fffffffeL, 0x5884b7fa00034802L, 0x998c4fefecbc4ff5L, 0x1824b159acc5056fL};
|
||||
#include "c_kzg.h"
|
||||
#include "blst_util.h"
|
||||
|
||||
// MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513
|
||||
// PRIMITIVE_ROOT = 5
|
||||
|
@ -69,9 +66,7 @@ typedef struct {
|
|||
blst_fr *reverse_roots_of_unity;
|
||||
} FFTSettings;
|
||||
|
||||
bool is_one(const blst_fr *fr_p);
|
||||
bool is_power_of_two(uint64_t n);
|
||||
void fr_from_uint64(blst_fr *a, uint64_t n);
|
||||
C_KZG_RET expand_root_of_unity(blst_fr * roots, blst_fr *root_of_unity, uint64_t width);
|
||||
C_KZG_RET reverse(blst_fr *out, blst_fr *roots, uint64_t width);
|
||||
C_KZG_RET new_fft_settings(FFTSettings *s, unsigned int max_scale);
|
||||
|
|
|
@ -15,15 +15,11 @@
|
|||
*/
|
||||
|
||||
#include "../inc/acutest.h"
|
||||
#include "test_util.h"
|
||||
#include "debug_util.h"
|
||||
#include "fft_util.h"
|
||||
|
||||
#define NUM_ROOTS 32
|
||||
|
||||
void is_one_works(void) {
|
||||
TEST_CHECK(true == is_one(&one));
|
||||
}
|
||||
|
||||
void roots_of_unity_is_the_expected_size(void) {
|
||||
TEST_CHECK(NUM_ROOTS ==
|
||||
sizeof(scale2_root_of_unity) / sizeof(scale2_root_of_unity[0]));
|
||||
|
@ -36,7 +32,7 @@ void roots_of_unity_are_plausible(void) {
|
|||
for (unsigned int j = 0; j < i; j++) {
|
||||
blst_fr_sqr(&r, &r);
|
||||
}
|
||||
TEST_CHECK(true == is_one(&r));
|
||||
TEST_CHECK(true == fr_is_one(&r));
|
||||
TEST_MSG("Root %d failed", i);
|
||||
}
|
||||
}
|
||||
|
@ -58,9 +54,9 @@ void reverse_works(void) {
|
|||
// Verify - decreasing values
|
||||
for (int i = 0; i < n; i++) {
|
||||
blst_fr_sub(&diff, rev + i, rev + i + 1);
|
||||
TEST_CHECK(true == is_one(&diff));
|
||||
TEST_CHECK(true == fr_is_one(&diff));
|
||||
}
|
||||
TEST_CHECK(true == is_one(rev + n));
|
||||
TEST_CHECK(true == fr_is_one(rev + n));
|
||||
}
|
||||
|
||||
void expand_roots_is_plausible(void) {
|
||||
|
@ -74,11 +70,11 @@ void expand_roots_is_plausible(void) {
|
|||
TEST_CHECK(expand_root_of_unity(expanded, &root, width) == C_KZG_SUCCESS);
|
||||
|
||||
// Verify - each pair should multiply to one
|
||||
TEST_CHECK(true == is_one(expanded + 0));
|
||||
TEST_CHECK(true == is_one(expanded + width));
|
||||
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);
|
||||
TEST_CHECK(true == is_one(&prod));
|
||||
TEST_CHECK(true == fr_is_one(&prod));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,7 +90,7 @@ void new_fft_settings_is_plausible(void) {
|
|||
// 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);
|
||||
TEST_CHECK(true == is_one(&prod));
|
||||
TEST_CHECK(true == fr_is_one(&prod));
|
||||
}
|
||||
|
||||
free_fft_settings(&s);
|
||||
|
@ -115,30 +111,13 @@ void is_power_of_two_works(void) {
|
|||
TEST_CHECK(false == is_power_of_two(1234567));
|
||||
}
|
||||
|
||||
void fr_from_uint64_works(void) {
|
||||
blst_fr a;
|
||||
fr_from_uint64(&a, 1);
|
||||
TEST_CHECK(true == is_one(&a));
|
||||
}
|
||||
|
||||
void fr_equal_works(void) {
|
||||
blst_fr a, b;
|
||||
blst_fr_from_uint64(&a, scale2_root_of_unity[15]);
|
||||
blst_fr_from_uint64(&b, scale2_root_of_unity[16]);
|
||||
TEST_CHECK(true == fr_equal(&a, &a));
|
||||
TEST_CHECK(false == fr_equal(&a, &b));
|
||||
}
|
||||
|
||||
TEST_LIST =
|
||||
{
|
||||
{"is_one_works", is_one_works },
|
||||
{"roots_of_unity_is_the_expected_size", roots_of_unity_is_the_expected_size},
|
||||
{"roots_of_unity_are_plausible", roots_of_unity_are_plausible},
|
||||
{"reverse_works", reverse_works},
|
||||
{"expand_roots_is_plausible", expand_roots_is_plausible},
|
||||
{"new_fft_settings_is_plausible", new_fft_settings_is_plausible},
|
||||
{"is_power_of_two_works", is_power_of_two_works},
|
||||
{"fr_from_uint64_works", fr_from_uint64_works},
|
||||
{"fr_equal_works", fr_equal_works},
|
||||
{ NULL, NULL } /* zero record marks the end of the list */
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue