From 1dc17214310ae4ff17555cc4014fcedbb6c641ce Mon Sep 17 00:00:00 2001 From: Bowen Xue <93296844+bxue-l2@users.noreply.github.com> Date: Sun, 25 Feb 2024 22:55:06 -0800 Subject: [PATCH] rm custom bn254 under kzg and cleanup (#280) Co-authored-by: bxue@eigenlabs.org --- .gitignore | 5 +- clients/retrieval_client.go | 4 +- clients/tests/retrieval_client_test.go | 8 +- core/data.go | 3 +- core/serialization_test.go | 3 +- core/test/core_test.go | 8 +- disperser/batcher/batcher_test.go | 6 +- disperser/cmd/batcher/config.go | 6 +- disperser/cmd/encoder/config.go | 6 +- disperser/cmd/encoder/encoder.go | 2 +- disperser/cmd/encoder/flags/flags.go | 4 +- disperser/encoder/server_test.go | 10 +- .../bn254/globals.go => encoding/constants.go | 75 ++--- encoding/data.go | 15 +- {pkg/kzg => encoding/fft}/errors.go | 4 +- {pkg/kzg => encoding/fft}/fft.go | 32 +- {pkg/kzg => encoding/fft}/fft_fr.go | 95 +++--- encoding/fft/fft_fr_test.go | 102 ++++++ {pkg/kzg => encoding/fft}/fft_g1.go | 96 +++--- .../fft}/recover_from_samples.go | 84 +++-- .../fft}/recover_from_samples_test.go | 42 +-- {pkg/kzg => encoding/fft}/zero_poly.go | 98 ++++-- {pkg/kzg => encoding/fft}/zero_poly_test.go | 72 ++--- encoding/{kzgrs => kzg}/cli.go | 2 +- encoding/kzg/constants.go | 40 +++ pkg/kzg/poly.go => encoding/kzg/kzg.go | 67 ++-- encoding/{kzgrs => kzg}/kzgrs.go | 2 +- encoding/{kzgrs => kzg}/pointsIO.go | 52 +-- encoding/{kzgrs => kzg}/prover/decode.go | 0 encoding/{kzgrs => kzg}/prover/decode_test.go | 2 +- .../prover/parametrized_prover.go | 105 ++++--- .../prover/parametrized_prover_test.go | 10 +- encoding/{kzgrs => kzg}/prover/precompute.go | 66 ++-- .../{kzgrs => kzg}/prover/precompute_test.go | 8 +- encoding/{kzgrs => kzg}/prover/prover.go | 54 +--- .../{kzgrs => kzg}/prover/prover_fuzz_test.go | 2 +- encoding/{kzgrs => kzg}/prover/prover_test.go | 10 +- encoding/kzg/setup.go | 134 ++++++++ {pkg => encoding}/kzg/srs.go | 10 +- .../verifier/batch_commit_equivalence.go | 61 ++-- .../verifier/batch_commit_equivalence_test.go | 14 +- .../{kzgrs => kzg}/verifier/degree_test.go | 4 +- .../{kzgrs => kzg}/verifier/frame_test.go | 15 +- .../{kzgrs => kzg}/verifier/multiframe.go | 130 ++++---- .../verifier/multiframe_test.go | 4 +- encoding/{kzgrs => kzg}/verifier/verifier.go | 123 +++++--- .../{kzgrs => kzg}/verifier/verifier_test.go | 10 +- encoding/params.go | 5 +- encoding/rs/decode.go | 12 +- encoding/rs/encode.go | 22 +- encoding/rs/encoder.go | 6 +- encoding/rs/encoder_suite_test.go | 1 - encoding/rs/frame.go | 4 +- encoding/rs/interpolation.go | 51 +-- encoding/rs/params.go | 6 +- encoding/rs/utils.go | 28 +- encoding/test/main.go | 72 ++--- encoding/test/testCrypto.go | 55 +--- encoding/test/testKzgBn254.go | 4 +- encoding/utils.go | 15 +- encoding/utils/reverseBits/reverseBits.go | 29 +- encoding/utils/toeplitz/cir.go | 97 ++---- encoding/utils/toeplitz/cir_test.go | 146 ++------- encoding/utils/toeplitz/toeplitz.go | 84 +++-- encoding/utils/toeplitz/toeplitz_test.go | 163 ++++------ inabox/tests/integration_suite_test.go | 6 +- node/config.go | 6 +- node/flags/flags.go | 4 +- node/grpc/server_test.go | 8 +- node/node.go | 2 +- node/store_test.go | 9 +- pkg/kzg/LICENSE | 21 -- pkg/kzg/README.md | 57 ---- pkg/kzg/bn254/bignum_gnark.go | 126 -------- pkg/kzg/bn254/bignum_gnark_test.go | 193 ------------ pkg/kzg/bn254/bn254_all.go | 64 ---- pkg/kzg/bn254/bn254_all_test.go | 96 ------ pkg/kzg/bn254/bn254_gnark.go | 277 ---------------- pkg/kzg/bn254/bn254_gnark_test.go | 295 ------------------ pkg/kzg/bn254/globals_test.go | 57 ---- pkg/kzg/das_extension.go | 108 ------- pkg/kzg/das_extension_test.go | 99 ------ pkg/kzg/fft_fr_test.go | 89 ------ pkg/kzg/fk20_multi.go | 155 --------- pkg/kzg/fk20_multi_test.go | 116 ------- pkg/kzg/fk20_single.go | 217 ------------- pkg/kzg/fk20_single_test.go | 62 ---- pkg/kzg/integration_test.go | 184 ----------- pkg/kzg/kzg.go | 129 -------- pkg/kzg/kzg_multi_proofs.go | 123 -------- pkg/kzg/kzg_multi_proofs_test.go | 67 ---- pkg/kzg/kzg_single_proofs.go | 281 ----------------- pkg/kzg/kzg_single_proofs_test.go | 80 ----- pkg/kzg/legacy_recover_test.go | 144 --------- pkg/kzg/legacy_recovery.go | 293 ----------------- pkg/kzg/reverse_bit_order.go | 126 -------- pkg/kzg/reverse_bit_order_test.go | 84 ----- pkg/kzg/setup.go | 204 ------------ retriever/cmd/main.go | 2 +- retriever/config.go | 6 +- retriever/flags/flags.go | 4 +- retriever/server_test.go | 8 +- test/integration_test.go | 11 +- test/synthetic-test/synthetic_client_test.go | 8 +- 104 files changed, 1354 insertions(+), 4972 deletions(-) rename pkg/kzg/bn254/globals.go => encoding/constants.go (73%) rename {pkg/kzg => encoding/fft}/errors.go (93%) rename {pkg/kzg => encoding/fft}/fft.go (78%) rename {pkg/kzg => encoding/fft}/fft_fr.go (60%) create mode 100644 encoding/fft/fft_fr_test.go rename {pkg/kzg => encoding/fft}/fft_g1.go (65%) rename {pkg/kzg => encoding/fft}/recover_from_samples.go (66%) rename {pkg/kzg => encoding/fft}/recover_from_samples_test.go (77%) rename {pkg/kzg => encoding/fft}/zero_poly.go (81%) rename {pkg/kzg => encoding/fft}/zero_poly_test.go (82%) rename encoding/{kzgrs => kzg}/cli.go (99%) create mode 100644 encoding/kzg/constants.go rename pkg/kzg/poly.go => encoding/kzg/kzg.go (58%) rename encoding/{kzgrs => kzg}/kzgrs.go (96%) rename encoding/{kzgrs => kzg}/pointsIO.go (86%) rename encoding/{kzgrs => kzg}/prover/decode.go (100%) rename encoding/{kzgrs => kzg}/prover/decode_test.go (93%) rename encoding/{kzgrs => kzg}/prover/parametrized_prover.go (65%) rename encoding/{kzgrs => kzg}/prover/parametrized_prover_test.go (75%) rename encoding/{kzgrs => kzg}/prover/precompute.go (82%) rename encoding/{kzgrs => kzg}/prover/precompute_test.go (82%) rename encoding/{kzgrs => kzg}/prover/prover.go (84%) rename encoding/{kzgrs => kzg}/prover/prover_fuzz_test.go (95%) rename encoding/{kzgrs => kzg}/prover/prover_test.go (95%) create mode 100644 encoding/kzg/setup.go rename {pkg => encoding}/kzg/srs.go (89%) rename encoding/{kzgrs => kzg}/verifier/batch_commit_equivalence.go (54%) rename encoding/{kzgrs => kzg}/verifier/batch_commit_equivalence_test.go (81%) rename encoding/{kzgrs => kzg}/verifier/degree_test.go (91%) rename encoding/{kzgrs => kzg}/verifier/frame_test.go (68%) rename encoding/{kzgrs => kzg}/verifier/multiframe.go (67%) rename encoding/{kzgrs => kzg}/verifier/multiframe_test.go (95%) rename encoding/{kzgrs => kzg}/verifier/verifier.go (66%) rename encoding/{kzgrs => kzg}/verifier/verifier_test.go (95%) delete mode 100644 pkg/kzg/LICENSE delete mode 100644 pkg/kzg/README.md delete mode 100644 pkg/kzg/bn254/bignum_gnark.go delete mode 100644 pkg/kzg/bn254/bignum_gnark_test.go delete mode 100644 pkg/kzg/bn254/bn254_all.go delete mode 100644 pkg/kzg/bn254/bn254_all_test.go delete mode 100644 pkg/kzg/bn254/bn254_gnark.go delete mode 100644 pkg/kzg/bn254/bn254_gnark_test.go delete mode 100644 pkg/kzg/bn254/globals_test.go delete mode 100644 pkg/kzg/das_extension.go delete mode 100644 pkg/kzg/das_extension_test.go delete mode 100644 pkg/kzg/fft_fr_test.go delete mode 100644 pkg/kzg/fk20_multi.go delete mode 100644 pkg/kzg/fk20_multi_test.go delete mode 100644 pkg/kzg/fk20_single.go delete mode 100644 pkg/kzg/fk20_single_test.go delete mode 100644 pkg/kzg/integration_test.go delete mode 100644 pkg/kzg/kzg.go delete mode 100644 pkg/kzg/kzg_multi_proofs.go delete mode 100644 pkg/kzg/kzg_multi_proofs_test.go delete mode 100644 pkg/kzg/kzg_single_proofs.go delete mode 100644 pkg/kzg/kzg_single_proofs_test.go delete mode 100644 pkg/kzg/legacy_recover_test.go delete mode 100644 pkg/kzg/legacy_recovery.go delete mode 100644 pkg/kzg/reverse_bit_order.go delete mode 100644 pkg/kzg/reverse_bit_order_test.go delete mode 100644 pkg/kzg/setup.go diff --git a/.gitignore b/.gitignore index 3d15c6dde9..bbf26b13d7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,11 @@ inabox/anvil.pid test/testdata/* inabox/resources/kzg/SRSTables/* +encoding/kzgrs/prover/data/SRSTable/* **/bin/* coverage.* -contracts/broadcast \ No newline at end of file +contracts/broadcast + + diff --git a/clients/retrieval_client.go b/clients/retrieval_client.go index baad69bdf2..71f1ad6aec 100644 --- a/clients/retrieval_client.go +++ b/clients/retrieval_client.go @@ -7,7 +7,7 @@ import ( "github.com/Layr-Labs/eigenda/common" "github.com/Layr-Labs/eigenda/core" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/gammazero/workerpool" "github.com/wealdtech/go-merkletree" "github.com/wealdtech/go-merkletree/keccak256" @@ -172,5 +172,5 @@ func (r *retrievalClient) RetrieveBlob( indices = append(indices, assignment.GetIndices()...) } - return r.verifier.Decode(chunks, indices, encodingParams, uint64(blobHeader.Length)*bn254.BYTES_PER_COEFFICIENT) + return r.verifier.Decode(chunks, indices, encodingParams, uint64(blobHeader.Length)*encoding.BYTES_PER_COEFFICIENT) } diff --git a/clients/tests/retrieval_client_test.go b/clients/tests/retrieval_client_test.go index 977bd3b5ee..1c859fb233 100644 --- a/clients/tests/retrieval_client_test.go +++ b/clients/tests/retrieval_client_test.go @@ -13,9 +13,9 @@ import ( coreindexer "github.com/Layr-Labs/eigenda/core/indexer" coremock "github.com/Layr-Labs/eigenda/core/mock" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" indexermock "github.com/Layr-Labs/eigenda/indexer/mock" "github.com/consensys/gnark-crypto/ecc/bn254" "github.com/stretchr/testify/assert" @@ -27,7 +27,7 @@ import ( const numOperators = 10 func makeTestComponents() (encoding.Prover, encoding.Verifier, error) { - config := &kzgrs.KzgConfig{ + config := &kzg.KzgConfig{ G1Path: "../../inabox/resources/kzg/g1.point", G2Path: "../../inabox/resources/kzg/g2.point", CacheDir: "../../inabox/resources/kzg/SRSTables", diff --git a/core/data.go b/core/data.go index b0469d0ab8..9185edda5b 100644 --- a/core/data.go +++ b/core/data.go @@ -6,7 +6,6 @@ import ( "github.com/Layr-Labs/eigenda/common" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" ) type AccountID = string @@ -122,7 +121,7 @@ func (b *BlobHeader) EncodedSizeAllQuorums() int64 { size := int64(0) for _, quorum := range b.QuorumInfos { - size += int64(roundUpDivide(b.Length*percentMultiplier*bn254.BYTES_PER_COEFFICIENT, uint(quorum.QuorumThreshold-quorum.AdversaryThreshold))) + size += int64(roundUpDivide(b.Length*percentMultiplier*encoding.BYTES_PER_COEFFICIENT, uint(quorum.QuorumThreshold-quorum.AdversaryThreshold))) } return size } diff --git a/core/serialization_test.go b/core/serialization_test.go index 6a15ceab9f..ae90b3a12c 100644 --- a/core/serialization_test.go +++ b/core/serialization_test.go @@ -9,7 +9,6 @@ import ( "github.com/Layr-Labs/eigenda/core" "github.com/Layr-Labs/eigenda/core/eth" "github.com/Layr-Labs/eigenda/encoding" - kzgbn254 "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" "github.com/consensys/gnark-crypto/ecc/bn254" "github.com/consensys/gnark-crypto/ecc/bn254/fp" "github.com/ethereum/go-ethereum/common" @@ -73,7 +72,7 @@ func TestBlobHeaderEncoding(t *testing.T) { _, err = lengthYA1.SetString("4082367875863433681332203403145435568316851327593401208105741076214120093531") assert.NoError(t, err) - var lengthProof, lengthCommitment kzgbn254.G2Point + var lengthProof, lengthCommitment bn254.G2Affine lengthProof.X.A0 = lengthXA0 lengthProof.X.A1 = lengthXA1 lengthProof.Y.A0 = lengthYA0 diff --git a/core/test/core_test.go b/core/test/core_test.go index 5f8c4b3cc1..80b4e1ff4a 100644 --- a/core/test/core_test.go +++ b/core/test/core_test.go @@ -12,9 +12,9 @@ import ( "github.com/Layr-Labs/eigenda/core" "github.com/Layr-Labs/eigenda/core/mock" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/gammazero/workerpool" "github.com/stretchr/testify/assert" ) @@ -42,7 +42,7 @@ func setup(m *testing.M) { // makeTestComponents makes a prover and verifier currently using the only supported backend. func makeTestComponents() (encoding.Prover, encoding.Verifier, error) { - config := &kzgrs.KzgConfig{ + config := &kzg.KzgConfig{ G1Path: "../../inabox/resources/kzg/g1.point", G2Path: "../../inabox/resources/kzg/g2.point", CacheDir: "../../inabox/resources/kzg/SRSTables", diff --git a/disperser/batcher/batcher_test.go b/disperser/batcher/batcher_test.go index 86ed7308c0..b1232a849e 100644 --- a/disperser/batcher/batcher_test.go +++ b/disperser/batcher/batcher_test.go @@ -21,8 +21,8 @@ import ( "github.com/Layr-Labs/eigenda/disperser/common/inmem" dmock "github.com/Layr-Labs/eigenda/disperser/mock" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/assert" @@ -45,7 +45,7 @@ type batcherComponents struct { // makeTestEncoder makes an encoder currently using the only supported backend. func makeTestProver() (encoding.Prover, error) { - config := &kzgrs.KzgConfig{ + config := &kzg.KzgConfig{ G1Path: "../../inabox/resources/kzg/g1.point", G2Path: "../../inabox/resources/kzg/g2.point", CacheDir: "../../inabox/resources/kzg/SRSTables", diff --git a/disperser/cmd/batcher/config.go b/disperser/cmd/batcher/config.go index f1b5e656ec..c5209b6b43 100644 --- a/disperser/cmd/batcher/config.go +++ b/disperser/cmd/batcher/config.go @@ -7,7 +7,7 @@ import ( "github.com/Layr-Labs/eigenda/disperser/batcher" "github.com/Layr-Labs/eigenda/disperser/cmd/batcher/flags" "github.com/Layr-Labs/eigenda/disperser/common/blobstore" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" + "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/Layr-Labs/eigenda/indexer" "github.com/urfave/cli" ) @@ -18,7 +18,7 @@ type Config struct { BlobstoreConfig blobstore.Config EthClientConfig geth.EthClientConfig AwsClientConfig aws.ClientConfig - EncoderConfig kzgrs.KzgConfig + EncoderConfig kzg.KzgConfig LoggerConfig logging.Config MetricsConfig batcher.MetricsConfig IndexerConfig indexer.Config @@ -40,7 +40,7 @@ func NewConfig(ctx *cli.Context) Config { }, EthClientConfig: geth.ReadEthClientConfig(ctx), AwsClientConfig: aws.ReadClientConfig(ctx, flags.FlagPrefix), - EncoderConfig: kzgrs.ReadCLIConfig(ctx), + EncoderConfig: kzg.ReadCLIConfig(ctx), LoggerConfig: logging.ReadCLIConfig(ctx, flags.FlagPrefix), BatcherConfig: batcher.Config{ PullInterval: ctx.GlobalDuration(flags.PullIntervalFlag.Name), diff --git a/disperser/cmd/encoder/config.go b/disperser/cmd/encoder/config.go index 124af71e1c..5cdc4d65bd 100644 --- a/disperser/cmd/encoder/config.go +++ b/disperser/cmd/encoder/config.go @@ -4,12 +4,12 @@ import ( "github.com/Layr-Labs/eigenda/common/logging" "github.com/Layr-Labs/eigenda/disperser/cmd/encoder/flags" "github.com/Layr-Labs/eigenda/disperser/encoder" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" + "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/urfave/cli" ) type Config struct { - EncoderConfig kzgrs.KzgConfig + EncoderConfig kzg.KzgConfig LoggerConfig logging.Config ServerConfig *encoder.ServerConfig MetricsConfig encoder.MetrisConfig @@ -17,7 +17,7 @@ type Config struct { func NewConfig(ctx *cli.Context) Config { config := Config{ - EncoderConfig: kzgrs.ReadCLIConfig(ctx), + EncoderConfig: kzg.ReadCLIConfig(ctx), LoggerConfig: logging.ReadCLIConfig(ctx, flags.FlagPrefix), ServerConfig: &encoder.ServerConfig{ GrpcPort: ctx.GlobalString(flags.GrpcPortFlag.Name), diff --git a/disperser/cmd/encoder/encoder.go b/disperser/cmd/encoder/encoder.go index c16d6b2739..7062b139e8 100644 --- a/disperser/cmd/encoder/encoder.go +++ b/disperser/cmd/encoder/encoder.go @@ -6,7 +6,7 @@ import ( "github.com/Layr-Labs/eigenda/common" "github.com/Layr-Labs/eigenda/disperser/encoder" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" ) type EncoderGRPCServer struct { diff --git a/disperser/cmd/encoder/flags/flags.go b/disperser/cmd/encoder/flags/flags.go index aadc5b826f..7262156986 100644 --- a/disperser/cmd/encoder/flags/flags.go +++ b/disperser/cmd/encoder/flags/flags.go @@ -3,7 +3,7 @@ package flags import ( "github.com/Layr-Labs/eigenda/common" "github.com/Layr-Labs/eigenda/common/logging" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" + "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/urfave/cli" ) @@ -66,6 +66,6 @@ var Flags []cli.Flag func init() { Flags = append(requiredFlags, optionalFlags...) - Flags = append(Flags, kzgrs.CLIFlags(envVarPrefix)...) + Flags = append(Flags, kzg.CLIFlags(envVarPrefix)...) Flags = append(Flags, logging.CLIFlags(envVarPrefix, FlagPrefix)...) } diff --git a/disperser/encoder/server_test.go b/disperser/encoder/server_test.go index 0ff38ff435..8a083cb060 100644 --- a/disperser/encoder/server_test.go +++ b/disperser/encoder/server_test.go @@ -10,10 +10,12 @@ import ( "testing" "time" + "github.com/consensys/gnark-crypto/ecc/bn254" "github.com/consensys/gnark-crypto/ecc/bn254/fp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "github.com/Layr-Labs/eigenda/encoding/kzg" encmock "github.com/Layr-Labs/eigenda/encoding/mock" cmock "github.com/Layr-Labs/eigenda/common/mock" @@ -21,9 +23,7 @@ import ( coremock "github.com/Layr-Labs/eigenda/core/mock" pb "github.com/Layr-Labs/eigenda/disperser/api/grpc/encoder" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" ) var ( @@ -33,7 +33,7 @@ var ( var logger = &cmock.Logger{} func makeTestProver(numPoint uint64) (encoding.Prover, ServerConfig) { - kzgConfig := &kzgrs.KzgConfig{ + kzgConfig := &kzg.KzgConfig{ G1Path: "../../inabox/resources/kzg/g1.point", G2Path: "../../inabox/resources/kzg/g2.point", CacheDir: "../../inabox/resources/kzg/SRSTables", @@ -163,7 +163,7 @@ func TestThrottling(t *testing.T) { _, err = lengthYA1.SetString("4082367875863433681332203403145435568316851327593401208105741076214120093531") assert.NoError(t, err) - var lengthProof, lengthCommitment bn254.G2Point + var lengthProof, lengthCommitment bn254.G2Affine lengthProof.X.A0 = lengthXA0 lengthProof.X.A1 = lengthXA1 lengthProof.Y.A0 = lengthYA0 diff --git a/pkg/kzg/bn254/globals.go b/encoding/constants.go similarity index 73% rename from pkg/kzg/bn254/globals.go rename to encoding/constants.go index c92fe0c752..ba8ba6d44c 100644 --- a/pkg/kzg/bn254/globals.go +++ b/encoding/constants.go @@ -1,20 +1,35 @@ -package bn254 +package encoding -func ToFr(v string) (out Fr) { - SetFr(&out, v) - return -} +import ( + "fmt" + + "github.com/consensys/gnark-crypto/ecc/bn254/fr" +) const BYTES_PER_COEFFICIENT = 31 -var Scale2RootOfUnity []Fr -var ZERO, ONE, TWO Fr -var MODULUS_MINUS1, MODULUS_MINUS1_DIV2, MODULUS_MINUS2 Fr -var INVERSE_TWO Fr +func init() { + initGlobals() +} + +func ToFr(v string) fr.Element { + var out fr.Element + _, err := out.SetString(v) + if err != nil { + fmt.Println("Failed to initialize Root of Unity") + panic(err) + } + return out +} + +var Scale2RootOfUnity []fr.Element +var ZERO, ONE, TWO fr.Element +var MODULUS_MINUS1, MODULUS_MINUS1_DIV2, MODULUS_MINUS2 fr.Element +var INVERSE_TWO fr.Element // copied from https://github.com/adjoint-io/pairing/blob/master/src/Data/Pairing/BN254.hs func initGlobals() { - Scale2RootOfUnity = []Fr{ + Scale2RootOfUnity = []fr.Element{ ToFr("1"), ToFr("21888242871839275222246405745257275088548364400416034343698204186575808495616"), ToFr("21888242871839275217838484774961031246007050428528088939761107053157389710902"), @@ -46,37 +61,11 @@ func initGlobals() { ToFr("19103219067921713944291392827692070036145651957329286315305642004821462161904"), } - AsFr(&ZERO, 0) - AsFr(&ONE, 1) - AsFr(&TWO, 2) - - SubModFr(&MODULUS_MINUS1, &ZERO, &ONE) - DivModFr(&MODULUS_MINUS1_DIV2, &MODULUS_MINUS1, &TWO) - SubModFr(&MODULUS_MINUS2, &ZERO, &TWO) - InvModFr(&INVERSE_TWO, &TWO) -} - -func IsPowerOfTwo(v uint64) bool { - return v&(v-1) == 0 -} - -func EvalPolyAtUnoptimized(dst *Fr, coeffs []Fr, x *Fr) { - if len(coeffs) == 0 { - CopyFr(dst, &ZERO) - return - } - if EqualZero(x) { - CopyFr(dst, &coeffs[0]) - return - } - // Horner's method: work backwards, avoid doing more than N multiplications - // https://en.wikipedia.org/wiki/Horner%27s_method - var last Fr - CopyFr(&last, &coeffs[len(coeffs)-1]) - var tmp Fr - for i := len(coeffs) - 2; i >= 0; i-- { - MulModFr(&tmp, &last, x) - AddModFr(&last, &tmp, &coeffs[i]) - } - CopyFr(dst, &last) + ZERO.SetZero() + ONE.SetOne() + TWO.SetInt64(int64(2)) + MODULUS_MINUS1.Sub(&ZERO, &ONE) + MODULUS_MINUS1_DIV2.Div(&MODULUS_MINUS1, &TWO) + MODULUS_MINUS2.Sub(&ZERO, &TWO) + INVERSE_TWO.Inverse(&TWO) } diff --git a/encoding/data.go b/encoding/data.go index b8c94e65c1..2bcc2bfc21 100644 --- a/encoding/data.go +++ b/encoding/data.go @@ -1,21 +1,24 @@ package encoding -import "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" +import ( + "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" +) // Commitment is a polynomial commitment (e.g. a kzg commitment) -type G1Commitment bn254.G1Point +type G1Commitment bn254.G1Affine // Commitment is a polynomial commitment (e.g. a kzg commitment) -type G2Commitment bn254.G2Point +type G2Commitment bn254.G2Affine // LengthProof is a polynomial commitment on G2 (e.g. a kzg commitment) used for low degree proof type LengthProof = G2Commitment // The proof used to open a commitment. In the case of Kzg, this is also a kzg commitment, and is different from a Commitment only semantically. -type Proof = bn254.G1Point +type Proof = bn254.G1Affine // Symbol is a symbol in the field used for polynomial commitments -type Symbol = bn254.Fr +type Symbol = fr.Element // BlomCommitments contains the blob's commitment, degree proof, and the actual degree. type BlobCommitments struct { @@ -39,7 +42,7 @@ func (f *Frame) Length() int { // Returns the size of chunk in bytes. func (f *Frame) Size() int { - return f.Length() * bn254.BYTES_PER_COEFFICIENT + return f.Length() * BYTES_PER_COEFFICIENT } // Sample is a chunk with associated metadata used by the Universal Batch Verifier diff --git a/pkg/kzg/errors.go b/encoding/fft/errors.go similarity index 93% rename from pkg/kzg/errors.go rename to encoding/fft/errors.go index 4db562faa6..ea7efeadcc 100644 --- a/pkg/kzg/errors.go +++ b/encoding/fft/errors.go @@ -22,14 +22,12 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -package kzg +package fft import ( "errors" ) -var ErrFrListTooLarge = errors.New("ErrFrListTooLarge") -var ErrG1ListTooLarge = errors.New("ErrG1ListTooLarge") var ErrZeroPolyTooLarge = errors.New("ErrZeroPolyTooLarge") var ErrDestNotPowerOfTwo = errors.New("ErrDestNotPowerOfTwo") var ErrEmptyLeaves = errors.New("ErrEmptyLeaves") diff --git a/pkg/kzg/fft.go b/encoding/fft/fft.go similarity index 78% rename from pkg/kzg/fft.go rename to encoding/fft/fft.go index 9c4b9f7b57..aec175fcca 100644 --- a/pkg/kzg/fft.go +++ b/encoding/fft/fft.go @@ -24,10 +24,11 @@ // Original: https://github.com/ethereum/research/blob/master/mimc_stark/fft.py -package kzg +package fft import ( - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/Layr-Labs/eigenda/encoding" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" "math/bits" ) @@ -43,15 +44,17 @@ func nextPowOf2(v uint64) uint64 { // Expands the power circle for a given root of unity to WIDTH+1 values. // The first entry will be 1, the last entry will also be 1, // for convenience when reversing the array (useful for inverses) -func expandRootOfUnity(rootOfUnity *bls.Fr) []bls.Fr { - rootz := make([]bls.Fr, 2) - rootz[0] = bls.ONE // some unused number in py code +func expandRootOfUnity(rootOfUnity *fr.Element) []fr.Element { + rootz := make([]fr.Element, 2) + rootz[0].SetOne() // some unused number in py code rootz[1] = *rootOfUnity - for i := 1; !bls.EqualOne(&rootz[i]); { - rootz = append(rootz, bls.Fr{}) + + for i := 1; !rootz[i].IsOne(); { + rootz = append(rootz, fr.Element{}) this := &rootz[i] i++ - bls.MulModFr(&rootz[i], this, rootOfUnity) + rootz[i].Mul(this, rootOfUnity) + //bls.MulModFr(&rootz[i], this, rootOfUnity) } return rootz } @@ -59,19 +62,20 @@ func expandRootOfUnity(rootOfUnity *bls.Fr) []bls.Fr { type FFTSettings struct { MaxWidth uint64 // the generator used to get all roots of unity - RootOfUnity *bls.Fr + RootOfUnity *fr.Element // domain, starting and ending with 1 (duplicate!) - ExpandedRootsOfUnity []bls.Fr + ExpandedRootsOfUnity []fr.Element // reverse domain, same as inverse values of domain. Also starting and ending with 1. - ReverseRootsOfUnity []bls.Fr + ReverseRootsOfUnity []fr.Element } func NewFFTSettings(maxScale uint8) *FFTSettings { width := uint64(1) << maxScale - root := &bls.Scale2RootOfUnity[maxScale] - rootz := expandRootOfUnity(&bls.Scale2RootOfUnity[maxScale]) + root := &encoding.Scale2RootOfUnity[maxScale] + rootz := expandRootOfUnity(&encoding.Scale2RootOfUnity[maxScale]) + // reverse roots of unity - rootzReverse := make([]bls.Fr, len(rootz)) + rootzReverse := make([]fr.Element, len(rootz)) copy(rootzReverse, rootz) for i, j := uint64(0), uint64(len(rootz)-1); i < j; i, j = i+1, j-1 { rootzReverse[i], rootzReverse[j] = rootzReverse[j], rootzReverse[i] diff --git a/pkg/kzg/fft_fr.go b/encoding/fft/fft_fr.go similarity index 60% rename from pkg/kzg/fft_fr.go rename to encoding/fft/fft_fr.go index 10d6aaebf9..2fae4af69d 100644 --- a/pkg/kzg/fft_fr.go +++ b/encoding/fft/fft_fr.go @@ -21,37 +21,37 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -package kzg +package fft import ( "fmt" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) -func (fs *FFTSettings) simpleFT(vals []bls.Fr, valsOffset uint64, valsStride uint64, rootsOfUnity []bls.Fr, rootsOfUnityStride uint64, out []bls.Fr) { +func (fs *FFTSettings) simpleFT(vals []fr.Element, valsOffset uint64, valsStride uint64, rootsOfUnity []fr.Element, rootsOfUnityStride uint64, out []fr.Element) { l := uint64(len(out)) - var v bls.Fr - var tmp bls.Fr - var last bls.Fr + var v fr.Element + var tmp fr.Element + var last fr.Element for i := uint64(0); i < l; i++ { jv := &vals[valsOffset] r := &rootsOfUnity[0] - bls.MulModFr(&v, jv, r) - bls.CopyFr(&last, &v) + v.Mul(jv, r) + last.Set(&v) for j := uint64(1); j < l; j++ { jv := &vals[valsOffset+j*valsStride] r := &rootsOfUnity[((i*j)%l)*rootsOfUnityStride] - bls.MulModFr(&v, jv, r) - bls.CopyFr(&tmp, &last) - bls.AddModFr(&last, &tmp, &v) + v.Mul(jv, r) + tmp.Set(&last) + last.Add(&tmp, &v) } - bls.CopyFr(&out[i], &last) + out[i].Set(&last) } } -func (fs *FFTSettings) _fft(vals []bls.Fr, valsOffset uint64, valsStride uint64, rootsOfUnity []bls.Fr, rootsOfUnityStride uint64, out []bls.Fr) { +func (fs *FFTSettings) _fft(vals []fr.Element, valsOffset uint64, valsStride uint64, rootsOfUnity []fr.Element, rootsOfUnityStride uint64, out []fr.Element) { if len(out) <= 4 { // if the value count is small, run the unoptimized version instead. // TODO tune threshold. fs.simpleFT(vals, valsOffset, valsStride, rootsOfUnity, rootsOfUnityStride, out) return @@ -63,60 +63,64 @@ func (fs *FFTSettings) _fft(vals []bls.Fr, valsOffset uint64, valsStride uint64, // R will be the right half of out fs._fft(vals, valsOffset+valsStride, valsStride<<1, rootsOfUnity, rootsOfUnityStride<<1, out[half:]) // just take even again - var yTimesRoot bls.Fr - var x, y bls.Fr + var yTimesRoot fr.Element + var x, y fr.Element for i := uint64(0); i < half; i++ { // temporary copies, so that writing to output doesn't conflict with input - bls.CopyFr(&x, &out[i]) - bls.CopyFr(&y, &out[i+half]) + x.Set(&out[i]) + y.Set(&out[i+half]) + root := &rootsOfUnity[i*rootsOfUnityStride] - bls.MulModFr(&yTimesRoot, &y, root) - bls.AddModFr(&out[i], &x, &yTimesRoot) - bls.SubModFr(&out[i+half], &x, &yTimesRoot) + yTimesRoot.Mul(&y, root) + out[i].Add(&x, &yTimesRoot) + out[i+half].Sub(&x, &yTimesRoot) } } -func (fs *FFTSettings) FFT(vals []bls.Fr, inv bool) ([]bls.Fr, error) { +func (fs *FFTSettings) FFT(vals []fr.Element, inv bool) ([]fr.Element, error) { n := uint64(len(vals)) if n > fs.MaxWidth { return nil, fmt.Errorf("got %d values but only have %d roots of unity", n, fs.MaxWidth) } n = nextPowOf2(n) // We make a copy so we can mutate it during the work. - valsCopy := make([]bls.Fr, n) + valsCopy := make([]fr.Element, n) for i := 0; i < len(vals); i++ { - bls.CopyFr(&valsCopy[i], &vals[i]) + valsCopy[i].Set(&vals[i]) + } for i := uint64(len(vals)); i < n; i++ { - bls.CopyFr(&valsCopy[i], &bls.ZERO) + valsCopy[i].SetZero() } - out := make([]bls.Fr, n) + out := make([]fr.Element, n) if err := fs.InplaceFFT(valsCopy, out, inv); err != nil { return nil, err } return out, nil } -func (fs *FFTSettings) InplaceFFT(vals []bls.Fr, out []bls.Fr, inv bool) error { +func (fs *FFTSettings) InplaceFFT(vals []fr.Element, out []fr.Element, inv bool) error { n := uint64(len(vals)) if n > fs.MaxWidth { return fmt.Errorf("got %d values but only have %d roots of unity", n, fs.MaxWidth) } - if !bls.IsPowerOfTwo(n) { + if !IsPowerOfTwo(n) { return fmt.Errorf("got %d values but not a power of two", n) } if inv { - var invLen bls.Fr - bls.AsFr(&invLen, n) - bls.InvModFr(&invLen, &invLen) + var invLen fr.Element + + invLen.SetInt64(int64(n)) + + invLen.Inverse(&invLen) rootz := fs.ReverseRootsOfUnity[:fs.MaxWidth] stride := fs.MaxWidth / n fs._fft(vals, 0, 1, rootz, stride, out) - var tmp bls.Fr + var tmp fr.Element for i := 0; i < len(out); i++ { - bls.MulModFr(&tmp, &out[i], &invLen) - bls.CopyFr(&out[i], &tmp) // TODO: depending on Fr implementation, allow to directly write back to an input + tmp.Mul(&out[i], &invLen) + out[i].Set(&tmp) } return nil } else { @@ -128,27 +132,6 @@ func (fs *FFTSettings) InplaceFFT(vals []bls.Fr, out []bls.Fr, inv bool) error { } } -// rearrange Fr elements in reverse bit order. Supports 2**31 max element count. -func reverseBitOrderFr(values []bls.Fr) error { - if len(values) > (1 << 31) { - return ErrFrListTooLarge - } - var tmp bls.Fr - reverseBitOrder(uint32(len(values)), func(i, j uint32) { - bls.CopyFr(&tmp, &values[i]) - bls.CopyFr(&values[i], &values[j]) - bls.CopyFr(&values[j], &tmp) - }) - return nil +func IsPowerOfTwo(v uint64) bool { + return v&(v-1) == 0 } - -// rearrange Fr ptr elements in reverse bit order. Supports 2**31 max element count. -// func reverseBitOrderFrPtr(values []*bls.Fr) error { -// if len(values) > (1 << 31) { -// return ErrFrListTooLarge -// } -// reverseBitOrder(uint32(len(values)), func(i, j uint32) { -// values[i], values[j] = values[j], values[i] -// }) -// return nil -// } diff --git a/encoding/fft/fft_fr_test.go b/encoding/fft/fft_fr_test.go new file mode 100644 index 0000000000..a9c60b1dd7 --- /dev/null +++ b/encoding/fft/fft_fr_test.go @@ -0,0 +1,102 @@ +// This code is sourced from the go-kzg Repository by protolambda. +// Original code: https://github.com/protolambda/go-kzg +// MIT License +// +// Copyright (c) 2020 @protolambda +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +package fft + +import ( + "testing" + + "github.com/consensys/gnark-crypto/ecc/bn254/fr" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestFFTRoundtrip(t *testing.T) { + fs := NewFFTSettings(4) + data := make([]fr.Element, fs.MaxWidth) + for i := uint64(0); i < fs.MaxWidth; i++ { + data[i].SetInt64(int64(i)) + } + coeffs, err := fs.FFT(data, false) + require.Nil(t, err) + require.NotNil(t, coeffs) + + res, err := fs.FFT(coeffs, true) + require.Nil(t, err) + require.NotNil(t, coeffs) + + for i := range res { + assert.True(t, res[i].Equal(&data[i])) + } + +} + +func TestInvFFT(t *testing.T) { + fs := NewFFTSettings(4) + data := make([]fr.Element, fs.MaxWidth) + for i := uint64(0); i < fs.MaxWidth; i++ { + data[i].SetInt64(int64(i)) + } + + res, err := fs.FFT(data, true) + require.Nil(t, err) + require.NotNil(t, res) + + expected := make([]fr.Element, 16) + _, err = expected[0].SetString("10944121435919637611123202872628637544274182200208017171849102093287904247816") + require.Nil(t, err) + _, err = expected[1].SetString("1936030771851033959223912058450265953781825736913396623629635806885115007405") + require.Nil(t, err) + _, err = expected[2].SetString("16407567355707715082381689537916387329395994555403796510305004205827931381005") + require.Nil(t, err) + _, err = expected[3].SetString("10191068092603585790326358584923261075982428954421092317052884890230353083980") + require.Nil(t, err) + _, err = expected[4].SetString("21888242871839275220042445260109153167277707414472061641729655619866599103259") + require.Nil(t, err) + _, err = expected[5].SetString("21152419124866706061239949059012548909204540700669677175965090584889269743773") + require.Nil(t, err) + _, err = expected[6].SetString("16407567355707715086789610508212631171937308527291741914242101339246350165720") + require.Nil(t, err) + _, err = expected[7].SetString("12897381804114154238953344473132041472086565426937872290416035768380869236628") + require.Nil(t, err) + _, err = expected[8].SetString("10944121435919637611123202872628637544274182200208017171849102093287904247808") + require.Nil(t, err) + _, err = expected[9].SetString("8990861067725120983293061272125233616461798973478162053282168418194939258988") + require.Nil(t, err) + _, err = expected[10].SetString("5480675516131560135456795237044643916611055873124292429456102847329458329896") + require.Nil(t, err) + _, err = expected[11].SetString("735823746972569161006456686244726179343823699746357167733113601686538751843") + require.Nil(t, err) + _, err = expected[12].SetString("2203960485148121921270656985943972701968548566709209392357") + require.Nil(t, err) + _, err = expected[13].SetString("11697174779235689431920047160334014012565935445994942026645319296345455411636") + require.Nil(t, err) + _, err = expected[14].SetString("5480675516131560139864716207340887759152369845012237833393199980747877114611") + require.Nil(t, err) + _, err = expected[15].SetString("19952212099988241263022493686807009134766538663502637720068568379690693488211") + require.Nil(t, err) + + for i := range res { + assert.True(t, res[i].Equal(&expected[i])) + } +} diff --git a/pkg/kzg/fft_g1.go b/encoding/fft/fft_g1.go similarity index 65% rename from pkg/kzg/fft_g1.go rename to encoding/fft/fft_g1.go index 2f067e7e14..28b55a07f7 100644 --- a/pkg/kzg/fft_g1.go +++ b/encoding/fft/fft_g1.go @@ -25,37 +25,47 @@ //go:build !bignum_pure && !bignum_hol256 // +build !bignum_pure,!bignum_hol256 -package kzg +package fft import ( "fmt" + "math/big" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) -func (fs *FFTSettings) simpleFTG1(vals []bls.G1Point, valsOffset uint64, valsStride uint64, rootsOfUnity []bls.Fr, rootsOfUnityStride uint64, out []bls.G1Point) { +func (fs *FFTSettings) simpleFTG1(vals []bn254.G1Affine, valsOffset uint64, valsStride uint64, rootsOfUnity []fr.Element, rootsOfUnityStride uint64, out []bn254.G1Affine) { l := uint64(len(out)) - var v bls.G1Point - var tmp bls.G1Point - var last bls.G1Point + var v bn254.G1Affine + var tmp bn254.G1Affine + var last bn254.G1Affine for i := uint64(0); i < l; i++ { jv := &vals[valsOffset] r := &rootsOfUnity[0] - bls.MulG1(&v, jv, r) - bls.CopyG1(&last, &v) + + var t big.Int + r.BigInt(&t) + v.ScalarMultiplication(jv, &t) + + last.Set(&v) for j := uint64(1); j < l; j++ { jv := &vals[valsOffset+j*valsStride] r := &rootsOfUnity[((i*j)%l)*rootsOfUnityStride] - bls.MulG1(&v, jv, r) - bls.CopyG1(&tmp, &last) - bls.AddG1(&last, &tmp, &v) + + var t big.Int + r.BigInt(&t) + v.ScalarMultiplication(jv, &t) + tmp.Set(&last) + last.Add(&tmp, &v) } - bls.CopyG1(&out[i], &last) + out[i].Set(&last) + } } -func (fs *FFTSettings) _fftG1(vals []bls.G1Point, valsOffset uint64, valsStride uint64, rootsOfUnity []bls.Fr, rootsOfUnityStride uint64, out []bls.G1Point) { +func (fs *FFTSettings) _fftG1(vals []bn254.G1Affine, valsOffset uint64, valsStride uint64, rootsOfUnity []fr.Element, rootsOfUnityStride uint64, out []bn254.G1Affine) { if len(out) <= 4 { // if the value count is small, run the unoptimized version instead. // TODO tune threshold. (can be different for G1) fs.simpleFTG1(vals, valsOffset, valsStride, rootsOfUnity, rootsOfUnityStride, out) return @@ -67,49 +77,57 @@ func (fs *FFTSettings) _fftG1(vals []bls.G1Point, valsOffset uint64, valsStride // R will be the right half of out fs._fftG1(vals, valsOffset+valsStride, valsStride<<1, rootsOfUnity, rootsOfUnityStride<<1, out[half:]) // just take even again - var yTimesRoot bls.G1Point - var x, y bls.G1Point + var yTimesRoot bn254.G1Affine + var x, y bn254.G1Affine for i := uint64(0); i < half; i++ { // temporary copies, so that writing to output doesn't conflict with input - bls.CopyG1(&x, &out[i]) - bls.CopyG1(&y, &out[i+half]) + x.Set(&out[i]) + y.Set(&out[i+half]) + root := &rootsOfUnity[i*rootsOfUnityStride] - bls.MulG1(&yTimesRoot, &y, root) - bls.AddG1(&out[i], &x, &yTimesRoot) - bls.SubG1(&out[i+half], &x, &yTimesRoot) + + yTimesRoot.ScalarMultiplication(&y, root.BigInt(new(big.Int))) + + out[i].Add(&x, &yTimesRoot) + out[i+half].Sub(&x, &yTimesRoot) + } } -func (fs *FFTSettings) FFTG1(vals []bls.G1Point, inv bool) ([]bls.G1Point, error) { +func (fs *FFTSettings) FFTG1(vals []bn254.G1Affine, inv bool) ([]bn254.G1Affine, error) { n := uint64(len(vals)) if n > fs.MaxWidth { return nil, fmt.Errorf("got %d values but only have %d roots of unity", n, fs.MaxWidth) } - if !bls.IsPowerOfTwo(n) { + + if !IsPowerOfTwo(n) { return nil, fmt.Errorf("got %d values but not a power of two", n) } // We make a copy so we can mutate it during the work. - valsCopy := make([]bls.G1Point, n) + valsCopy := make([]bn254.G1Affine, n) for i := 0; i < len(vals); i++ { // TODO: maybe optimize this away, and write back to original input array? - bls.CopyG1(&valsCopy[i], &vals[i]) + + valsCopy[i].Set(&vals[i]) } if inv { - var invLen bls.Fr - bls.AsFr(&invLen, n) - bls.InvModFr(&invLen, &invLen) + var invLen fr.Element + + invLen.SetUint64(n) + + invLen.Inverse(&invLen) + rootz := fs.ReverseRootsOfUnity[:fs.MaxWidth] stride := fs.MaxWidth / n - out := make([]bls.G1Point, n) + out := make([]bn254.G1Affine, n) fs._fftG1(valsCopy, 0, 1, rootz, stride, out) - var tmp bls.G1Point + for i := 0; i < len(out); i++ { - bls.MulG1(&tmp, &out[i], &invLen) - bls.CopyG1(&out[i], &tmp) + out[i].ScalarMultiplication(&out[i], invLen.BigInt(new(big.Int))) } return out, nil } else { - out := make([]bls.G1Point, n) + out := make([]bn254.G1Affine, n) rootz := fs.ExpandedRootsOfUnity[:fs.MaxWidth] stride := fs.MaxWidth / n // Regular FFT @@ -117,17 +135,3 @@ func (fs *FFTSettings) FFTG1(vals []bls.G1Point, inv bool) ([]bls.G1Point, error return out, nil } } - -// rearrange G1 elements in reverse bit order. Supports 2**31 max element count. -func reverseBitOrderG1(values []bls.G1Point) error { - if len(values) > (1 << 31) { - return ErrG1ListTooLarge - } - var tmp bls.G1Point - reverseBitOrder(uint32(len(values)), func(i, j uint32) { - bls.CopyG1(&tmp, &values[i]) - bls.CopyG1(&values[i], &values[j]) - bls.CopyG1(&values[j], &tmp) - }) - return nil -} diff --git a/pkg/kzg/recover_from_samples.go b/encoding/fft/recover_from_samples.go similarity index 66% rename from pkg/kzg/recover_from_samples.go rename to encoding/fft/recover_from_samples.go index 1758ccce99..bbb6b942d7 100644 --- a/pkg/kzg/recover_from_samples.go +++ b/encoding/fft/recover_from_samples.go @@ -22,50 +22,62 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -package kzg +package fft import ( "fmt" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" - //"github.com/protolambda/go-kzg/bls" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) // unshift poly, in-place. Multiplies each coeff with 1/shift_factor**i -func (fs *FFTSettings) ShiftPoly(poly []bls.Fr) { - var shiftFactor bls.Fr - bls.AsFr(&shiftFactor, 5) // primitive root of unity - var factorPower bls.Fr - bls.CopyFr(&factorPower, &bls.ONE) - var invFactor bls.Fr - bls.InvModFr(&invFactor, &shiftFactor) - var tmp bls.Fr +func (fs *FFTSettings) ShiftPoly(poly []fr.Element) { + var shiftFactor fr.Element + shiftFactor.SetInt64(int64(5)) + var factorPower fr.Element + factorPower.SetOne() + var invFactor fr.Element + invFactor.Inverse(&shiftFactor) + var tmp fr.Element for i := 0; i < len(poly); i++ { - bls.CopyFr(&tmp, &poly[i]) - bls.MulModFr(&poly[i], &tmp, &factorPower) + + tmp.Set(&poly[i]) + + + poly[i].Mul(&tmp, &factorPower) + // TODO: pre-compute all these shift scalars - bls.CopyFr(&tmp, &factorPower) - bls.MulModFr(&factorPower, &tmp, &invFactor) + + tmp.Set(&factorPower) + + + factorPower.Mul(&tmp, &invFactor) } } // unshift poly, in-place. Multiplies each coeff with shift_factor**i -func (fs *FFTSettings) UnshiftPoly(poly []bls.Fr) { - var shiftFactor bls.Fr - bls.AsFr(&shiftFactor, 5) // primitive root of unity - var factorPower bls.Fr - bls.CopyFr(&factorPower, &bls.ONE) - var tmp bls.Fr +func (fs *FFTSettings) UnshiftPoly(poly []fr.Element) { + var shiftFactor fr.Element + + shiftFactor.SetInt64(int64(5)) + var factorPower fr.Element + factorPower.SetOne() + + var tmp fr.Element for i := 0; i < len(poly); i++ { - bls.CopyFr(&tmp, &poly[i]) - bls.MulModFr(&poly[i], &tmp, &factorPower) + tmp.Set(&poly[i]) + + poly[i].Mul(&tmp, &factorPower) + // TODO: pre-compute all these shift scalars - bls.CopyFr(&tmp, &factorPower) - bls.MulModFr(&factorPower, &tmp, &shiftFactor) + + tmp.Set(&factorPower) + + factorPower.Mul(&tmp, &shiftFactor) } } -func (fs *FFTSettings) RecoverPolyFromSamples(samples []*bls.Fr, zeroPolyFn ZeroPolyFn) ([]bls.Fr, error) { +func (fs *FFTSettings) RecoverPolyFromSamples(samples []*fr.Element, zeroPolyFn ZeroPolyFn) ([]fr.Element, error) { // TODO: using a single additional temporary array, all the FFTs can run in-place. missingIndices := make([]uint64, 0, len(samples)) @@ -81,17 +93,19 @@ func (fs *FFTSettings) RecoverPolyFromSamples(samples []*bls.Fr, zeroPolyFn Zero } for i, s := range samples { - if (s == nil) != bls.EqualZero(&zeroEval[i]) { - panic("bad zero eval") + if (s == nil) != zeroEval[i].IsZero() { + return nil, fmt.Errorf("bad zero eval") } } - polyEvaluationsWithZero := make([]bls.Fr, len(samples)) + polyEvaluationsWithZero := make([]fr.Element, len(samples)) for i, s := range samples { if s == nil { - bls.CopyFr(&polyEvaluationsWithZero[i], &bls.ZERO) + + polyEvaluationsWithZero[i].SetZero() } else { - bls.MulModFr(&polyEvaluationsWithZero[i], s, &zeroEval[i]) + + polyEvaluationsWithZero[i].Mul(s, &zeroEval[i]) } } polyWithZero, err := fs.FFT(polyEvaluationsWithZero, true) @@ -116,7 +130,8 @@ func (fs *FFTSettings) RecoverPolyFromSamples(samples []*bls.Fr, zeroPolyFn Zero evalShiftedReconstructedPoly := evalShiftedPolyWithZero for i := 0; i < len(evalShiftedReconstructedPoly); i++ { - bls.DivModFr(&evalShiftedReconstructedPoly[i], &evalShiftedPolyWithZero[i], &evalShiftedZeroPoly[i]) + + evalShiftedReconstructedPoly[i].Div(&evalShiftedPolyWithZero[i], &evalShiftedZeroPoly[i]) } shiftedReconstructedPoly, err := fs.FFT(evalShiftedReconstructedPoly, true) if err != nil { @@ -129,9 +144,10 @@ func (fs *FFTSettings) RecoverPolyFromSamples(samples []*bls.Fr, zeroPolyFn Zero if err != nil { return nil, err } + for i, s := range samples { - if s != nil && !bls.EqualFr(&reconstructedData[i], s) { - return nil, fmt.Errorf("failed to reconstruct data correctly, changed value at index %d. Expected: %s, got: %s", i, bls.FrStr(s), bls.FrStr(&reconstructedData[i])) + if s != nil && !reconstructedData[i].Equal(s) { + return nil, fmt.Errorf("failed to reconstruct data correctly, changed value at index %d. Expected: %s, got: %s", i, s.String(), reconstructedData[i].String()) } } return reconstructedData, nil diff --git a/pkg/kzg/recover_from_samples_test.go b/encoding/fft/recover_from_samples_test.go similarity index 77% rename from pkg/kzg/recover_from_samples_test.go rename to encoding/fft/recover_from_samples_test.go index e53d03539b..021f48fcab 100644 --- a/pkg/kzg/recover_from_samples_test.go +++ b/encoding/fft/recover_from_samples_test.go @@ -22,14 +22,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -package kzg +package fft import ( "fmt" "math/rand" "testing" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -37,19 +37,19 @@ import ( func TestFFTSettings_RecoverPolyFromSamples_Simple(t *testing.T) { // Create some random data, with padding... fs := NewFFTSettings(2) - poly := make([]bls.Fr, fs.MaxWidth) + poly := make([]fr.Element, fs.MaxWidth) for i := uint64(0); i < fs.MaxWidth/2; i++ { - bls.AsFr(&poly[i], i) + poly[i].SetInt64(int64(i)) } for i := fs.MaxWidth / 2; i < fs.MaxWidth; i++ { - poly[i] = bls.ZERO + poly[i].SetZero() } // Get data for polynomial SLOW_INDICES data, err := fs.FFT(poly, false) require.Nil(t, err) - subset := make([]*bls.Fr, fs.MaxWidth) + subset := make([]*fr.Element, fs.MaxWidth) subset[0] = &data[0] subset[3] = &data[3] @@ -57,8 +57,8 @@ func TestFFTSettings_RecoverPolyFromSamples_Simple(t *testing.T) { require.Nil(t, err) for i := range recovered { - assert.True(t, bls.EqualFr(&recovered[i], &data[i]), - "recovery at index %d got %s but expected %s", i, bls.FrStr(&recovered[i]), bls.FrStr(&data[i])) + assert.True(t, recovered[i].Equal(&data[i]), + "recovery at index %d got %s but expected %s", i, recovered[i].String(), data[i].String()) } // And recover the original coeffs for good measure @@ -66,12 +66,12 @@ func TestFFTSettings_RecoverPolyFromSamples_Simple(t *testing.T) { require.Nil(t, err) for i := uint64(0); i < fs.MaxWidth/2; i++ { - assert.True(t, bls.EqualFr(&back[i], &poly[i]), - "coeff at index %d got %s but expected %s", i, bls.FrStr(&back[i]), bls.FrStr(&poly[i])) + assert.True(t, back[i].Equal(&poly[i]), + "coeff at index %d got %s but expected %s", i, back[i].String(), poly[i].String()) } for i := fs.MaxWidth / 2; i < fs.MaxWidth; i++ { - assert.True(t, bls.EqualZero(&back[i]), + assert.True(t, back[i].IsZero(), "expected zero padding in index %d", i) } } @@ -79,12 +79,12 @@ func TestFFTSettings_RecoverPolyFromSamples_Simple(t *testing.T) { func TestFFTSettings_RecoverPolyFromSamples(t *testing.T) { // Create some random poly, with padding so we get redundant data fs := NewFFTSettings(10) - poly := make([]bls.Fr, fs.MaxWidth) + poly := make([]fr.Element, fs.MaxWidth) for i := uint64(0); i < fs.MaxWidth/2; i++ { - bls.AsFr(&poly[i], i) + poly[i].SetInt64(int64(i)) } for i := fs.MaxWidth / 2; i < fs.MaxWidth; i++ { - poly[i] = bls.ZERO + poly[i].SetZero() } // Get coefficients for polynomial SLOW_INDICES @@ -92,8 +92,8 @@ func TestFFTSettings_RecoverPolyFromSamples(t *testing.T) { require.Nil(t, err) // Util to pick a random subnet of the values - randomSubset := func(known uint64, rngSeed uint64) []*bls.Fr { - withMissingValues := make([]*bls.Fr, fs.MaxWidth) + randomSubset := func(known uint64, rngSeed uint64) []*fr.Element { + withMissingValues := make([]*fr.Element, fs.MaxWidth) for i := range data { withMissingValues[i] = &data[i] } @@ -122,8 +122,8 @@ func TestFFTSettings_RecoverPolyFromSamples(t *testing.T) { require.Nil(t, err) for i := range recovered { - assert.True(t, bls.EqualFr(&recovered[i], &data[i]), - "recovery at index %d got %s but expected %s", i, bls.FrStr(&recovered[i]), bls.FrStr(&data[i])) + assert.True(t, recovered[i].Equal(&data[i]), + "recovery at index %d got %s but expected %s", i, recovered[i].String(), data[i].String()) } // And recover the original coeffs for good measure @@ -132,11 +132,11 @@ func TestFFTSettings_RecoverPolyFromSamples(t *testing.T) { half := uint64(len(back)) / 2 for i := uint64(0); i < half; i++ { - assert.True(t, bls.EqualFr(&back[i], &poly[i]), - "coeff at index %d got %s but expected %s", i, bls.FrStr(&back[i]), bls.FrStr(&poly[i])) + assert.True(t, back[i].Equal(&poly[i]), + "coeff at index %d got %s but expected %s", i, back[i].String(), poly[i].String()) } for i := half; i < fs.MaxWidth; i++ { - assert.True(t, bls.EqualZero(&back[i]), + assert.True(t, back[i].IsZero(), "expected zero padding in index %d", i) } }) diff --git a/pkg/kzg/zero_poly.go b/encoding/fft/zero_poly.go similarity index 81% rename from pkg/kzg/zero_poly.go rename to encoding/fft/zero_poly.go index 0a8f4e8c66..9394e240f4 100644 --- a/pkg/kzg/zero_poly.go +++ b/encoding/fft/zero_poly.go @@ -29,50 +29,62 @@ // - simplified merges // - no heap allocations during reduction -package kzg +package fft import ( "log" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" - //"github.com/protolambda/go-kzg/bls" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) -type ZeroPolyFn func(missingIndices []uint64, length uint64) ([]bls.Fr, []bls.Fr, error) +type ZeroPolyFn func(missingIndices []uint64, length uint64) ([]fr.Element, []fr.Element, error) -func (fs *FFTSettings) makeZeroPolyMulLeaf(dst []bls.Fr, indices []uint64, domainStride uint64) error { +func (fs *FFTSettings) makeZeroPolyMulLeaf(dst []fr.Element, indices []uint64, domainStride uint64) error { if len(dst) < len(indices)+1 { log.Printf("expected bigger destination length: %d, got: %d", len(indices)+1, len(dst)) return ErrInvalidDestinationLength } // zero out the unused slots for i := len(indices) + 1; i < len(dst); i++ { - bls.CopyFr(&dst[i], &bls.ZERO) + dst[i].SetZero() + } - bls.CopyFr(&dst[len(indices)], &bls.ONE) - var negDi bls.Fr + + dst[len(indices)].SetOne() + var negDi fr.Element + + var frZero fr.Element + frZero.SetZero() + for i, v := range indices { - bls.SubModFr(&negDi, &bls.ZERO, &fs.ExpandedRootsOfUnity[v*domainStride]) - bls.CopyFr(&dst[i], &negDi) + + negDi.Sub(&frZero, &fs.ExpandedRootsOfUnity[v*domainStride]) + + dst[i].Set(&negDi) if i > 0 { - bls.AddModFr(&dst[i], &dst[i], &dst[i-1]) + + dst[i].Add(&dst[i], &dst[i-1]) for j := i - 1; j > 0; j-- { - bls.MulModFr(&dst[j], &dst[j], &negDi) - bls.AddModFr(&dst[j], &dst[j], &dst[j-1]) + dst[j].Mul(&dst[j], &negDi) + + dst[j].Add(&dst[j], &dst[j-1]) } - bls.MulModFr(&dst[0], &dst[0], &negDi) + + dst[0].Mul(&dst[0], &negDi) } } return nil } // Copy all of the values of poly into out, and fill the remainder of out with zeroes. -func padPoly(out []bls.Fr, poly []bls.Fr) { +func padPoly(out []fr.Element, poly []fr.Element) { for i := 0; i < len(poly); i++ { - bls.CopyFr(&out[i], &poly[i]) + + out[i].Set(&poly[i]) } for i := len(poly); i < len(out); i++ { - bls.CopyFr(&out[i], &bls.ZERO) + + out[i].SetZero() } } @@ -83,9 +95,9 @@ func padPoly(out []bls.Fr, poly []bls.Fr) { // The scratch space must be at least 3 times the output space. // The output must have a power of 2 length. // The input polynomials must not be empty, and sum to no larger than the output. -func (fs *FFTSettings) reduceLeaves(scratch []bls.Fr, dst []bls.Fr, ps [][]bls.Fr) ([]bls.Fr, error) { +func (fs *FFTSettings) reduceLeaves(scratch []fr.Element, dst []fr.Element, ps [][]fr.Element) ([]fr.Element, error) { n := uint64(len(dst)) - if !bls.IsPowerOfTwo(n) { + if !IsPowerOfTwo(n) { log.Println("destination must be a power of two") return nil, ErrDestNotPowerOfTwo } @@ -124,13 +136,15 @@ func (fs *FFTSettings) reduceLeaves(scratch []bls.Fr, dst []bls.Fr, ps [][]bls.F for i := uint64(0); i < last; i++ { p := ps[i] for j := 0; j < len(p); j++ { - bls.CopyFr(&pPadded[j], &p[j]) + + pPadded[j].Set(&p[j]) } if err := fs.InplaceFFT(pPadded, pEval, false); err != nil { return nil, err } for j := uint64(0); j < n; j++ { - bls.MulModFr(&mulEvalPs[j], &mulEvalPs[j], &pEval[j]) + mulEvalPs[j].Mul(&mulEvalPs[j], &pEval[j]) + } } if err := fs.InplaceFFT(mulEvalPs, dst, true); err != nil { @@ -146,15 +160,15 @@ func (fs *FFTSettings) reduceLeaves(scratch []bls.Fr, dst []bls.Fr, ps [][]bls.F // of direct multiplication (makeZeroPolyMulLeaf) and iterated multiplication via convolution (reduceLeaves) // // Also calculates the FFT (the "evaluation polynomial"). -func (fs *FFTSettings) ZeroPolyViaMultiplication(missingIndices []uint64, length uint64) ([]bls.Fr, []bls.Fr, error) { +func (fs *FFTSettings) ZeroPolyViaMultiplication(missingIndices []uint64, length uint64) ([]fr.Element, []fr.Element, error) { if len(missingIndices) == 0 { - return make([]bls.Fr, length), make([]bls.Fr, length), nil + return make([]fr.Element, length), make([]fr.Element, length), nil } if length > fs.MaxWidth { log.Println("domain too small for requested length") return nil, nil, ErrDomainTooSmall } - if !bls.IsPowerOfTwo(length) { + if !IsPowerOfTwo(length) { log.Println("length not a power of two") return nil, nil, ErrLengthNotPowerOfTwo } @@ -165,7 +179,7 @@ func (fs *FFTSettings) ZeroPolyViaMultiplication(missingIndices []uint64, length // If the work is as small as a single leaf, don't bother with tree reduction if uint64(len(missingIndices)) <= perLeaf { - zeroPoly := make([]bls.Fr, len(missingIndices)+1, length) + zeroPoly := make([]fr.Element, len(missingIndices)+1, length) err := fs.makeZeroPolyMulLeaf(zeroPoly, missingIndices, domainStride) if err != nil { return nil, nil, err @@ -184,13 +198,13 @@ func (fs *FFTSettings) ZeroPolyViaMultiplication(missingIndices []uint64, length // The assumption here is that if the output is a power of two length, matching the sum of child leaf lengths, // then the space can be reused. - out := make([]bls.Fr, n) + out := make([]fr.Element, n) // Build the leaves. // Just the headers, a leaf re-uses the output space. // Combining leaves can be done mostly in-place, using a scratchpad. - leaves := make([][]bls.Fr, leafCount) + leaves := make([][]fr.Element, leafCount) offset := uint64(0) outOffset := uint64(0) @@ -213,7 +227,7 @@ func (fs *FFTSettings) ZeroPolyViaMultiplication(missingIndices []uint64, length // must be a power of 2 reductionFactor := uint64(4) - scratch := make([]bls.Fr, n*3) + scratch := make([]fr.Element, n*3) // from bottom to top, start reducing leaves. for len(leaves) > 1 { @@ -248,7 +262,7 @@ func (fs *FFTSettings) ZeroPolyViaMultiplication(missingIndices []uint64, length } zeroPoly := leaves[0] if zl := uint64(len(zeroPoly)); zl < length { - zeroPoly = append(zeroPoly, make([]bls.Fr, length-zl)...) + zeroPoly = append(zeroPoly, make([]fr.Element, length-zl)...) } else if zl > length { log.Println("expected output smaller or equal to input length") return nil, nil, ErrZeroPolyTooLarge @@ -261,3 +275,29 @@ func (fs *FFTSettings) ZeroPolyViaMultiplication(missingIndices []uint64, length return zeroEval, zeroPoly, nil } + +func EvalPolyAt(dst *fr.Element, coeffs []fr.Element, x *fr.Element) { + if len(coeffs) == 0 { + + dst.SetZero() + return + } + if x.IsZero() { + + dst.Set(&coeffs[0]) + return + } + // Horner's method: work backwards, avoid doing more than N multiplications + // https://en.wikipedia.org/wiki/Horner%27s_method + var last fr.Element + + last.Set(&coeffs[len(coeffs)-1]) + var tmp fr.Element + for i := len(coeffs) - 2; i >= 0; i-- { + tmp.Mul(&last, x) + + last.Add(&tmp, &coeffs[i]) + } + + dst.Set(&last) +} diff --git a/pkg/kzg/zero_poly_test.go b/encoding/fft/zero_poly_test.go similarity index 82% rename from pkg/kzg/zero_poly_test.go rename to encoding/fft/zero_poly_test.go index 29ca14f6b6..04dd8dda28 100644 --- a/pkg/kzg/zero_poly_test.go +++ b/encoding/fft/zero_poly_test.go @@ -22,32 +22,33 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -package kzg +package fft import ( "fmt" "math/rand" "testing" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" + "github.com/stretchr/testify/assert" ) func TestFFTSettings_reduceLeaves(t *testing.T) { fs := NewFFTSettings(4) - var fromTreeReduction []bls.Fr + var fromTreeReduction []fr.Element { // prepare some leaves - leaves := [][]bls.Fr{make([]bls.Fr, 3), make([]bls.Fr, 3), make([]bls.Fr, 3), make([]bls.Fr, 3)} + leaves := [][]fr.Element{make([]fr.Element, 3), make([]fr.Element, 3), make([]fr.Element, 3), make([]fr.Element, 3)} leafIndices := [][]uint64{{1, 3}, {7, 8}, {9, 10}, {12, 13}} for i := 0; i < 4; i++ { err := fs.makeZeroPolyMulLeaf(leaves[i], leafIndices[i], 1) assert.Nil(t, err) } - dst := make([]bls.Fr, 16) - scratch := make([]bls.Fr, 16*3) + dst := make([]fr.Element, 16) + scratch := make([]fr.Element, 16*3) _, err := fs.reduceLeaves(scratch, dst, leaves) if err != nil { assert.Nil(t, err) @@ -55,9 +56,9 @@ func TestFFTSettings_reduceLeaves(t *testing.T) { fromTreeReduction = dst[:2*4+1] } - var fromDirect []bls.Fr + var fromDirect []fr.Element { - dst := make([]bls.Fr, 9) + dst := make([]fr.Element, 9) indices := []uint64{1, 3, 7, 8, 9, 10, 12, 13} err := fs.makeZeroPolyMulLeaf(dst, indices, 1) if err != nil { @@ -69,11 +70,11 @@ func TestFFTSettings_reduceLeaves(t *testing.T) { for i := 0; i < len(fromDirect); i++ { a, b := &fromDirect[i], &fromTreeReduction[i] - if !bls.EqualFr(a, b) { - t.Errorf("zero poly coeff %d is different. direct: %s, tree: %s", i, bls.FrStr(a), bls.FrStr(b)) + if !a.Equal(b) { + t.Errorf("zero poly coeff %d is different. direct: %s, tree: %s", i, a.String(), b.String()) } - assert.True(t, bls.EqualFr(a, b), - "zero poly coeff %d is different. direct: %s, tree: %s", i, bls.FrStr(a), bls.FrStr(b)) + assert.True(t, a.Equal(b), + "zero poly coeff %d is different. direct: %s, tree: %s", i, a.String(), b.String()) } } @@ -113,7 +114,7 @@ func testReduceLeaves(scale uint8, missingRatio float64, seed int64, t *testing. // build the leaves pointsPerLeaf := uint64(63) leafCount := (missingCount + pointsPerLeaf - 1) / pointsPerLeaf - leaves := make([][]bls.Fr, leafCount) + leaves := make([][]fr.Element, leafCount) for i := uint64(0); i < leafCount; i++ { start := i * pointsPerLeaf end := start + pointsPerLeaf @@ -121,7 +122,7 @@ func testReduceLeaves(scale uint8, missingRatio float64, seed int64, t *testing. end = missingCount } leafSize := end - start - leaf := make([]bls.Fr, leafSize+1) + leaf := make([]fr.Element, leafSize+1) indices := make([]uint64, leafSize) for j := uint64(0); j < leafSize; j++ { indices[j] = missing[i*pointsPerLeaf+j] @@ -131,10 +132,10 @@ func testReduceLeaves(scale uint8, missingRatio float64, seed int64, t *testing. leaves[i] = leaf } - var fromTreeReduction []bls.Fr + var fromTreeReduction []fr.Element { - dst := make([]bls.Fr, pointCount) - scratch := make([]bls.Fr, pointCount*3) + dst := make([]fr.Element, pointCount) + scratch := make([]fr.Element, pointCount*3) _, err := fs.reduceLeaves(scratch, dst, leaves) if err != nil { assert.Nil(t, err) @@ -142,9 +143,9 @@ func testReduceLeaves(scale uint8, missingRatio float64, seed int64, t *testing. fromTreeReduction = dst[:missingCount+1] } - var fromDirect []bls.Fr + var fromDirect []fr.Element { - dst := make([]bls.Fr, missingCount+1) + dst := make([]fr.Element, missingCount+1) err := fs.makeZeroPolyMulLeaf(dst, missing, fs.MaxWidth/pointCount) assert.Nil(t, err) fromDirect = dst @@ -153,8 +154,8 @@ func testReduceLeaves(scale uint8, missingRatio float64, seed int64, t *testing. for i := 0; i < len(fromDirect); i++ { a, b := &fromDirect[i], &fromTreeReduction[i] - assert.True(t, bls.EqualFr(a, b), - "zero poly coeff %d is different. direct: %s, tree: %s", i, bls.FrStr(a), bls.FrStr(b)) + assert.True(t, a.Equal(b), + "zero poly coeff %d is different. direct: %s, tree: %s", i, a.String(), b.String()) } } @@ -178,7 +179,7 @@ func testReduceLeaves(scale uint8, missingRatio float64, seed int64, t *testing. // zeroEval, zeroPoly, _ := fs.ZeroPolyViaMultiplication(missingIndices, uint64(len(exists))) // // produced from python implementation, check it's exactly correct. -// expectedEval := []bls.Fr{ +// expectedEval := []fr.Element{ // bls.ToFr("40868503138626303263713448452028063093974861640573380501185290423282553381059"), // bls.ToFr("0"), // bls.ToFr("0"), @@ -200,10 +201,10 @@ func testReduceLeaves(scale uint8, missingRatio float64, seed int64, t *testing. // for i := range zeroEval { // fmt.Println(expectedEval[i]) // assert.True(t, bls.EqualFr(&expectedEval[i], &zeroEval[i]), -// "at eval %d, expected: %s, got: %s", i, bls.FrStr(&expectedEval[i]), bls.FrStr(&zeroEval[i])) +// "at eval %d, expected: %s, got: %s", i, fr.ElementStr(&expectedEval[i]), fr.ElementStr(&zeroEval[i])) // } -// expectedPoly := []bls.Fr{ +// expectedPoly := []fr.Element{ // bls.ToFr("37647706414300369857238608619982937390838535937985112215973498325246987289395"), // bls.ToFr("2249310547870908874251949653552971443359134481191188461034956129255788965773"), // bls.ToFr("14214218681578879810156974734536988864583938194339599855352132142401756507144"), @@ -224,7 +225,7 @@ func testReduceLeaves(scale uint8, missingRatio float64, seed int64, t *testing. // for i := range zeroPoly { // assert.True(t, bls.EqualFr(&expectedPoly[i], &zeroPoly[i]), -// "at poly %d, expected: %s, got: %s", i, bls.FrStr(&expectedPoly[i]), bls.FrStr(&zeroPoly[i])) +// "at poly %d, expected: %s, got: %s", i, fr.ElementStr(&expectedPoly[i]), fr.ElementStr(&zeroPoly[i])) // } // } @@ -249,12 +250,13 @@ func testZeroPoly(t *testing.T, scale uint8, seed int64) { for i, v := range exists { if !v { - var at bls.Fr - bls.CopyFr(&at, &fs.ExpandedRootsOfUnity[i]) - var out bls.Fr - bls.EvalPolyAt(&out, zeroPoly, &at) - if !bls.EqualZero(&out) { - t.Errorf("expected zero at %d, but got: %s", i, bls.FrStr(&out)) + var at fr.Element + //xbls.CopyFr(&at, &fs.ExpandedRootsOfUnity[i]) + at.Set(&fs.ExpandedRootsOfUnity[i]) + var out fr.Element + EvalPolyAt(&out, zeroPoly, &at) + if !out.IsZero() { + t.Errorf("expected zero at %d, but got: %s", i, out.String()) } } } @@ -264,13 +266,13 @@ func testZeroPoly(t *testing.T, scale uint8, seed int64) { t.Fatal(err) } for i := 0; i < len(zeroPoly); i++ { - if !bls.EqualFr(&p[i], &zeroPoly[i]) { - t.Errorf("fft not correct, i: %v, a: %s, b: %s", i, bls.FrStr(&p[i]), bls.FrStr(&zeroPoly[i])) + if !p[i].Equal(&zeroPoly[i]) { + t.Errorf("fft not correct, i: %v, a: %s, b: %s", i, p[i].String(), zeroPoly[i].String()) } } for i := len(zeroPoly); i < len(p); i++ { - if !bls.EqualZero(&p[i]) { - t.Errorf("fft not correct, i: %v, a: %s, b: 0", i, bls.FrStr(&p[i])) + if !p[i].IsZero() { + t.Errorf("fft not correct, i: %v, a: %s, b: 0", i, p[i].String()) } } } diff --git a/encoding/kzgrs/cli.go b/encoding/kzg/cli.go similarity index 99% rename from encoding/kzgrs/cli.go rename to encoding/kzg/cli.go index 3a87e5247f..a893fcfcc2 100644 --- a/encoding/kzgrs/cli.go +++ b/encoding/kzg/cli.go @@ -1,4 +1,4 @@ -package kzgrs +package kzg import ( "runtime" diff --git a/encoding/kzg/constants.go b/encoding/kzg/constants.go new file mode 100644 index 0000000000..81b2db31a4 --- /dev/null +++ b/encoding/kzg/constants.go @@ -0,0 +1,40 @@ +package kzg + +import ( + "github.com/consensys/gnark-crypto/ecc/bn254" +) + +func init() { + initG1G2() +} + +var GenG1 bn254.G1Affine +var GenG2 bn254.G2Affine + +var ZeroG1 bn254.G1Affine +var ZeroG2 bn254.G2Affine + +func initG1G2() { + + _, _, genG1, genG2 := bn254.Generators() + + GenG1 = *(*bn254.G1Affine)(&genG1) + GenG2 = *(*bn254.G2Affine)(&genG2) + + var g1Jac bn254.G1Jac + g1Jac.X.SetZero() + g1Jac.Y.SetOne() + g1Jac.Z.SetZero() + + var g1Aff bn254.G1Affine + g1Aff.FromJacobian(&g1Jac) + ZeroG1 = *(*bn254.G1Affine)(&g1Aff) + + var g2Jac bn254.G2Jac + g2Jac.X.SetZero() + g2Jac.Y.SetOne() + g2Jac.Z.SetZero() + var g2Aff bn254.G2Affine + g2Aff.FromJacobian(&g2Jac) + ZeroG2 = *(*bn254.G2Affine)(&g2Aff) +} diff --git a/pkg/kzg/poly.go b/encoding/kzg/kzg.go similarity index 58% rename from pkg/kzg/poly.go rename to encoding/kzg/kzg.go index f52f155403..f35d268056 100644 --- a/pkg/kzg/poly.go +++ b/encoding/kzg/kzg.go @@ -22,45 +22,46 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +//go:build !bignum_pure && !bignum_hol256 +// +build !bignum_pure,!bignum_hol256 + package kzg import ( - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/Layr-Labs/eigenda/encoding/fft" + "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) -// invert the divisor, then multiply -func polyFactorDiv(dst *bls.Fr, a *bls.Fr, b *bls.Fr) { - // TODO: use divmod instead. - var tmp bls.Fr - bls.InvModFr(&tmp, b) - bls.MulModFr(dst, &tmp, a) +type KZGSettings struct { + *fft.FFTSettings + + Srs *SRS + // setup values } -// Long polynomial division for two polynomials in coefficient form -func PolyLongDiv(dividend []bls.Fr, divisor []bls.Fr) []bls.Fr { - a := make([]bls.Fr, len(dividend)) - for i := 0; i < len(a); i++ { - bls.CopyFr(&a[i], ÷nd[i]) - } - aPos := len(a) - 1 - bPos := len(divisor) - 1 - diff := aPos - bPos - out := make([]bls.Fr, diff+1) - for diff >= 0 { - quot := &out[diff] - polyFactorDiv(quot, &a[aPos], &divisor[bPos]) - var tmp, tmp2 bls.Fr - for i := bPos; i >= 0; i-- { - // In steps: a[diff + i] -= b[i] * quot - // tmp = b[i] * quot - bls.MulModFr(&tmp, quot, &divisor[i]) - // tmp2 = a[diff + i] - tmp - bls.SubModFr(&tmp2, &a[diff+i], &tmp) - // a[diff + i] = tmp2 - bls.CopyFr(&a[diff+i], &tmp2) - } - aPos -= 1 - diff -= 1 +func NewKZGSettings(fs *fft.FFTSettings, srs *SRS) (*KZGSettings, error) { + + ks := &KZGSettings{ + FFTSettings: fs, + Srs: srs, } - return out + + return ks, nil +} + +// KZG commitment to polynomial in coefficient form +func (ks *KZGSettings) CommitToPoly(coeffs []fr.Element) (*bn254.G1Affine, error) { + var commit bn254.G1Affine + _, err := commit.MultiExp(ks.Srs.G1[:len(coeffs)], coeffs, ecc.MultiExpConfig{}) + return &commit, err +} + +func HashToSingleField(dst *fr.Element, msg []byte) error { + DST := []byte("-") + randomFr, err := fr.Hash(msg, DST, 1) + randomFrBytes := (randomFr[0]).Bytes() + dst.SetBytes(randomFrBytes[:]) + return err } diff --git a/encoding/kzgrs/kzgrs.go b/encoding/kzg/kzgrs.go similarity index 96% rename from encoding/kzgrs/kzgrs.go rename to encoding/kzg/kzgrs.go index 8d8905887c..183323af52 100644 --- a/encoding/kzgrs/kzgrs.go +++ b/encoding/kzg/kzgrs.go @@ -1,4 +1,4 @@ -package kzgrs +package kzg type KzgConfig struct { G1Path string diff --git a/encoding/kzgrs/pointsIO.go b/encoding/kzg/pointsIO.go similarity index 86% rename from encoding/kzgrs/pointsIO.go rename to encoding/kzg/pointsIO.go index a74e804972..0431c49ce8 100644 --- a/encoding/kzgrs/pointsIO.go +++ b/encoding/kzg/pointsIO.go @@ -1,4 +1,4 @@ -package kzgrs +package kzg import ( "bufio" @@ -9,7 +9,7 @@ import ( "os" "time" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254" ) const ( @@ -38,34 +38,34 @@ func ReadDesiredBytes(reader *bufio.Reader, numBytesToRead uint64) ([]byte, erro } // Read the n-th G1 point from SRS. -func ReadG1Point(n uint64, g *KzgConfig) (bls.G1Point, error) { +func ReadG1Point(n uint64, g *KzgConfig) (bn254.G1Affine, error) { if n > g.SRSOrder { - return bls.G1Point{}, fmt.Errorf("requested power %v is larger than SRSOrder %v", n, g.SRSOrder) + return bn254.G1Affine{}, fmt.Errorf("requested power %v is larger than SRSOrder %v", n, g.SRSOrder) } g1point, err := ReadG1PointSection(g.G1Path, n, n+1, 1) if err != nil { - return bls.G1Point{}, err + return bn254.G1Affine{}, err } return g1point[0], nil } // Read the n-th G2 point from SRS. -func ReadG2Point(n uint64, g *KzgConfig) (bls.G2Point, error) { +func ReadG2Point(n uint64, g *KzgConfig) (bn254.G2Affine, error) { if n > g.SRSOrder { - return bls.G2Point{}, fmt.Errorf("requested power %v is larger than SRSOrder %v", n, g.SRSOrder) + return bn254.G2Affine{}, fmt.Errorf("requested power %v is larger than SRSOrder %v", n, g.SRSOrder) } g2point, err := ReadG2PointSection(g.G2Path, n, n+1, 1) if err != nil { - return bls.G2Point{}, err + return bn254.G2Affine{}, err } return g2point[0], nil } // Read g2 points from power of 2 file -func ReadG2PointOnPowerOf2(exponent uint64, g *KzgConfig) (bls.G2Point, error) { +func ReadG2PointOnPowerOf2(exponent uint64, g *KzgConfig) (bn254.G2Affine, error) { // the powerOf2 file, only [tau^exp] are stored. // exponent 0, 1, 2, , .. @@ -81,22 +81,22 @@ func ReadG2PointOnPowerOf2(exponent uint64, g *KzgConfig) (bls.G2Point, error) { actualPowerOfTau := g.SRSOrder - 1 largestPowerofSRS := uint64(math.Log2(float64(actualPowerOfTau))) if exponent > largestPowerofSRS { - return bls.G2Point{}, fmt.Errorf("requested power %v is larger than largest power of SRS %v", + return bn254.G2Affine{}, fmt.Errorf("requested power %v is larger than largest power of SRS %v", uint64(math.Pow(2, float64(exponent))), largestPowerofSRS) } if len(g.G2PowerOf2Path) == 0 { - return bls.G2Point{}, fmt.Errorf("G2PathPowerOf2 path is empty") + return bn254.G2Affine{}, fmt.Errorf("G2PathPowerOf2 path is empty") } g2point, err := ReadG2PointSection(g.G2PowerOf2Path, exponent, exponent+1, 1) if err != nil { - return bls.G2Point{}, err + return bn254.G2Affine{}, err } return g2point[0], nil } -func ReadG1Points(filepath string, n uint64, numWorker uint64) ([]bls.G1Point, error) { +func ReadG1Points(filepath string, n uint64, numWorker uint64) ([]bn254.G1Affine, error) { g1f, err := os.Open(filepath) if err != nil { log.Println("Cannot ReadG1Points", filepath, err) @@ -127,7 +127,7 @@ func ReadG1Points(filepath string, n uint64, numWorker uint64) ([]bls.G1Point, e log.Printf(" Reading G1 points (%v bytes) takes %v\n", (n * G1PointBytes), elapsed) startTimer = time.Now() - s1Outs := make([]bls.G1Point, n) + s1Outs := make([]bn254.G1Affine, n) start := uint64(0) end := uint64(0) @@ -163,7 +163,7 @@ func ReadG1Points(filepath string, n uint64, numWorker uint64) ([]bls.G1Point, e } // from is inclusive, to is exclusive -func ReadG1PointSection(filepath string, from, to uint64, numWorker uint64) ([]bls.G1Point, error) { +func ReadG1PointSection(filepath string, from, to uint64, numWorker uint64) ([]bn254.G1Affine, error) { if to <= from { return nil, fmt.Errorf("The range to read is invalid, from: %v, to: %v", from, to) } @@ -197,7 +197,7 @@ func ReadG1PointSection(filepath string, from, to uint64, numWorker uint64) ([]b return nil, err } - s1Outs := make([]bls.G1Point, n) + s1Outs := make([]bn254.G1Affine, n) start := uint64(0) end := uint64(0) @@ -229,7 +229,7 @@ func ReadG1PointSection(filepath string, from, to uint64, numWorker uint64) ([]b func readG1Worker( buf []byte, - outs []bls.G1Point, + outs []bn254.G1Affine, start uint64, // in element, not in byte end uint64, step uint64, @@ -237,10 +237,10 @@ func readG1Worker( ) { for i := start; i < end; i++ { g1 := buf[i*step : (i+1)*step] - err := outs[i].UnmarshalText(g1[:]) + _, err := outs[i].SetBytes(g1[:]) if err != nil { results <- err - panic(err) + return } } results <- nil @@ -248,7 +248,7 @@ func readG1Worker( func readG2Worker( buf []byte, - outs []bls.G2Point, + outs []bn254.G2Affine, start uint64, // in element, not in byte end uint64, step uint64, @@ -256,17 +256,17 @@ func readG2Worker( ) { for i := start; i < end; i++ { g1 := buf[i*step : (i+1)*step] - err := outs[i].UnmarshalText(g1[:]) + _, err := outs[i].SetBytes(g1[:]) if err != nil { results <- err log.Println("Unmarshalling error:", err) - panic(err) + return } } results <- nil } -func ReadG2Points(filepath string, n uint64, numWorker uint64) ([]bls.G2Point, error) { +func ReadG2Points(filepath string, n uint64, numWorker uint64) ([]bn254.G2Affine, error) { g1f, err := os.Open(filepath) if err != nil { log.Println("Cannot ReadG2Points", filepath) @@ -299,7 +299,7 @@ func ReadG2Points(filepath string, n uint64, numWorker uint64) ([]bls.G2Point, e startTimer = time.Now() - s2Outs := make([]bls.G2Point, n) + s2Outs := make([]bn254.G2Affine, n) results := make(chan error, numWorker) @@ -333,7 +333,7 @@ func ReadG2Points(filepath string, n uint64, numWorker uint64) ([]bls.G2Point, e } // from is inclusive, to is exclusive -func ReadG2PointSection(filepath string, from, to uint64, numWorker uint64) ([]bls.G2Point, error) { +func ReadG2PointSection(filepath string, from, to uint64, numWorker uint64) ([]bn254.G2Affine, error) { if to <= from { return nil, fmt.Errorf("The range to read is invalid, from: %v, to: %v", from, to) } @@ -367,7 +367,7 @@ func ReadG2PointSection(filepath string, from, to uint64, numWorker uint64) ([]b return nil, err } - s2Outs := make([]bls.G2Point, n) + s2Outs := make([]bn254.G2Affine, n) results := make(chan error, numWorker) diff --git a/encoding/kzgrs/prover/decode.go b/encoding/kzg/prover/decode.go similarity index 100% rename from encoding/kzgrs/prover/decode.go rename to encoding/kzg/prover/decode.go diff --git a/encoding/kzgrs/prover/decode_test.go b/encoding/kzg/prover/decode_test.go similarity index 93% rename from encoding/kzgrs/prover/decode_test.go rename to encoding/kzg/prover/decode_test.go index 189145c79b..cc6384c3a3 100644 --- a/encoding/kzgrs/prover/decode_test.go +++ b/encoding/kzg/prover/decode_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/encoding/kzgrs/prover/parametrized_prover.go b/encoding/kzg/prover/parametrized_prover.go similarity index 65% rename from encoding/kzgrs/prover/parametrized_prover.go rename to encoding/kzg/prover/parametrized_prover.go index 10086aedd7..bc35603e56 100644 --- a/encoding/kzgrs/prover/parametrized_prover.go +++ b/encoding/kzg/prover/parametrized_prover.go @@ -4,43 +4,44 @@ import ( "fmt" "log" "math" - "sync" "time" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" + + "github.com/Layr-Labs/eigenda/encoding/fft" + "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/Layr-Labs/eigenda/encoding/rs" "github.com/Layr-Labs/eigenda/encoding/utils/toeplitz" - kzg "github.com/Layr-Labs/eigenda/pkg/kzg" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) type ParametrizedProver struct { *rs.Encoder - *kzgrs.KzgConfig + *kzg.KzgConfig Srs *kzg.SRS - G2Trailing []bls.G2Point + G2Trailing []bn254.G2Affine - Fs *kzg.FFTSettings + Fs *fft.FFTSettings Ks *kzg.KZGSettings - SFs *kzg.FFTSettings // fft used for submatrix product helper - FFTPoints [][]bls.G1Point - FFTPointsT [][]bls.G1Point // transpose of FFTPoints + SFs *fft.FFTSettings // fft used for submatrix product helper + FFTPointsT [][]bn254.G1Affine // transpose of FFTPoints } type WorkerResult struct { - points []bls.G1Point + points []bn254.G1Affine err error } // just a wrapper to take bytes not Fr Element -func (g *ParametrizedProver) EncodeBytes(inputBytes []byte) (*bls.G1Point, *bls.G2Point, *bls.G2Point, []encoding.Frame, []uint32, error) { +func (g *ParametrizedProver) EncodeBytes(inputBytes []byte) (*bn254.G1Affine, *bn254.G2Affine, *bn254.G2Affine, []encoding.Frame, []uint32, error) { inputFr := rs.ToFrArray(inputBytes) return g.Encode(inputFr) } -func (g *ParametrizedProver) Encode(inputFr []bls.Fr) (*bls.G1Point, *bls.G2Point, *bls.G2Point, []encoding.Frame, []uint32, error) { +func (g *ParametrizedProver) Encode(inputFr []fr.Element) (*bn254.G1Affine, *bn254.G2Affine, *bn254.G2Affine, []encoding.Frame, []uint32, error) { startTime := time.Now() poly, frames, indices, err := g.Encoder.Encode(inputFr) @@ -53,8 +54,18 @@ func (g *ParametrizedProver) Encode(inputFr []bls.Fr) (*bls.G1Point, *bls.G2Poin } // compute commit for the full poly - commit := g.Commit(poly.Coeffs) - lowDegreeCommitment := bls.LinCombG2(g.Srs.G2[:len(poly.Coeffs)], poly.Coeffs) + commit, err := g.Commit(poly.Coeffs) + if err != nil { + return nil, nil, nil, nil, nil, err + } + + config := ecc.MultiExpConfig{} + + var lowDegreeCommitment bn254.G2Affine + _, err = lowDegreeCommitment.MultiExp(g.Srs.G2[:len(poly.Coeffs)], poly.Coeffs, config) + if err != nil { + return nil, nil, nil, nil, nil, err + } intermediate := time.Now() @@ -72,16 +83,11 @@ func (g *ParametrizedProver) Encode(inputFr []bls.Fr) (*bls.G1Point, *bls.G2Poin shiftedSecret := g.G2Trailing[g.KzgConfig.SRSNumberToLoad-polyDegreePlus1:] //The proof of low degree is commitment of the polynomial shifted to the largest srs degree - lowDegreeProof := bls.LinCombG2(shiftedSecret, poly.Coeffs[:polyDegreePlus1]) - - //fmt.Println("kzgFFT lowDegreeProof", lowDegreeProof, "poly len ", len(fullCoeffsPoly), "order", len(g.Ks.SecretG2) ) - //ok := VerifyLowDegreeProof(&commit, lowDegreeProof, polyDegreePlus1-1, g.SRSOrder, g.Srs.G2) - //if !ok { - // log.Printf("Kzg FFT Cannot Verify low degree proof %v", lowDegreeProof) - // return nil, nil, nil, nil, errors.New("cannot verify low degree proof") - // } else { - // log.Printf("Kzg FFT Verify low degree proof PPPASSS %v", lowDegreeProof) - // } + var lowDegreeProof bn254.G2Affine + _, err = lowDegreeProof.MultiExp(shiftedSecret, poly.Coeffs, config) + if err != nil { + return nil, nil, nil, nil, nil, err + } if g.Verbose { log.Printf(" Generating Low Degree Proof takes %v\n", time.Since(intermediate)) @@ -89,7 +95,7 @@ func (g *ParametrizedProver) Encode(inputFr []bls.Fr) (*bls.G1Point, *bls.G2Poin } // compute proofs - paddedCoeffs := make([]bls.Fr, g.NumEvaluations()) + paddedCoeffs := make([]fr.Element, g.NumEvaluations()) copy(paddedCoeffs, poly.Coeffs) proofs, err := g.ProveAllCosetThreads(paddedCoeffs, g.NumChunks, g.ChunkLength, g.NumWorker) @@ -112,29 +118,29 @@ func (g *ParametrizedProver) Encode(inputFr []bls.Fr) (*bls.G1Point, *bls.G2Poin if g.Verbose { log.Printf("Total encoding took %v\n", time.Since(startTime)) } - return &commit, lowDegreeCommitment, lowDegreeProof, kzgFrames, indices, nil + return &commit, &lowDegreeCommitment, &lowDegreeProof, kzgFrames, indices, nil } -func (g *ParametrizedProver) Commit(polyFr []bls.Fr) bls.G1Point { - commit := g.Ks.CommitToPoly(polyFr) - return *commit +func (g *ParametrizedProver) Commit(polyFr []fr.Element) (bn254.G1Affine, error) { + commit, err := g.Ks.CommitToPoly(polyFr) + return *commit, err } -func (p *ParametrizedProver) ProveAllCosetThreads(polyFr []bls.Fr, numChunks, chunkLen, numWorker uint64) ([]bls.G1Point, error) { +func (p *ParametrizedProver) ProveAllCosetThreads(polyFr []fr.Element, numChunks, chunkLen, numWorker uint64) ([]bn254.G1Affine, error) { begin := time.Now() // Robert: Standardizing this to use the same math used in precomputeSRS dimE := numChunks l := chunkLen - sumVec := make([]bls.G1Point, dimE*2) + sumVec := make([]bn254.G1Affine, dimE*2) jobChan := make(chan uint64, numWorker) results := make(chan WorkerResult, numWorker) // create storage for intermediate fft outputs - coeffStore := make([][]bls.Fr, dimE*2) + coeffStore := make([][]fr.Element, dimE*2) for i := range coeffStore { - coeffStore[i] = make([]bls.Fr, l) + coeffStore[i] = make([]fr.Element, l) } for w := uint64(0); w < numWorker; w++ { @@ -146,7 +152,7 @@ func (p *ParametrizedProver) ProveAllCosetThreads(polyFr []bls.Fr, numChunks, ch } close(jobChan) - // return only first error + // return last error var err error for w := uint64(0); w < numWorker; w++ { wr := <-results @@ -162,16 +168,23 @@ func (p *ParametrizedProver) ProveAllCosetThreads(polyFr []bls.Fr, numChunks, ch t0 := time.Now() // compute proof by multi scaler mulplication - var wg sync.WaitGroup + msmErrors := make(chan error, dimE*2) for i := uint64(0); i < dimE*2; i++ { - wg.Add(1) + go func(k uint64) { - defer wg.Done() - sumVec[k] = *bls.LinCombG1(p.FFTPointsT[k], coeffStore[k]) + _, err := sumVec[k].MultiExp(p.FFTPointsT[k], coeffStore[k], ecc.MultiExpConfig{}) + // handle error + msmErrors <- err }(i) } - wg.Wait() + for i := uint64(0); i < dimE*2; i++ { + err := <-msmErrors + if err != nil { + fmt.Println("Error. MSM while adding points", err) + return nil, err + } + } t1 := time.Now() @@ -193,16 +206,15 @@ func (p *ParametrizedProver) ProveAllCosetThreads(polyFr []bls.Fr, numChunks, ch fmt.Printf("mult-th %v, msm %v,fft1 %v, fft2 %v,\n", t0.Sub(begin), t1.Sub(t0), t2.Sub(t1), t3.Sub(t2)) - //rb.ReverseBitOrderG1Point(proofs) return proofs, nil } func (p *ParametrizedProver) proofWorker( - polyFr []bls.Fr, + polyFr []fr.Element, jobChan <-chan uint64, l uint64, dimE uint64, - coeffStore [][]bls.Fr, + coeffStore [][]fr.Element, results chan<- WorkerResult, ) { @@ -230,14 +242,15 @@ func (p *ParametrizedProver) proofWorker( // phi ^ (coset size ) = 1 // // implicitly pad slices to power of 2 -func (p *ParametrizedProver) GetSlicesCoeff(polyFr []bls.Fr, dimE, j, l uint64) ([]bls.Fr, error) { +func (p *ParametrizedProver) GetSlicesCoeff(polyFr []fr.Element, dimE, j, l uint64) ([]fr.Element, error) { // there is a constant term m := uint64(len(polyFr)) - 1 dim := (m - j) / l - toeV := make([]bls.Fr, 2*dimE-1) + toeV := make([]fr.Element, 2*dimE-1) for i := uint64(0); i < dim; i++ { - bls.CopyFr(&toeV[i], &polyFr[m-(j+i*l)]) + + toeV[i].Set(&polyFr[m-(j+i*l)]) } // use precompute table diff --git a/encoding/kzgrs/prover/parametrized_prover_test.go b/encoding/kzg/prover/parametrized_prover_test.go similarity index 75% rename from encoding/kzgrs/prover/parametrized_prover_test.go rename to encoding/kzg/prover/parametrized_prover_test.go index 3b8b2c0024..b56f8ad8aa 100644 --- a/encoding/kzgrs/prover/parametrized_prover_test.go +++ b/encoding/kzg/prover/parametrized_prover_test.go @@ -5,9 +5,9 @@ import ( "testing" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/Layr-Labs/eigenda/encoding/rs" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -40,8 +40,8 @@ func TestProveAllCosetThreads(t *testing.T) { fmt.Printf("frame %v leading coset %v\n", i, j) lc := enc.Fs.ExpandedRootsOfUnity[uint64(j)] - g2Atn, err := kzgrs.ReadG2Point(uint64(len(f.Coeffs)), kzgConfig) + g2Atn, err := kzg.ReadG2Point(uint64(len(f.Coeffs)), kzgConfig) require.Nil(t, err) - assert.True(t, verifier.VerifyFrame(&f, enc.Ks, commit, &lc, &g2Atn), "Proof %v failed\n", i) + assert.Nil(t, verifier.VerifyFrame(&f, enc.Ks, commit, &lc, &g2Atn), "Proof %v failed\n", i) } } diff --git a/encoding/kzgrs/prover/precompute.go b/encoding/kzg/prover/precompute.go similarity index 82% rename from encoding/kzgrs/prover/precompute.go rename to encoding/kzg/prover/precompute.go index 327ada79a8..9c76166d82 100644 --- a/encoding/kzgrs/prover/precompute.go +++ b/encoding/kzg/prover/precompute.go @@ -13,9 +13,9 @@ import ( "sync" "time" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - kzg "github.com/Layr-Labs/eigenda/pkg/kzg" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/Layr-Labs/eigenda/encoding/fft" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/consensys/gnark-crypto/ecc/bn254" ) type SubTable struct { @@ -33,10 +33,10 @@ type SRSTable struct { Tables map[TableParam]SubTable TableDir string NumWorker uint64 - s1 []bls.G1Point + s1 []bn254.G1Affine } -func NewSRSTable(tableDir string, s1 []bls.G1Point, numWorker uint64) (*SRSTable, error) { +func NewSRSTable(tableDir string, s1 []bn254.G1Affine, numWorker uint64) (*SRSTable, error) { err := os.MkdirAll(tableDir, os.ModePerm) if err != nil { @@ -87,7 +87,7 @@ func NewSRSTable(tableDir string, s1 []bls.G1Point, numWorker uint64) (*SRSTable func (p *SRSTable) GetSubTables( numChunks uint64, chunkLen uint64, -) ([][]bls.G1Point, error) { +) ([][]bn254.G1Affine, error) { cosetSize := chunkLen dimE := numChunks m := numChunks*chunkLen - 1 @@ -128,12 +128,12 @@ func (p *SRSTable) GetSubTables( } type DispatchReturn struct { - points []bls.G1Point + points []bn254.G1Affine j uint64 } // m = len(poly) - 1, which is deg -func (p *SRSTable) Precompute(dim, dimE, l, m uint64, filePath string, numWorker uint64) [][]bls.G1Point { +func (p *SRSTable) Precompute(dim, dimE, l, m uint64, filePath string, numWorker uint64) [][]bn254.G1Affine { order := dimE * l if l == 1 { order = dimE * 2 @@ -141,9 +141,9 @@ func (p *SRSTable) Precompute(dim, dimE, l, m uint64, filePath string, numWorker // TODO, create function only read g1 points //s1 := ReadG1Points(p.SrsFilePath, order) n := uint8(math.Log2(float64(order))) - fs := kzg.NewFFTSettings(n) + fs := fft.NewFFTSettings(n) - fftPoints := make([][]bls.G1Point, l) + fftPoints := make([][]bn254.G1Affine, l) numJob := l jobChan := make(chan uint64, numJob) @@ -170,7 +170,7 @@ func (p *SRSTable) Precompute(dim, dimE, l, m uint64, filePath string, numWorker return fftPoints } -func (p *SRSTable) precomputeWorker(fs *kzg.FFTSettings, m, dim, dimE uint64, jobChan <-chan uint64, l uint64, results chan DispatchReturn) { +func (p *SRSTable) precomputeWorker(fs *fft.FFTSettings, m, dim, dimE uint64, jobChan <-chan uint64, l uint64, results chan DispatchReturn) { for j := range jobChan { dr, err := p.PrecomputeSubTable(fs, m, dim, dimE, j, l) if err != nil { @@ -181,17 +181,17 @@ func (p *SRSTable) precomputeWorker(fs *kzg.FFTSettings, m, dim, dimE uint64, jo } } -func (p *SRSTable) PrecomputeSubTable(fs *kzg.FFTSettings, m, dim, dimE, j, l uint64) (DispatchReturn, error) { +func (p *SRSTable) PrecomputeSubTable(fs *fft.FFTSettings, m, dim, dimE, j, l uint64) (DispatchReturn, error) { // there is a constant term - points := make([]bls.G1Point, 2*dimE) + points := make([]bn254.G1Affine, 2*dimE) k := m - l - j for i := uint64(0); i < dim; i++ { - bls.CopyG1(&points[i], &p.s1[k]) + points[i].Set(&p.s1[k]) k -= l } for i := dim; i < 2*dimE; i++ { - bls.CopyG1(&points[i], &bls.ZeroG1) + points[i].Set(&kzg.ZeroG1) } y, err := fs.FFTG1(points, false) @@ -213,21 +213,15 @@ type Boundary struct { sliceAt uint64 } -func (p *SRSTable) TableReaderThreads(filePath string, dimE, l uint64, numWorker uint64) ([][]bls.G1Point, error) { +func (p *SRSTable) TableReaderThreads(filePath string, dimE, l uint64, numWorker uint64) ([][]bn254.G1Affine, error) { g1f, err := os.Open(filePath) if err != nil { log.Println("TableReaderThreads.ERR.0", err) return nil, err } - //todo: resolve panic - defer func() { - if err := g1f.Close(); err != nil { - panic(err) - } - }() // 2 due to circular FFT mul - subTableSize := dimE * 2 * kzgrs.G1PointBytes + subTableSize := dimE * 2 * kzg.G1PointBytes totalSubTableSize := subTableSize * l if numWorker > l { @@ -253,7 +247,7 @@ func (p *SRSTable) TableReaderThreads(filePath string, dimE, l uint64, numWorker boundaries[i] = boundary } - fftPoints := make([][]bls.G1Point, l) + fftPoints := make([][]bn254.G1Affine, l) jobChan := make(chan Boundary, l) @@ -268,21 +262,26 @@ func (p *SRSTable) TableReaderThreads(filePath string, dimE, l uint64, numWorker } close(jobChan) wg.Wait() + + if err := g1f.Close(); err != nil { + return nil, err + } + return fftPoints, nil } func (p *SRSTable) readWorker( buf []byte, - fftPoints [][]bls.G1Point, + fftPoints [][]bn254.G1Affine, jobChan <-chan Boundary, dimE uint64, wg *sync.WaitGroup, ) { for b := range jobChan { - slicePoints := make([]bls.G1Point, dimE*2) + slicePoints := make([]bn254.G1Affine, dimE*2) for i := uint64(0); i < dimE*2; i++ { - g1 := buf[b.start+i*kzgrs.G1PointBytes : b.start+(i+1)*kzgrs.G1PointBytes] - err := slicePoints[i].UnmarshalText(g1[:]) + g1 := buf[b.start+i*kzg.G1PointBytes : b.start+(i+1)*kzg.G1PointBytes] + _, err := slicePoints[i].SetBytes(g1[:]) //UnmarshalText(g1[:]) if err != nil { log.Printf("Error. From %v to %v. %v", b.start, b.end, err) log.Println() @@ -295,7 +294,7 @@ func (p *SRSTable) readWorker( wg.Done() } -func (p *SRSTable) TableWriter(fftPoints [][]bls.G1Point, dimE uint64, filePath string) error { +func (p *SRSTable) TableWriter(fftPoints [][]bn254.G1Affine, dimE uint64, filePath string) error { wf, err := os.Create(filePath) if err != nil { log.Println("TableWriter.ERR.0", err) @@ -310,8 +309,8 @@ func (p *SRSTable) TableWriter(fftPoints [][]bls.G1Point, dimE uint64, filePath for j := uint64(0); j < l; j++ { for i := uint64(0); i < dimE*2; i++ { - g1Bytes := fftPoints[j][i].MarshalText() - if _, err := writer.Write(g1Bytes); err != nil { + g1Bytes := fftPoints[j][i].Bytes() + if _, err := writer.Write(g1Bytes[:]); err != nil { log.Println("TableWriter.ERR.2", err) return err } @@ -327,5 +326,8 @@ func (p *SRSTable) TableWriter(fftPoints [][]bls.G1Point, dimE uint64, filePath log.Println("TableWriter.ERR.4", err) return err } - return nil + + err = wf.Close() + + return err } diff --git a/encoding/kzgrs/prover/precompute_test.go b/encoding/kzg/prover/precompute_test.go similarity index 82% rename from encoding/kzgrs/prover/precompute_test.go rename to encoding/kzg/prover/precompute_test.go index 1c7c680fb8..035514bd28 100644 --- a/encoding/kzgrs/prover/precompute_test.go +++ b/encoding/kzg/prover/precompute_test.go @@ -7,8 +7,8 @@ import ( "github.com/stretchr/testify/require" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" ) func TestNewSRSTable_PreComputeWorks(t *testing.T) { @@ -19,11 +19,11 @@ func TestNewSRSTable_PreComputeWorks(t *testing.T) { params := encoding.ParamsFromSysPar(numSys, numPar, uint64(len(gettysburgAddressBytes))) require.NotNil(t, params) - s1, err := kzgrs.ReadG1Points(kzgConfig.G1Path, kzgConfig.SRSOrder, kzgConfig.NumWorker) + s1, err := kzg.ReadG1Points(kzgConfig.G1Path, kzgConfig.SRSOrder, kzgConfig.NumWorker) require.Nil(t, err) require.NotNil(t, s1) - _, err = kzgrs.ReadG2Points(kzgConfig.G2Path, kzgConfig.SRSOrder, kzgConfig.NumWorker) + _, err = kzg.ReadG2Points(kzgConfig.G2Path, kzgConfig.SRSOrder, kzgConfig.NumWorker) require.Nil(t, err) subTable1, err := prover.NewSRSTable(kzgConfig.CacheDir, s1, kzgConfig.NumWorker) diff --git a/encoding/kzgrs/prover/prover.go b/encoding/kzg/prover/prover.go similarity index 84% rename from encoding/kzgrs/prover/prover.go rename to encoding/kzg/prover/prover.go index 6c47be9ce9..6dedb74381 100644 --- a/encoding/kzgrs/prover/prover.go +++ b/encoding/kzg/prover/prover.go @@ -12,18 +12,18 @@ import ( "sync" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" + "github.com/Layr-Labs/eigenda/encoding/fft" + "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/Layr-Labs/eigenda/encoding/rs" - kzg "github.com/Layr-Labs/eigenda/pkg/kzg" + "github.com/consensys/gnark-crypto/ecc/bn254" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" _ "go.uber.org/automaxprocs" ) type Prover struct { - *kzgrs.KzgConfig + *kzg.KzgConfig Srs *kzg.SRS - G2Trailing []bls.G2Point + G2Trailing []bn254.G2Affine mu sync.Mutex LoadG2Points bool @@ -32,21 +32,21 @@ type Prover struct { var _ encoding.Prover = &Prover{} -func NewProver(config *kzgrs.KzgConfig, loadG2Points bool) (*Prover, error) { +func NewProver(config *kzg.KzgConfig, loadG2Points bool) (*Prover, error) { if config.SRSNumberToLoad > config.SRSOrder { return nil, errors.New("SRSOrder is less than srsNumberToLoad") } // read the whole order, and treat it as entire SRS for low degree proof - s1, err := kzgrs.ReadG1Points(config.G1Path, config.SRSNumberToLoad, config.NumWorker) + s1, err := kzg.ReadG1Points(config.G1Path, config.SRSNumberToLoad, config.NumWorker) if err != nil { log.Println("failed to read G1 points", err) return nil, err } - s2 := make([]bls.G2Point, 0) - g2Trailing := make([]bls.G2Point, 0) + s2 := make([]bn254.G2Affine, 0) + g2Trailing := make([]bn254.G2Affine, 0) // PreloadEncoder is by default not used by operator node, PreloadEncoder if loadG2Points { @@ -54,13 +54,13 @@ func NewProver(config *kzgrs.KzgConfig, loadG2Points bool) (*Prover, error) { return nil, fmt.Errorf("G2Path is empty. However, object needs to load G2Points") } - s2, err = kzgrs.ReadG2Points(config.G2Path, config.SRSNumberToLoad, config.NumWorker) + s2, err = kzg.ReadG2Points(config.G2Path, config.SRSNumberToLoad, config.NumWorker) if err != nil { log.Println("failed to read G2 points", err) return nil, err } - g2Trailing, err = kzgrs.ReadG2PointSection( + g2Trailing, err = kzg.ReadG2PointSection( config.G2Path, config.SRSOrder-config.SRSNumberToLoad, config.SRSOrder, // last exclusive @@ -209,18 +209,19 @@ func (g *Prover) newProver(params encoding.EncodingParams) (*ParametrizedProver, return nil, err } - fftPointsT := make([][]bls.G1Point, len(fftPoints[0])) + fftPointsT := make([][]bn254.G1Affine, len(fftPoints[0])) for i := range fftPointsT { - fftPointsT[i] = make([]bls.G1Point, len(fftPoints)) + fftPointsT[i] = make([]bn254.G1Affine, len(fftPoints)) for j := uint64(0); j < encoder.ChunkLength; j++ { fftPointsT[i][j] = fftPoints[j][i] } } + _ = fftPoints n := uint8(math.Log2(float64(encoder.NumEvaluations()))) if encoder.ChunkLength == 1 { n = uint8(math.Log2(float64(2 * encoder.NumChunks))) } - fs := kzg.NewFFTSettings(n) + fs := fft.NewFFTSettings(n) ks, err := kzg.NewKZGSettings(fs, g.Srs) if err != nil { @@ -228,7 +229,7 @@ func (g *Prover) newProver(params encoding.EncodingParams) (*ParametrizedProver, } t := uint8(math.Log2(float64(2 * encoder.NumChunks))) - sfs := kzg.NewFFTSettings(t) + sfs := fft.NewFFTSettings(t) return &ParametrizedProver{ Encoder: encoder, @@ -238,33 +239,10 @@ func (g *Prover) newProver(params encoding.EncodingParams) (*ParametrizedProver, Fs: fs, Ks: ks, SFs: sfs, - FFTPoints: fftPoints, FFTPointsT: fftPointsT, }, nil } -// get Fiat-Shamir challenge -// func createFiatShamirChallenge(byteArray [][32]byte) *bls.Fr { -// alphaBytesTmp := make([]byte, 0) -// for i := 0; i < len(byteArray); i++ { -// for j := 0; j < len(byteArray[i]); j++ { -// alphaBytesTmp = append(alphaBytesTmp, byteArray[i][j]) -// } -// } -// alphaBytes := crypto.Keccak256(alphaBytesTmp) -// alpha := new(bls.Fr) -// bls.FrSetBytes(alpha, alphaBytes) -// -// return alpha -// } - -// invert the divisor, then multiply -// func polyFactorDiv(dst *bls.Fr, a *bls.Fr, b *bls.Fr) { -// // TODO: use divmod instead. -// var tmp bls.Fr -// bls.InvModFr(&tmp, b) -// bls.MulModFr(dst, &tmp, a) -// } // Detect the precomputed table from the specified directory // the file name follow the name convention of diff --git a/encoding/kzgrs/prover/prover_fuzz_test.go b/encoding/kzg/prover/prover_fuzz_test.go similarity index 95% rename from encoding/kzgrs/prover/prover_fuzz_test.go rename to encoding/kzg/prover/prover_fuzz_test.go index 51ed05bd04..4b2fd4457a 100644 --- a/encoding/kzgrs/prover/prover_fuzz_test.go +++ b/encoding/kzg/prover/prover_fuzz_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" "github.com/stretchr/testify/assert" ) diff --git a/encoding/kzgrs/prover/prover_test.go b/encoding/kzg/prover/prover_test.go similarity index 95% rename from encoding/kzgrs/prover/prover_test.go rename to encoding/kzg/prover/prover_test.go index 9ef23bf5eb..ebf9ccd6ff 100644 --- a/encoding/kzgrs/prover/prover_test.go +++ b/encoding/kzg/prover/prover_test.go @@ -9,9 +9,9 @@ import ( "testing" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/stretchr/testify/assert" ) @@ -22,7 +22,7 @@ const ( var ( gettysburgAddressBytes = []byte("Fourscore and seven years ago our fathers brought forth, on this continent, a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived, and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting-place for those who here gave their lives, that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we cannot dedicate, we cannot consecrate—we cannot hallow—this ground. The brave men, living and dead, who struggled here, have consecrated it far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us—that from these honored dead we take increased devotion to that cause for which they here gave the last full measure of devotion—that we here highly resolve that these dead shall not have died in vain—that this nation, under God, shall have a new birth of freedom, and that government of the people, by the people, for the people, shall not perish from the earth.") - kzgConfig *kzgrs.KzgConfig + kzgConfig *kzg.KzgConfig numNode uint64 numSys uint64 numPar uint64 @@ -31,7 +31,7 @@ var ( func setupSuite(t *testing.T) func(t *testing.T) { log.Println("Setting up suite") - kzgConfig = &kzgrs.KzgConfig{ + kzgConfig = &kzg.KzgConfig{ G1Path: "../../../inabox/resources/kzg/g1.point", G2Path: "../../../inabox/resources/kzg/g2.point", G2PowerOf2Path: "../../../inabox/resources/kzg/g2.point.powerOf2", diff --git a/encoding/kzg/setup.go b/encoding/kzg/setup.go new file mode 100644 index 0000000000..3a6eba8b75 --- /dev/null +++ b/encoding/kzg/setup.go @@ -0,0 +1,134 @@ +// This code is sourced from the go-kzg Repository by protolambda. +// Original code: https://github.com/protolambda/go-kzg +// MIT License +// +// Copyright (c) 2020 @protolambda +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +//go:build !bignum_pure && !bignum_hol256 +// +build !bignum_pure,!bignum_hol256 + +package kzg + +import ( + "math/big" + + "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" + + "bufio" + "fmt" + "log" + "os" + "strconv" + "time" +) + +// GenerateTestingSetup creates a setup of n values from the given secret. **for testing purposes only** +func GenerateTestingSetup(secret string, n uint64) ([]bn254.G1Affine, []bn254.G2Affine, error) { + var s fr.Element + _, err := s.SetString(secret) + if err != nil { + return nil, nil, err + } + + var sPow fr.Element + sPow.SetOne() + + s1Out := make([]bn254.G1Affine, n) + s2Out := make([]bn254.G2Affine, n) + for i := uint64(0); i < n; i++ { + + s1Out[i].ScalarMultiplication(&GenG1, sPow.BigInt(new(big.Int))) + + + s2Out[i].ScalarMultiplication(&GenG2, sPow.BigInt(new(big.Int))) + + sPow.Mul(&sPow, &s) + } + return s1Out, s2Out, nil +} + +func WriteGeneratorPoints(n uint64) error { + secret := "1927409816240961209460912649125" + ns := strconv.Itoa(int(n)) + + var s fr.Element + _, err := s.SetString(secret) + if err != nil { + return err + } + + + var sPow fr.Element + sPow.SetOne() + + + g1f, err := os.Create("g1.point." + ns) + if err != nil { + log.Println("WriteGeneratorPoints.ERR.0", err) + return err + } + + g1w := bufio.NewWriter(g1f) + g2f, err := os.Create("g2.point." + ns) + if err != nil { + log.Println("WriteGeneratorPoints.ERR.1", err) + return err + } + g2w := bufio.NewWriter(g2f) + + + + start := time.Now() + for i := uint64(0); i < n; i++ { + var s1Out bn254.G1Affine + var s2Out bn254.G2Affine + s1Out.ScalarMultiplication(&GenG1, sPow.BigInt(new(big.Int))) + + s2Out.ScalarMultiplication(&GenG2, sPow.BigInt(new(big.Int))) + + g1Byte := s1Out.Bytes() + if _, err := g1w.Write(g1Byte[:]); err != nil { + log.Println("WriteGeneratorPoints.ERR.3", err) + return err + } + + g2Byte := s2Out.Bytes() + if _, err := g2w.Write(g2Byte[:]); err != nil { + log.Println("WriteGeneratorPoints.ERR.5", err) + return err + } + sPow.Mul(&sPow, &s) + } + + if err = g1w.Flush(); err != nil { + log.Println("WriteGeneratorPoints.ERR.6", err) + return err + } + if err = g2w.Flush(); err != nil { + log.Println("WriteGeneratorPoints.ERR.7", err) + return err + } + t := time.Now() + elapsed := t.Sub(start) + fmt.Println("Generating takes", elapsed) + return nil +} diff --git a/pkg/kzg/srs.go b/encoding/kzg/srs.go similarity index 89% rename from pkg/kzg/srs.go rename to encoding/kzg/srs.go index e63610346d..25a6c16851 100644 --- a/pkg/kzg/srs.go +++ b/encoding/kzg/srs.go @@ -24,17 +24,19 @@ package kzg -import bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" +import ( + "github.com/consensys/gnark-crypto/ecc/bn254" +) type SRS struct { // [b.multiply(b.G1, pow(s, i, MODULUS)) for i in range(WIDTH+1)], - G1 []bls.G1Point + G1 []bn254.G1Affine // [b.multiply(b.G2, pow(s, i, MODULUS)) for i in range(WIDTH+1)], - G2 []bls.G2Point + G2 []bn254.G2Affine } -func NewSrs(G1 []bls.G1Point, G2 []bls.G2Point) (*SRS, error) { +func NewSrs(G1 []bn254.G1Affine, G2 []bn254.G2Affine) (*SRS, error) { return &SRS{ G1: G1, diff --git a/encoding/kzgrs/verifier/batch_commit_equivalence.go b/encoding/kzg/verifier/batch_commit_equivalence.go similarity index 54% rename from encoding/kzgrs/verifier/batch_commit_equivalence.go rename to encoding/kzg/verifier/batch_commit_equivalence.go index 7b61b23e31..fb3f1ed01f 100644 --- a/encoding/kzgrs/verifier/batch_commit_equivalence.go +++ b/encoding/kzg/verifier/batch_commit_equivalence.go @@ -6,46 +6,50 @@ import ( "errors" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/Layr-Labs/eigenda/encoding/kzg" + + "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) type CommitmentPair struct { - Commitment bn254.G1Point - LengthCommitment bn254.G2Point + Commitment bn254.G1Affine + LengthCommitment bn254.G2Affine } // generate a random value using Fiat Shamir transform // we can also pseudo randomness generated locally, but we have to ensure no adversary can manipulate it // Hashing everything takes about 1ms, so Fiat Shamir transform does not incur much cost -func GenRandomFactorForEquivalence(g1commits []bn254.G1Point, g2commits []bn254.G2Point) (bn254.Fr, error) { +func GenRandomFactorForEquivalence(g1commits []bn254.G1Affine, g2commits []bn254.G2Affine) (fr.Element, error) { var buffer bytes.Buffer enc := gob.NewEncoder(&buffer) for _, commit := range g1commits { err := enc.Encode(commit) if err != nil { - return bn254.ZERO, err + return fr.Element{}, err } } for _, commit := range g2commits { err := enc.Encode(commit) if err != nil { - return bn254.ZERO, err + return fr.Element{}, err } } - var randomFr bn254.Fr + var randomFr fr.Element - err := bn254.HashToSingleField(&randomFr, buffer.Bytes()) + err := kzg.HashToSingleField(&randomFr, buffer.Bytes()) if err != nil { - return bn254.ZERO, err + return fr.Element{}, err } return randomFr, nil } -func CreateRandomnessVector(g1commits []bn254.G1Point, g2commits []bn254.G2Point) ([]bn254.Fr, error) { +func CreateRandomnessVector(g1commits []bn254.G1Affine, g2commits []bn254.G2Affine) ([]fr.Element, error) { r, err := GenRandomFactorForEquivalence(g1commits, g2commits) if err != nil { return nil, err @@ -53,15 +57,16 @@ func CreateRandomnessVector(g1commits []bn254.G1Point, g2commits []bn254.G2Point n := len(g1commits) if len(g1commits) != len(g2commits) { - return nil, errors.New("Inconsistent number of blobs for g1 and g2") + return nil, errors.New("inconsistent number of blobs for g1 and g2") } - randomsFr := make([]bn254.Fr, n) - bn254.CopyFr(&randomsFr[0], &r) + randomsFr := make([]fr.Element, n) + + randomsFr[0].Set(&r) // power of r for j := 0; j < n-1; j++ { - bn254.MulModFr(&randomsFr[j+1], &randomsFr[j], &r) + randomsFr[j+1].Mul(&randomsFr[j], &r) } return randomsFr, nil @@ -72,8 +77,8 @@ func (v *Verifier) VerifyCommitEquivalenceBatch(commitments []encoding.BlobCommi for i, c := range commitments { commitmentsPair[i] = CommitmentPair{ - Commitment: (bn254.G1Point)(*c.Commitment), - LengthCommitment: (bn254.G2Point)(*c.LengthCommitment), + Commitment: (bn254.G1Affine)(*c.Commitment), + LengthCommitment: (bn254.G2Affine)(*c.LengthCommitment), } } return v.BatchVerifyCommitEquivalence(commitmentsPair) @@ -81,8 +86,8 @@ func (v *Verifier) VerifyCommitEquivalenceBatch(commitments []encoding.BlobCommi func (group *Verifier) BatchVerifyCommitEquivalence(commitmentsPair []CommitmentPair) error { - g1commits := make([]bn254.G1Point, len(commitmentsPair)) - g2commits := make([]bn254.G2Point, len(commitmentsPair)) + g1commits := make([]bn254.G1Affine, len(commitmentsPair)) + g2commits := make([]bn254.G2Affine, len(commitmentsPair)) for i := 0; i < len(commitmentsPair); i++ { g1commits[i] = commitmentsPair[i].Commitment g2commits[i] = commitmentsPair[i].LengthCommitment @@ -93,13 +98,23 @@ func (group *Verifier) BatchVerifyCommitEquivalence(commitmentsPair []Commitment return err } - lhsG1 := bn254.LinCombG1(g1commits, randomsFr) - lhsG2 := &bn254.GenG2 + var lhsG1 bn254.G1Affine + _, err = lhsG1.MultiExp(g1commits, randomsFr, ecc.MultiExpConfig{}) + if err != nil { + return err + } - rhsG2 := bn254.LinCombG2(g2commits, randomsFr) - rhsG1 := &bn254.GenG1 + lhsG2 := &kzg.GenG2 + + var rhsG2 bn254.G2Affine + _, err = rhsG2.MultiExp(g2commits, randomsFr, ecc.MultiExpConfig{}) + if err != nil { + return err + } + rhsG1 := &kzg.GenG1 - if bn254.PairingsVerify(lhsG1, lhsG2, rhsG1, rhsG2) { + err = PairingsVerify(&lhsG1, lhsG2, rhsG1, &rhsG2) + if err == nil { return nil } else { return errors.New("Universal Verify Incorrect paring") diff --git a/encoding/kzgrs/verifier/batch_commit_equivalence_test.go b/encoding/kzg/verifier/batch_commit_equivalence_test.go similarity index 81% rename from encoding/kzgrs/verifier/batch_commit_equivalence_test.go rename to encoding/kzg/verifier/batch_commit_equivalence_test.go index 0ba1433140..d1cebe1e88 100644 --- a/encoding/kzgrs/verifier/batch_commit_equivalence_test.go +++ b/encoding/kzg/verifier/batch_commit_equivalence_test.go @@ -4,10 +4,11 @@ import ( "testing" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/Layr-Labs/eigenda/encoding/rs" - "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + + "github.com/consensys/gnark-crypto/ecc/bn254" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -37,8 +38,9 @@ func TestBatchEquivalence(t *testing.T) { assert.NoError(t, v.BatchVerifyCommitEquivalence(commitPairs), "batch equivalence negative test failed\n") - var modifiedCommit bn254.G1Point - bn254.AddG1(&modifiedCommit, commit, commit) + var modifiedCommit bn254.G1Affine + modifiedCommit.Add(commit, commit) + for z := 0; z < numBlob; z++ { commitPairs[z] = verifier.CommitmentPair{ Commitment: modifiedCommit, @@ -55,7 +57,7 @@ func TestBatchEquivalence(t *testing.T) { } } - bn254.AddG1(&commitPairs[numBlob/2].Commitment, &commitPairs[numBlob/2].Commitment, &commitPairs[numBlob/2].Commitment) + commitPairs[numBlob/2].Commitment.Add(&commitPairs[numBlob/2].Commitment, &commitPairs[numBlob/2].Commitment) assert.Error(t, v.BatchVerifyCommitEquivalence(commitPairs), "batch equivalence negative test failed in outer loop\n") } diff --git a/encoding/kzgrs/verifier/degree_test.go b/encoding/kzg/verifier/degree_test.go similarity index 91% rename from encoding/kzgrs/verifier/degree_test.go rename to encoding/kzg/verifier/degree_test.go index ce275eabee..ff811b5cb7 100644 --- a/encoding/kzgrs/verifier/degree_test.go +++ b/encoding/kzg/verifier/degree_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/Layr-Labs/eigenda/encoding/rs" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/encoding/kzgrs/verifier/frame_test.go b/encoding/kzg/verifier/frame_test.go similarity index 68% rename from encoding/kzgrs/verifier/frame_test.go rename to encoding/kzg/verifier/frame_test.go index eaf6c55778..d3353733de 100644 --- a/encoding/kzgrs/verifier/frame_test.go +++ b/encoding/kzg/verifier/frame_test.go @@ -8,10 +8,11 @@ import ( "github.com/stretchr/testify/require" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" - kzg "github.com/Layr-Labs/eigenda/pkg/kzg" + + "github.com/Layr-Labs/eigenda/encoding/fft" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" ) func TestVerify(t *testing.T) { @@ -32,13 +33,13 @@ func TestVerify(t *testing.T) { require.NotNil(t, frames) n := uint8(math.Log2(float64(params.NumEvaluations()))) - fs := kzg.NewFFTSettings(n) + fs := fft.NewFFTSettings(n) require.NotNil(t, fs) lc := enc.Fs.ExpandedRootsOfUnity[uint64(0)] require.NotNil(t, lc) - g2Atn, err := kzgrs.ReadG2Point(uint64(len(frames[0].Coeffs)), kzgConfig) + g2Atn, err := kzg.ReadG2Point(uint64(len(frames[0].Coeffs)), kzgConfig) require.Nil(t, err) - assert.True(t, verifier.VerifyFrame(&frames[0], enc.Ks, commit, &lc, &g2Atn)) + assert.Nil(t, verifier.VerifyFrame(&frames[0], enc.Ks, commit, &lc, &g2Atn)) } diff --git a/encoding/kzgrs/verifier/multiframe.go b/encoding/kzg/verifier/multiframe.go similarity index 67% rename from encoding/kzgrs/verifier/multiframe.go rename to encoding/kzg/verifier/multiframe.go index f81cf6e56c..7ae8955a1d 100644 --- a/encoding/kzgrs/verifier/multiframe.go +++ b/encoding/kzg/verifier/multiframe.go @@ -8,42 +8,43 @@ import ( "math" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" + + "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/Layr-Labs/eigenda/encoding/rs" - kzg "github.com/Layr-Labs/eigenda/pkg/kzg" - "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) // Sample is the basic unit for a verification // A blob may contain multiple Samples type Sample struct { - Commitment bls.G1Point - Proof bls.G1Point + Commitment bn254.G1Affine + Proof bn254.G1Affine RowIndex int // corresponds to a row in the verification matrix - Coeffs []bls.Fr + Coeffs []fr.Element X uint // X is the evaluating index which corresponds to the leading coset } // generate a random value using Fiat Shamir transform // we can also pseudo randomness generated locally, but we have to ensure no adversary can manipulate it // Hashing everything takes about 1ms, so Fiat Shamir transform does not incur much cost -func GenRandomFactor(samples []Sample) (bls.Fr, error) { +func GenRandomFactor(samples []Sample) (fr.Element, error) { var buffer bytes.Buffer enc := gob.NewEncoder(&buffer) for _, sample := range samples { err := enc.Encode(sample.Commitment) if err != nil { - return bls.ZERO, err + return fr.Element{}, err } } - var randomFr bls.Fr + var randomFr fr.Element - err := bls.HashToSingleField(&randomFr, buffer.Bytes()) + err := kzg.HashToSingleField(&randomFr, buffer.Bytes()) if err != nil { - return bls.ZERO, err + return fr.Element{}, err } return randomFr, nil @@ -51,7 +52,7 @@ func GenRandomFactor(samples []Sample) (bls.Fr, error) { // Every sample has its own randomness, even though multiple samples can come from identical blob // Randomnesss for each sample is computed by repeatedly raising the power of the root randomness -func GenRandomnessVector(samples []Sample) ([]bls.Fr, error) { +func GenRandomnessVector(samples []Sample) ([]fr.Element, error) { // root randomness r, err := GenRandomFactor(samples) if err != nil { @@ -60,50 +61,57 @@ func GenRandomnessVector(samples []Sample) ([]bls.Fr, error) { n := len(samples) - randomsFr := make([]bls.Fr, n) - bls.CopyFr(&randomsFr[0], &r) + randomsFr := make([]fr.Element, n) + randomsFr[0].Set(&r) // power of r for j := 0; j < n-1; j++ { - bls.MulModFr(&randomsFr[j+1], &randomsFr[j], &r) + randomsFr[j+1].Mul(&randomsFr[j], &r) } return randomsFr, nil } // the rhsG1 comprises of three terms, see https://ethresear.ch/t/a-universal-verification-equation-for-data-availability-sampling/13240/1 -func genRhsG1(samples []Sample, randomsFr []bls.Fr, m int, params encoding.EncodingParams, ks *kzg.KZGSettings, proofs []bls.G1Point) (*bls.G1Point, error) { +func genRhsG1(samples []Sample, randomsFr []fr.Element, m int, params encoding.EncodingParams, ks *kzg.KZGSettings, proofs []bn254.G1Affine) (*bn254.G1Affine, error) { n := len(samples) - commits := make([]bls.G1Point, m) + commits := make([]bn254.G1Affine, m) D := params.ChunkLength - var tmp bls.Fr + var tmp fr.Element // first term // get coeffs to compute the aggregated commitment // note the coeff is affected by how many chunks are validated per blob // if x chunks are sampled from one blob, we need to compute the sum of all x random field element corresponding to each sample - aggCommitCoeffs := make([]bls.Fr, m) + aggCommitCoeffs := make([]fr.Element, m) setCommit := make([]bool, m) for k := 0; k < n; k++ { s := samples[k] row := s.RowIndex - bls.AddModFr(&aggCommitCoeffs[row], &aggCommitCoeffs[row], &randomsFr[k]) + + aggCommitCoeffs[row].Add(&aggCommitCoeffs[row], &randomsFr[k]) if !setCommit[row] { - bls.CopyG1(&commits[row], &s.Commitment) + commits[row].Set(&s.Commitment) + setCommit[row] = true } else { - if !bls.EqualG1(&commits[row], &s.Commitment) { - return nil, errors.New("Samples of the same row has different commitments") + + if !commits[row].Equal(&s.Commitment) { + return nil, errors.New("samples of the same row has different commitments") } } } - aggCommit := bls.LinCombG1(commits, aggCommitCoeffs) + var aggCommit bn254.G1Affine + _, err := aggCommit.MultiExp(commits, aggCommitCoeffs, ecc.MultiExpConfig{}) + if err != nil { + return nil, err + } // second term // compute the aggregated interpolation polynomial - aggPolyCoeffs := make([]bls.Fr, D) + aggPolyCoeffs := make([]fr.Element, D) // we sum over the weighted coefficients (by the random field element) over all D monomial in all n samples for k := 0; k < n; k++ { @@ -111,50 +119,63 @@ func genRhsG1(samples []Sample, randomsFr []bls.Fr, m int, params encoding.Encod rk := randomsFr[k] // for each monomial in a given polynomial, multiply its coefficient with the corresponding random field, - // then sum it with others. Given ChunkLength (D) is identical for all samples in a subBatch. + // then sum it with others. Given ChunkLen (D) is identical for all samples in a subBatch. // The operation is always valid. for j := uint64(0); j < D; j++ { - bls.MulModFr(&tmp, &coeffs[j], &rk) - bls.AddModFr(&aggPolyCoeffs[j], &aggPolyCoeffs[j], &tmp) + tmp.Mul(&coeffs[j], &rk) + //bls.MulModFr(&tmp, &coeffs[j], &rk) + //bls.AddModFr(&aggPolyCoeffs[j], &aggPolyCoeffs[j], &tmp) + aggPolyCoeffs[j].Add(&aggPolyCoeffs[j], &tmp) } } // All samples in a subBatch has identical chunkLen - aggPolyG1 := bls.LinCombG1(ks.Srs.G1[:D], aggPolyCoeffs) + var aggPolyG1 bn254.G1Affine + _, err = aggPolyG1.MultiExp(ks.Srs.G1[:D], aggPolyCoeffs, ecc.MultiExpConfig{}) + if err != nil { + return nil, err + } // third term // leading coset is an evaluation index, here we compute the weighted leading coset evaluation by random fields - lcCoeffs := make([]bls.Fr, n) + lcCoeffs := make([]fr.Element, n) // get leading coset powers - leadingDs := make([]bls.Fr, n) + leadingDs := make([]fr.Element, n) for k := 0; k < n; k++ { // got the leading coset field element h := ks.ExpandedRootsOfUnity[samples[k].X] - var hPow bls.Fr - bls.CopyFr(&hPow, &bls.ONE) + var hPow fr.Element + hPow.SetOne() // raising the power for each leading coset for j := uint64(0); j < D; j++ { - bls.MulModFr(&tmp, &hPow, &h) - bls.CopyFr(&hPow, &tmp) + hPow.Mul(&hPow, &h) } - bls.CopyFr(&leadingDs[k], &hPow) + + leadingDs[k].Set(&hPow) } // applying the random weights to leading coset elements for k := 0; k < n; k++ { rk := randomsFr[k] - bls.MulModFr(&lcCoeffs[k], &rk, &leadingDs[k]) + + lcCoeffs[k].Mul(&rk, &leadingDs[k]) + } + + var offsetG1 bn254.G1Affine + _, err = offsetG1.MultiExp(proofs, lcCoeffs, ecc.MultiExpConfig{}) + if err != nil { + return nil, err } - offsetG1 := bls.LinCombG1(proofs, lcCoeffs) + var rhsG1 bn254.G1Affine + + rhsG1.Sub(&aggCommit, &aggPolyG1) - var rhsG1 bls.G1Point - bls.SubG1(&rhsG1, aggCommit, aggPolyG1) - bls.AddG1(&rhsG1, &rhsG1, offsetG1) + rhsG1.Add(&rhsG1, &offsetG1) return &rhsG1, nil } @@ -173,7 +194,7 @@ func (v *Verifier) UniversalVerifySubBatch(params encoding.EncodingParams, sampl } sample := Sample{ - Commitment: (bn254.G1Point)(*sc.Commitment), + Commitment: (bn254.G1Affine)(*sc.Commitment), Proof: sc.Chunk.Proof, RowIndex: sc.BlobIndex, Coeffs: sc.Chunk.Coeffs, @@ -224,21 +245,26 @@ func (group *Verifier) UniversalVerify(params encoding.EncodingParams, samples [ } // array of proofs - proofs := make([]bls.G1Point, n) + proofs := make([]bn254.G1Affine, n) for i := 0; i < n; i++ { - bls.CopyG1(&proofs[i], &samples[i].Proof) + + proofs[i].Set(&samples[i].Proof) } // lhs g1 - lhsG1 := bls.LinCombG1(proofs, randomsFr) + var lhsG1 bn254.G1Affine + _, err = lhsG1.MultiExp(proofs, randomsFr, ecc.MultiExpConfig{}) + if err != nil { + return err + } // lhs g2 exponent := uint64(math.Log2(float64(D))) - G2atD, err := kzgrs.ReadG2PointOnPowerOf2(exponent, group.KzgConfig) + G2atD, err := kzg.ReadG2PointOnPowerOf2(exponent, group.KzgConfig) if err != nil { // then try to access if there is a full list of g2 srs - G2atD, err = kzgrs.ReadG2Point(D, group.KzgConfig) + G2atD, err = kzg.ReadG2Point(D, group.KzgConfig) if err != nil { return err } @@ -248,7 +274,7 @@ func (group *Verifier) UniversalVerify(params encoding.EncodingParams, samples [ lhsG2 := &G2atD // rhs g2 - rhsG2 := &bls.GenG2 + rhsG2 := &kzg.GenG2 // rhs g1 rhsG1, err := genRhsG1( @@ -263,9 +289,5 @@ func (group *Verifier) UniversalVerify(params encoding.EncodingParams, samples [ return err } - if bls.PairingsVerify(lhsG1, lhsG2, rhsG1, rhsG2) { - return nil - } else { - return errors.New("Universal Verify Incorrect paring") - } + return PairingsVerify(&lhsG1, lhsG2, rhsG1, rhsG2) } diff --git a/encoding/kzgrs/verifier/multiframe_test.go b/encoding/kzg/verifier/multiframe_test.go similarity index 95% rename from encoding/kzgrs/verifier/multiframe_test.go rename to encoding/kzg/verifier/multiframe_test.go index 2cd199158e..64efa47d8b 100644 --- a/encoding/kzgrs/verifier/multiframe_test.go +++ b/encoding/kzg/verifier/multiframe_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/Layr-Labs/eigenda/encoding/rs" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/encoding/kzgrs/verifier/verifier.go b/encoding/kzg/verifier/verifier.go similarity index 66% rename from encoding/kzgrs/verifier/verifier.go rename to encoding/kzg/verifier/verifier.go index f77153cd8f..fd145034ee 100644 --- a/encoding/kzgrs/verifier/verifier.go +++ b/encoding/kzg/verifier/verifier.go @@ -5,21 +5,25 @@ import ( "fmt" "log" "math" + "math/big" "runtime" "sync" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" + + "github.com/Layr-Labs/eigenda/encoding/fft" + "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/Layr-Labs/eigenda/encoding/rs" - kzg "github.com/Layr-Labs/eigenda/pkg/kzg" - "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + + "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) type Verifier struct { - *kzgrs.KzgConfig + *kzg.KzgConfig Srs *kzg.SRS - G2Trailing []bls.G2Point + G2Trailing []bn254.G2Affine mu sync.Mutex LoadG2Points bool @@ -28,21 +32,21 @@ type Verifier struct { var _ encoding.Verifier = &Verifier{} -func NewVerifier(config *kzgrs.KzgConfig, loadG2Points bool) (*Verifier, error) { +func NewVerifier(config *kzg.KzgConfig, loadG2Points bool) (*Verifier, error) { if config.SRSNumberToLoad > config.SRSOrder { return nil, errors.New("SRSOrder is less than srsNumberToLoad") } // read the whole order, and treat it as entire SRS for low degree proof - s1, err := kzgrs.ReadG1Points(config.G1Path, config.SRSNumberToLoad, config.NumWorker) + s1, err := kzg.ReadG1Points(config.G1Path, config.SRSNumberToLoad, config.NumWorker) if err != nil { log.Println("failed to read G1 points", err) return nil, err } - s2 := make([]bls.G2Point, 0) - g2Trailing := make([]bls.G2Point, 0) + s2 := make([]bn254.G2Affine, 0) + g2Trailing := make([]bn254.G2Affine, 0) // PreloadEncoder is by default not used by operator node, PreloadEncoder if loadG2Points { @@ -50,13 +54,13 @@ func NewVerifier(config *kzgrs.KzgConfig, loadG2Points bool) (*Verifier, error) return nil, fmt.Errorf("G2Path is empty. However, object needs to load G2Points") } - s2, err = kzgrs.ReadG2Points(config.G2Path, config.SRSNumberToLoad, config.NumWorker) + s2, err = kzg.ReadG2Points(config.G2Path, config.SRSNumberToLoad, config.NumWorker) if err != nil { log.Println("failed to read G2 points", err) return nil, err } - g2Trailing, err = kzgrs.ReadG2PointSection( + g2Trailing, err = kzg.ReadG2PointSection( config.G2Path, config.SRSOrder-config.SRSNumberToLoad, config.SRSOrder, // last exclusive @@ -93,12 +97,12 @@ func NewVerifier(config *kzgrs.KzgConfig, loadG2Points bool) (*Verifier, error) } type ParametrizedVerifier struct { - *kzgrs.KzgConfig + *kzg.KzgConfig Srs *kzg.SRS *rs.Encoder - Fs *kzg.FFTSettings + Fs *fft.FFTSettings Ks *kzg.KZGSettings } @@ -136,7 +140,7 @@ func (g *Verifier) newKzgVerifier(params encoding.EncodingParams) (*Parametrized } n := uint8(math.Log2(float64(params.NumEvaluations()))) - fs := kzg.NewFFTSettings(n) + fs := fft.NewFFTSettings(n) ks, err := kzg.NewKZGSettings(fs, g.Srs) if err != nil { @@ -159,24 +163,25 @@ func (g *Verifier) newKzgVerifier(params encoding.EncodingParams) (*Parametrized } func (v *Verifier) VerifyBlobLength(commitments encoding.BlobCommitments) error { - return v.VerifyCommit((*bn254.G2Point)(commitments.LengthCommitment), (*bn254.G2Point)(commitments.LengthProof), uint64(commitments.Length)) + return v.VerifyCommit((*bn254.G2Affine)(commitments.LengthCommitment), (*bn254.G2Affine)(commitments.LengthProof), uint64(commitments.Length)) } // VerifyCommit verifies the low degree proof; since it doesn't depend on the encoding parameters // we leave it as a method of the KzgEncoderGroup -func (v *Verifier) VerifyCommit(lengthCommit *bls.G2Point, lowDegreeProof *bls.G2Point, length uint64) error { +func (v *Verifier) VerifyCommit(lengthCommit *bn254.G2Affine, lowDegreeProof *bn254.G2Affine, length uint64) error { - g1Challenge, err := kzgrs.ReadG1Point(v.SRSOrder-length, v.KzgConfig) + g1Challenge, err := kzg.ReadG1Point(v.SRSOrder-length, v.KzgConfig) if err != nil { return err } - if !VerifyLowDegreeProof(lengthCommit, lowDegreeProof, &g1Challenge) { - return errors.New("low degree proof fails") + err = VerifyLowDegreeProof(lengthCommit, lowDegreeProof, &g1Challenge) + if err != nil { + return fmt.Errorf("%v . %v ", "low degree proof fails", err) + } else { + return nil } - return nil - } // The function verify low degree proof against a poly commitment @@ -185,8 +190,8 @@ func (v *Verifier) VerifyCommit(lengthCommit *bls.G2Point, lowDegreeProof *bls.G // proof = commit(shiftedPoly) on G1 // so we can verify by checking // e( commit_1, [x^shift]_2) = e( proof_1, G_2 ) -func VerifyLowDegreeProof(lengthCommit *bls.G2Point, proof *bls.G2Point, g1Challenge *bls.G1Point) bool { - return bls.PairingsVerify(g1Challenge, lengthCommit, &bls.GenG1, proof) +func VerifyLowDegreeProof(lengthCommit *bn254.G2Affine, proof *bn254.G2Affine, g1Challenge *bn254.G1Affine) error { + return PairingsVerify(g1Challenge, lengthCommit, &kzg.GenG1, proof) } func (v *Verifier) VerifyFrames(frames []*encoding.Frame, indices []encoding.ChunkNumber, commitments encoding.BlobCommitments, params encoding.EncodingParams) error { @@ -198,7 +203,7 @@ func (v *Verifier) VerifyFrames(frames []*encoding.Frame, indices []encoding.Chu for ind := range frames { err = verifier.VerifyFrame( - (*bn254.G1Point)(commitments.Commitment), + (*bn254.G1Affine)(commitments.Commitment), frames[ind], uint64(indices[ind]), ) @@ -212,7 +217,7 @@ func (v *Verifier) VerifyFrames(frames []*encoding.Frame, indices []encoding.Chu } -func (v *ParametrizedVerifier) VerifyFrame(commit *bls.G1Point, f *encoding.Frame, index uint64) error { +func (v *ParametrizedVerifier) VerifyFrame(commit *bn254.G1Affine, f *encoding.Frame, index uint64) error { j, err := rs.GetLeadingCosetIndex( uint64(index), @@ -222,45 +227,51 @@ func (v *ParametrizedVerifier) VerifyFrame(commit *bls.G1Point, f *encoding.Fram return err } - g2Atn, err := kzgrs.ReadG2Point(uint64(len(f.Coeffs)), v.KzgConfig) + g2Atn, err := kzg.ReadG2Point(uint64(len(f.Coeffs)), v.KzgConfig) if err != nil { return err } - if !VerifyFrame(f, v.Ks, commit, &v.Ks.ExpandedRootsOfUnity[j], &g2Atn) { - return errors.New("multireveal proof fails") - } - - return nil + err = VerifyFrame(f, v.Ks, commit, &v.Ks.ExpandedRootsOfUnity[j], &g2Atn) + if err != nil { + return fmt.Errorf("%v . %v ", "VerifyFrame Error", err) + } else { + return nil + } } // Verify function assumes the Data stored is coefficients of coset's interpolating poly -func VerifyFrame(f *encoding.Frame, ks *kzg.KZGSettings, commitment *bls.G1Point, x *bls.Fr, g2Atn *bls.G2Point) bool { - var xPow bls.Fr - bls.CopyFr(&xPow, &bls.ONE) +func VerifyFrame(f *encoding.Frame, ks *kzg.KZGSettings, commitment *bn254.G1Affine, x *fr.Element, g2Atn *bn254.G2Affine) error { + var xPow fr.Element + xPow.SetOne() - var tmp bls.Fr for i := 0; i < len(f.Coeffs); i++ { - bls.MulModFr(&tmp, &xPow, x) - bls.CopyFr(&xPow, &tmp) + xPow.Mul(&xPow, x) } + var xPowBigInt big.Int + // [x^n]_2 - var xn2 bls.G2Point - bls.MulG2(&xn2, &bls.GenG2, &xPow) + var xn2 bn254.G2Affine - // [s^n - x^n]_2 - var xnMinusYn bls.G2Point + xn2.ScalarMultiplication(&kzg.GenG2, xPow.BigInt(&xPowBigInt)) - bls.SubG2(&xnMinusYn, g2Atn, &xn2) + // [s^n - x^n]_2 + var xnMinusYn bn254.G2Affine + xnMinusYn.Sub(g2Atn, &xn2) // [interpolation_polynomial(s)]_1 - is1 := bls.LinCombG1(ks.Srs.G1[:len(f.Coeffs)], f.Coeffs) + var is1 bn254.G1Affine + config := ecc.MultiExpConfig{} + _, err := is1.MultiExp(ks.Srs.G1[:len(f.Coeffs)], f.Coeffs, config) + if err != nil { + return err + } // [commitment - interpolation_polynomial(s)]_1 = [commit]_1 - [interpolation_polynomial(s)]_1 - var commitMinusInterpolation bls.G1Point - bls.SubG1(&commitMinusInterpolation, commitment, is1) + var commitMinusInterpolation bn254.G1Affine + commitMinusInterpolation.Sub(commitment, &is1) // Verify the pairing equation // @@ -269,7 +280,7 @@ func VerifyFrame(f *encoding.Frame, ks *kzg.KZGSettings, commitment *bls.G1Point // e([commitment - interpolation_polynomial]^(-1), [1]) * e([proof], [s^n - x^n]) = 1_T // - return bls.PairingsVerify(&commitMinusInterpolation, &bls.GenG2, &f.Proof, &xnMinusYn) + return PairingsVerify(&commitMinusInterpolation, &kzg.GenG2, &f.Proof, &xnMinusYn) } // Decode takes in the chunks, indices, and encoding parameters and returns the decoded blob @@ -296,3 +307,21 @@ func toUint64Array(chunkIndices []encoding.ChunkNumber) []uint64 { } return res } + +func PairingsVerify(a1 *bn254.G1Affine, a2 *bn254.G2Affine, b1 *bn254.G1Affine, b2 *bn254.G2Affine) error { + var negB1 bn254.G1Affine + negB1.Neg(b1) + + P := [2]bn254.G1Affine{*a1, negB1} + Q := [2]bn254.G2Affine{*a2, *b2} + + ok, err := bn254.PairingCheck(P[:], Q[:]) + if err != nil { + return err + } + if !ok { + return fmt.Errorf("PairingCheck pairing not ok. SRS is invalid") + } + + return nil +} diff --git a/encoding/kzgrs/verifier/verifier_test.go b/encoding/kzg/verifier/verifier_test.go similarity index 95% rename from encoding/kzgrs/verifier/verifier_test.go rename to encoding/kzg/verifier/verifier_test.go index 5a82cfacb5..8c82832058 100644 --- a/encoding/kzgrs/verifier/verifier_test.go +++ b/encoding/kzg/verifier/verifier_test.go @@ -9,9 +9,9 @@ import ( "testing" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/stretchr/testify/assert" ) @@ -21,7 +21,7 @@ const ( var ( GETTYSBURG_ADDRESS_BYTES = []byte("Fourscore and seven years ago our fathers brought forth, on this continent, a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived, and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting-place for those who here gave their lives, that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we cannot dedicate, we cannot consecrate—we cannot hallow—this ground. The brave men, living and dead, who struggled here, have consecrated it far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us—that from these honored dead we take increased devotion to that cause for which they here gave the last full measure of devotion—that we here highly resolve that these dead shall not have died in vain—that this nation, under God, shall have a new birth of freedom, and that government of the people, by the people, for the people, shall not perish from the earth.") - kzgConfig *kzgrs.KzgConfig + kzgConfig *kzg.KzgConfig numNode uint64 numSys uint64 numPar uint64 @@ -30,7 +30,7 @@ var ( func setupSuite(t *testing.T) func(t *testing.T) { log.Println("Setting up suite") - kzgConfig = &kzgrs.KzgConfig{ + kzgConfig = &kzg.KzgConfig{ G1Path: "../../../inabox/resources/kzg/g1.point", G2Path: "../../../inabox/resources/kzg/g2.point", G2PowerOf2Path: "../../../inabox/resources/kzg/g2.point.powerOf2", diff --git a/encoding/params.go b/encoding/params.go index 6697aed70b..6b6a216f16 100644 --- a/encoding/params.go +++ b/encoding/params.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" "golang.org/x/exp/constraints" ) @@ -48,14 +47,14 @@ func ParamsFromMins[T constraints.Integer](minChunkLength, minNumChunks T) Encod func ParamsFromSysPar(numSys, numPar, dataSize uint64) EncodingParams { numNodes := numSys + numPar - dataLen := roundUpDivide(dataSize, bls.BYTES_PER_COEFFICIENT) + dataLen := roundUpDivide(dataSize, BYTES_PER_COEFFICIENT) chunkLen := roundUpDivide(dataLen, numSys) return ParamsFromMins(chunkLen, numNodes) } func GetNumSys(dataSize uint64, chunkLen uint64) uint64 { - dataLen := roundUpDivide(dataSize, bls.BYTES_PER_COEFFICIENT) + dataLen := roundUpDivide(dataSize, BYTES_PER_COEFFICIENT) numSys := dataLen / chunkLen return numSys } diff --git a/encoding/rs/decode.go b/encoding/rs/decode.go index 55484277cf..6bb67be3e6 100644 --- a/encoding/rs/decode.go +++ b/encoding/rs/decode.go @@ -4,7 +4,8 @@ import ( "errors" "github.com/Layr-Labs/eigenda/encoding" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) // Decode data when some chunks from systematic nodes are lost. It first uses FFT to recover @@ -23,7 +24,7 @@ func (g *Encoder) Decode(frames []Frame, indices []uint64, maxInputSize uint64) return nil, errors.New("number of frame must be sufficient") } - samples := make([]*bls.Fr, g.NumEvaluations()) + samples := make([]*fr.Element, g.NumEvaluations()) // copy evals based on frame coeffs into samples for i, d := range indices { f := frames[i] @@ -40,12 +41,13 @@ func (g *Encoder) Decode(frames []Frame, indices []uint64, maxInputSize uint64) // Some pattern i butterfly swap. Find the leading coset, then increment by number of coset for j := uint64(0); j < g.ChunkLength; j++ { p := j*g.NumChunks + uint64(e) - samples[p] = new(bls.Fr) - bls.CopyFr(samples[p], &evals[j]) + samples[p] = new(fr.Element) + + samples[p].Set(&evals[j]) } } - reconstructedData := make([]bls.Fr, g.NumEvaluations()) + reconstructedData := make([]fr.Element, g.NumEvaluations()) missingIndices := false for i, s := range samples { if s == nil { diff --git a/encoding/rs/encode.go b/encoding/rs/encode.go index d9d013f4af..68bf2438bd 100644 --- a/encoding/rs/encode.go +++ b/encoding/rs/encode.go @@ -5,13 +5,15 @@ import ( "log" "time" + "github.com/Layr-Labs/eigenda/encoding" rb "github.com/Layr-Labs/eigenda/encoding/utils/reverseBits" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) type GlobalPoly struct { - Coeffs []bls.Fr - Values []bls.Fr + Coeffs []fr.Element + Values []fr.Element } // just a wrapper to take bytes not Fr Element @@ -27,7 +29,7 @@ func (g *Encoder) EncodeBytes(inputBytes []byte) (*GlobalPoly, []Frame, []uint32 // frame, the multireveal interpolating coefficients are identical to the part of input bytes // in the form of field element. The extra returned integer list corresponds to which leading // coset root of unity, the frame is proving against, which can be deduced from a frame's index -func (g *Encoder) Encode(inputFr []bls.Fr) (*GlobalPoly, []Frame, []uint32, error) { +func (g *Encoder) Encode(inputFr []fr.Element) (*GlobalPoly, []Frame, []uint32, error) { start := time.Now() intermediate := time.Now() @@ -55,7 +57,7 @@ func (g *Encoder) Encode(inputFr []bls.Fr) (*GlobalPoly, []Frame, []uint32, erro } log.Printf(" SUMMARY: Encode %v byte among %v numNode takes %v\n", - len(inputFr)*bls.BYTES_PER_COEFFICIENT, g.NumChunks, time.Since(start)) + len(inputFr)*encoding.BYTES_PER_COEFFICIENT, g.NumChunks, time.Since(start)) return poly, frames, indices, nil } @@ -63,7 +65,7 @@ func (g *Encoder) Encode(inputFr []bls.Fr) (*GlobalPoly, []Frame, []uint32, erro // This Function takes extended evaluation data and bundles relevant information into Frame. // Every frame is verifiable to the commitment. func (g *Encoder) MakeFrames( - polyEvals []bls.Fr, + polyEvals []fr.Element, ) ([]Frame, []uint32, error) { // reverse dataFr making easier to sample points err := rb.ReverseBitOrderFr(polyEvals) @@ -104,18 +106,18 @@ func (g *Encoder) MakeFrames( } // Encoding Reed Solomon using FFT -func (g *Encoder) ExtendPolyEval(coeffs []bls.Fr) ([]bls.Fr, []bls.Fr, error) { +func (g *Encoder) ExtendPolyEval(coeffs []fr.Element) ([]fr.Element, []fr.Element, error) { if len(coeffs) > int(g.NumEvaluations()) { return nil, nil, fmt.Errorf("the provided encoding parameters are not sufficient for the size of the data input") } - pdCoeffs := make([]bls.Fr, g.NumEvaluations()) + pdCoeffs := make([]fr.Element, g.NumEvaluations()) for i := 0; i < len(coeffs); i++ { - bls.CopyFr(&pdCoeffs[i], &coeffs[i]) + pdCoeffs[i].Set(&coeffs[i]) } for i := len(coeffs); i < len(pdCoeffs); i++ { - bls.CopyFr(&pdCoeffs[i], &bls.ZERO) + pdCoeffs[i].SetZero() } evals, err := g.Fs.FFT(pdCoeffs, false) diff --git a/encoding/rs/encoder.go b/encoding/rs/encoder.go index dd52447f24..3d6a4346e9 100644 --- a/encoding/rs/encoder.go +++ b/encoding/rs/encoder.go @@ -4,13 +4,13 @@ import ( "math" "github.com/Layr-Labs/eigenda/encoding" - kzg "github.com/Layr-Labs/eigenda/pkg/kzg" + "github.com/Layr-Labs/eigenda/encoding/fft" ) type Encoder struct { encoding.EncodingParams - Fs *kzg.FFTSettings + Fs *fft.FFTSettings verbose bool } @@ -31,7 +31,7 @@ func NewEncoder(params encoding.EncodingParams, verbose bool) (*Encoder, error) } n := uint8(math.Log2(float64(params.NumEvaluations()))) - fs := kzg.NewFFTSettings(n) + fs := fft.NewFFTSettings(n) return &Encoder{ EncodingParams: params, diff --git a/encoding/rs/encoder_suite_test.go b/encoding/rs/encoder_suite_test.go index 16fdac6fa2..a385b2a2a4 100644 --- a/encoding/rs/encoder_suite_test.go +++ b/encoding/rs/encoder_suite_test.go @@ -30,7 +30,6 @@ func setupSuite(t *testing.T) func(t *testing.T) { return func(t *testing.T) { log.Println("Tearing down suite") - // Some test may want to create a new SRS table so this should clean it up. os.RemoveAll("./data") } } diff --git a/encoding/rs/frame.go b/encoding/rs/frame.go index 05b7aff1e5..4b4ba0bed0 100644 --- a/encoding/rs/frame.go +++ b/encoding/rs/frame.go @@ -4,13 +4,13 @@ import ( "bytes" "encoding/gob" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) // Proof is the multireveal proof // Coeffs is identical to input data converted into Fr element type Frame struct { - Coeffs []bls.Fr + Coeffs []fr.Element } func (f *Frame) Encode() ([]byte, error) { diff --git a/encoding/rs/interpolation.go b/encoding/rs/interpolation.go index 1dda2d632c..5aa062edb7 100644 --- a/encoding/rs/interpolation.go +++ b/encoding/rs/interpolation.go @@ -1,7 +1,7 @@ package rs import ( - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) // Consider input data as the polynomial Coefficients, c @@ -17,12 +17,12 @@ import ( // Data. i.e. [o_1, o_2, o_3..] with coding ratio 0.5 becomes [o_1, p_1, o_2, p_2...] func (g *Encoder) GetInterpolationPolyEval( - interpolationPoly []bls.Fr, + interpolationPoly []fr.Element, j uint32, -) ([]bls.Fr, error) { - evals := make([]bls.Fr, g.ChunkLength) +) ([]fr.Element, error) { + evals := make([]fr.Element, g.ChunkLength) w := g.Fs.ExpandedRootsOfUnity[uint64(j)] - shiftedInterpolationPoly := make([]bls.Fr, len(interpolationPoly)) + shiftedInterpolationPoly := make([]fr.Element, len(interpolationPoly)) //multiply each term of the polynomial by x^i so the fourier transform results in the desired evaluations //The fourier matrix looks like @@ -49,14 +49,14 @@ func (g *Encoder) GetInterpolationPolyEval( // // to get our desired evaluations // cool idea protolambda :) - var wPow bls.Fr - bls.CopyFr(&wPow, &bls.ONE) - var tmp, tmp2 bls.Fr + var wPow fr.Element + wPow.SetOne() + //var tmp, tmp2 fr.Element for i := 0; i < len(interpolationPoly); i++ { - bls.MulModFr(&tmp2, &interpolationPoly[i], &wPow) - bls.CopyFr(&shiftedInterpolationPoly[i], &tmp2) - bls.MulModFr(&tmp, &wPow, &w) - bls.CopyFr(&wPow, &tmp) + shiftedInterpolationPoly[i].Mul(&interpolationPoly[i], &wPow) + + wPow.Mul(&wPow, &w) + } err := g.Fs.InplaceFFT(shiftedInterpolationPoly, evals, false) @@ -64,23 +64,28 @@ func (g *Encoder) GetInterpolationPolyEval( } // Since both F W are invertible, c = W^-1 F^-1 d, convert it back. F W W^-1 F^-1 d = c -func (g *Encoder) GetInterpolationPolyCoeff(chunk []bls.Fr, k uint32) ([]bls.Fr, error) { - coeffs := make([]bls.Fr, g.ChunkLength) +func (g *Encoder) GetInterpolationPolyCoeff(chunk []fr.Element, k uint32) ([]fr.Element, error) { + coeffs := make([]fr.Element, g.ChunkLength) w := g.Fs.ExpandedRootsOfUnity[uint64(k)] - shiftedInterpolationPoly := make([]bls.Fr, len(chunk)) + shiftedInterpolationPoly := make([]fr.Element, len(chunk)) err := g.Fs.InplaceFFT(chunk, shiftedInterpolationPoly, true) if err != nil { return coeffs, err } - var wPow bls.Fr - bls.CopyFr(&wPow, &bls.ONE) - var tmp, tmp2 bls.Fr + var wPow fr.Element + wPow.SetOne() + + var tmp, tmp2 fr.Element for i := 0; i < len(chunk); i++ { - bls.InvModFr(&tmp, &wPow) - bls.MulModFr(&tmp2, &shiftedInterpolationPoly[i], &tmp) - bls.CopyFr(&coeffs[i], &tmp2) - bls.MulModFr(&tmp, &wPow, &w) - bls.CopyFr(&wPow, &tmp) + tmp.Inverse(&wPow) + + tmp2.Mul(&shiftedInterpolationPoly[i], &tmp) + + coeffs[i].Set(&tmp2) + + tmp.Mul(&wPow, &w) + + wPow.Set(&tmp) } return coeffs, nil } diff --git a/encoding/rs/params.go b/encoding/rs/params.go index d3917e19a8..8403bd1e3e 100644 --- a/encoding/rs/params.go +++ b/encoding/rs/params.go @@ -3,7 +3,7 @@ package rs import ( "errors" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/Layr-Labs/eigenda/encoding" ) var ( @@ -37,7 +37,7 @@ func (p EncodingParams) Validate() error { } func GetNumSys(dataSize uint64, chunkLen uint64) uint64 { - dataLen := RoundUpDivision(dataSize, bls.BYTES_PER_COEFFICIENT) + dataLen := RoundUpDivision(dataSize, encoding.BYTES_PER_COEFFICIENT) numSys := dataLen / chunkLen return numSys } @@ -57,7 +57,7 @@ func ParamsFromMins(numChunks, chunkLen uint64) EncodingParams { func GetEncodingParams(numSys, numPar, dataSize uint64) EncodingParams { numNodes := numSys + numPar - dataLen := RoundUpDivision(dataSize, bls.BYTES_PER_COEFFICIENT) + dataLen := RoundUpDivision(dataSize, encoding.BYTES_PER_COEFFICIENT) chunkLen := RoundUpDivision(dataLen, numSys) return ParamsFromMins(numNodes, chunkLen) diff --git a/encoding/rs/utils.go b/encoding/rs/utils.go index 5d0306961d..8430df93a4 100644 --- a/encoding/rs/utils.go +++ b/encoding/rs/utils.go @@ -4,25 +4,27 @@ import ( "errors" "math" + "github.com/Layr-Labs/eigenda/encoding" rb "github.com/Layr-Labs/eigenda/encoding/utils/reverseBits" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) -func ToFrArray(data []byte) []bls.Fr { +func ToFrArray(data []byte) []fr.Element { //numEle := int(math.Ceil(float64(len(data)) / float64(BYTES_PER_COEFFICIENT))) - numEle := GetNumElement(uint64(len(data)), bls.BYTES_PER_COEFFICIENT) - eles := make([]bls.Fr, numEle) + numEle := GetNumElement(uint64(len(data)), encoding.BYTES_PER_COEFFICIENT) + eles := make([]fr.Element, numEle) for i := uint64(0); i < numEle; i++ { - start := i * uint64(bls.BYTES_PER_COEFFICIENT) - end := (i + 1) * uint64(bls.BYTES_PER_COEFFICIENT) + start := i * uint64(encoding.BYTES_PER_COEFFICIENT) + end := (i + 1) * uint64(encoding.BYTES_PER_COEFFICIENT) if end >= uint64(len(data)) { var padded [31]byte copy(padded[:], data[start:]) - bls.FrSetBytes(&eles[i], padded[:]) + eles[i].SetBytes(padded[:]) + } else { - bls.FrSetBytes(&eles[i], data[start:end]) + eles[i].SetBytes(data[start:end]) } } @@ -30,18 +32,18 @@ func ToFrArray(data []byte) []bls.Fr { } // ToByteArray converts a list of Fr to a byte array -func ToByteArray(dataFr []bls.Fr, maxDataSize uint64) []byte { +func ToByteArray(dataFr []fr.Element, maxDataSize uint64) []byte { n := len(dataFr) dataSize := int(math.Min( - float64(n*bls.BYTES_PER_COEFFICIENT), + float64(n*encoding.BYTES_PER_COEFFICIENT), float64(maxDataSize), )) data := make([]byte, dataSize) for i := 0; i < n; i++ { - v := bls.FrToBytes(&dataFr[i]) + v := dataFr[i].Bytes() - start := i * bls.BYTES_PER_COEFFICIENT - end := (i + 1) * bls.BYTES_PER_COEFFICIENT + start := i * encoding.BYTES_PER_COEFFICIENT + end := (i + 1) * encoding.BYTES_PER_COEFFICIENT if uint64(end) > maxDataSize { copy(data[start:maxDataSize], v[1:]) diff --git a/encoding/test/main.go b/encoding/test/main.go index 0a6e5c5b77..4dcc054ea2 100644 --- a/encoding/test/main.go +++ b/encoding/test/main.go @@ -3,18 +3,18 @@ package main import ( "fmt" "log" - "math" "math/rand" "runtime" "time" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/Layr-Labs/eigenda/encoding/rs" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) func main() { @@ -27,7 +27,7 @@ func main() { } func readpoints() { - kzgConfig := &kzgrs.KzgConfig{ + kzgConfig := &kzg.KzgConfig{ G1Path: "../../inabox/resources/kzg/g1.point", G2Path: "../../inabox/resources/kzg/g2.point", CacheDir: "SRSTables", @@ -40,9 +40,10 @@ func readpoints() { kzgGroup, _ := prover.NewProver(kzgConfig, true) fmt.Println("there are ", len(kzgGroup.Srs.G1), "points") for i := 0; i < len(kzgGroup.Srs.G1); i++ { - fmt.Printf("%v %v\n", i, string(kzgGroup.Srs.G1[i].MarshalText())) + + fmt.Printf("%v %v\n", i, string(kzgGroup.Srs.G1[i].String())) } - if kzgGroup.Srs.G1[0].X == bls.GenG1.X && kzgGroup.Srs.G1[0].Y == bls.GenG1.Y { + if kzgGroup.Srs.G1[0].X == kzg.GenG1.X && kzgGroup.Srs.G1[0].Y == kzg.GenG1.Y { fmt.Println("start with gen") } } @@ -59,7 +60,7 @@ func TestKzgRs() { fmt.Printf(" Num Par: %v\n", numPar) //fmt.Printf(" Data size(byte): %v\n", len(inputBytes)) - kzgConfig := &kzgrs.KzgConfig{ + kzgConfig := &kzg.KzgConfig{ G1Path: "g1.point", G2Path: "g2.point", CacheDir: "SRSTables", @@ -74,11 +75,11 @@ func TestKzgRs() { params := encoding.EncodingParams{NumChunks: 200, ChunkLength: 180} enc, _ := p.GetKzgEncoder(params) - //inputFr := kzgrs.ToFrArray(inputBytes) + //inputFr := kzg.ToFrArray(inputBytes) inputSize := uint64(numSymbols) - inputFr := make([]bls.Fr, inputSize) + inputFr := make([]fr.Element, inputSize) for i := uint64(0); i < inputSize; i++ { - bls.AsFr(&inputFr[i], i+1) + inputFr[i].SetInt64(int64(i + 1)) } fmt.Printf("Input \n") @@ -111,12 +112,12 @@ func TestKzgRs() { fmt.Printf("frame %v leading coset %v\n", i, j) lc := enc.Fs.ExpandedRootsOfUnity[uint64(j)] - g2Atn, err := kzgrs.ReadG2Point(uint64(len(f.Coeffs)), kzgConfig) + g2Atn, err := kzg.ReadG2Point(uint64(len(f.Coeffs)), kzgConfig) if err != nil { log.Fatalf("Load g2 %v failed\n", err) } - ok := verifier.VerifyFrame(&f, enc.Ks, commit, &lc, &g2Atn) - if !ok { + err = verifier.VerifyFrame(&f, enc.Ks, commit, &lc, &g2Atn) + if err != nil { log.Fatalf("Proof %v failed\n", i) } } @@ -134,14 +135,14 @@ func TestKzgRs() { } //printFr(dataFr) - //dataFr, err := kzgrs.DecodeSys(samples, indices, inputSize) + //dataFr, err := kzg.DecodeSys(samples, indices, inputSize) //if err != nil { //log.Fatalf("%v", err) //} fmt.Println(dataFr) // printFr(dataFr) - //deData := kzgrs.ToByteArray(dataFr, inputByteSize) + //deData := kzg.ToByteArray(dataFr, inputByteSize) //fmt.Println("dataFr") // printFr(dataFr) //fmt.Println(deData) @@ -153,15 +154,15 @@ func TestKzgRs() { //_ = deData } -// func getData(inputSize uint64) []bls.Fr { -// inputFr := make([]bls.Fr, inputSize) +// func getData(inputSize uint64) []fr.Element { +// inputFr := make([]fr.Element, inputSize) // for i := uint64(0); i < inputSize; i++ { // bls.AsFr(&inputFr[i], i+1) // } // return inputFr // } // -// func compareData(inputFr, dataFr []bls.Fr) { +// func compareData(inputFr, dataFr []fr.Element) { // if len(inputFr) != len(dataFr) { // log.Fatalf("Error. Diff length. input %v, data %v\n", len(inputFr), len(dataFr)) // } @@ -187,7 +188,7 @@ func TestKzgRs() { // } // } // -// func initPoly(size int) ([]bls.Fr, []bls.Fr) { +// func initPoly(size int) ([]fr.Element, []fr.Element) { // v := make([]uint64, size) // for i := 0; i < size; i++ { // v[i] = uint64(i + 1) @@ -198,13 +199,13 @@ func TestKzgRs() { // return polyFr, dataFr // } // -// func initData(size uint64) ([]bls.Fr, []bls.Fr) { +// func initData(size uint64) ([]fr.Element, []fr.Element) { // v := make([]uint64, size) // for i := uint64(0); i < size; i++ { // v[i] = uint64(i + 1) // } // dataFr := makeFr(v) -// order := kzgrs.CeilIntPowerOf2Num(size) +// order := kzg.CeilIntPowerOf2Num(size) // fs := kzg.NewFFTSettings(uint8(order)) // polyFr, err := fs.FFT(dataFr, true) // if err != nil { @@ -213,22 +214,22 @@ func TestKzgRs() { // return polyFr, dataFr // } // -// func makeFr(input []uint64) []bls.Fr { -// inputFr := make([]bls.Fr, len(input)) +// func makeFr(input []uint64) []fr.Element { +// inputFr := make([]fr.Element, len(input)) // for i := 0; i < len(input); i++ { // bls.AsFr(&inputFr[i], input[i]) // } // return inputFr // } -func printFr(d []bls.Fr) { +func printFr(d []fr.Element) { for _, e := range d { fmt.Printf("%v ", e.String()) } fmt.Printf("\n") } -// func printG1(d []bls.G1Point) { +// func printG1(d []bn254.G1Affine) { // for i, e := range d { // fmt.Printf("%v: %v \n", i, e.String()) // } @@ -247,20 +248,3 @@ func SampleFrames(frames []encoding.Frame, num uint64) ([]encoding.Frame, []uint } return samples, frameIndices } - -func RoundUpDivision(a, b uint64) uint64 { - if b == 0 { - log.Fatal("Cannot divide 0") - } - return uint64(math.Ceil(float64(a) / float64(b))) -} - -// func genText(M uint64) []byte { -// signal := make([]byte, M) -// rand.Seed(time.Now().UnixNano()) -// for i := uint64(0); i < M; i++ { -// r := rand.Intn(128) -// signal[i] = byte(r) -// } -// return signal -// } diff --git a/encoding/test/testCrypto.go b/encoding/test/testCrypto.go index 403deb3b2e..a40eba803c 100644 --- a/encoding/test/testCrypto.go +++ b/encoding/test/testCrypto.go @@ -130,57 +130,4 @@ func Verify(commitment *gkzg.Digest, proof *gkzg.OpeningProof, point fr.Element, } return nil -} - -// func newKZGSRS(kzgSize uint64) (*gkzg.SRS, error) { -// alpha, err := new(big.Int).SetString("1927409816240961209460912649125", 10) -// if !err { -// log.Fatal(err) -// } -// return gkzg.NewSRS(kzgSize, alpha) -// } -// -// func testBnFr() { -// -// a := [4]uint64{0, 1, 2, 3} -// aFr := makeBnFr(a[:]) -// fmt.Println("BnFr") -// printBnFr(aFr) -// -// diff := make([]bnl.Fr, 4) -// -// for i := 0; i < 4; i++ { -// a := aFr[i] -// var b bnl.Fr -// bnl.CopyFr(&a, &b) -// -// bnl.SubModFr(&diff[i], &a, &b) -// } -// fmt.Println("diff") -// printBnFr(diff) -// } - -// func makeBnFr(input []uint64) []bnl.Fr { -// inputFr := make([]bnl.Fr, len(input)) -// for i := 0; i < len(input); i++ { -// bnl.AsFr(&inputFr[i], input[i]) -// } -// return inputFr -// } -// -// func printBnFr(d []bnl.Fr) { -// for _, e := range d { -// fmt.Printf("%v ", e.String()) -// } -// fmt.Printf("\n") -// } -// -// func genText(M uint64) []byte { -// signal := make([]byte, M) -// rand.Seed(time.Now().UnixNano()) -// for i := uint64(0); i < M; i++ { -// r := rand.Intn(128) -// signal[i] = byte(r) -// } -// return signal -// } +} \ No newline at end of file diff --git a/encoding/test/testKzgBn254.go b/encoding/test/testKzgBn254.go index 115ca56b56..c98dabe651 100644 --- a/encoding/test/testKzgBn254.go +++ b/encoding/test/testKzgBn254.go @@ -3,8 +3,8 @@ package main // "fmt" // "log" // "math" -// bn "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" -// bnKzg "github.com/Layr-Labs/eigenda/pkg/kzgFFT/go-kzg-bn254" +// bn "github.com/Layr-Labs/eigenda/encoding/kzg/bn254" +// bnKzg "github.com/Layr-Labs/eigenda/encoding/kzgFFT/go-kzg-bn254" //func testLinComb() { //polyFr := GenPoly(1,2,3,4,5) diff --git a/encoding/utils.go b/encoding/utils.go index d25e42bdbc..48fc68fcbf 100644 --- a/encoding/utils.go +++ b/encoding/utils.go @@ -4,19 +4,17 @@ import ( "golang.org/x/exp/constraints" "math" - - "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" ) // GetBlobLength converts from blob size in bytes to blob size in symbols func GetBlobLength(blobSize uint) uint { - symSize := uint(bn254.BYTES_PER_COEFFICIENT) + symSize := uint(BYTES_PER_COEFFICIENT) return (blobSize + symSize - 1) / symSize } // GetBlobSize converts from blob length in symbols to blob size in bytes. This is not an exact conversion. func GetBlobSize(blobLength uint) uint { - return blobLength * bn254.BYTES_PER_COEFFICIENT + return blobLength * BYTES_PER_COEFFICIENT } // GetBlobLength converts from blob size in bytes to blob size in symbols @@ -29,15 +27,6 @@ func NextPowerOf2(d uint64) uint64 { return uint64(math.Pow(2.0, nextPower)) } -// func roundUpDivideBig(a, b *big.Int) *big.Int { - -// one := new(big.Int).SetUint64(1) -// num := new(big.Int).Sub(new(big.Int).Add(a, b), one) // a + b - 1 -// res := new(big.Int).Div(num, b) // (a + b - 1) / b -// return res - -// } - func roundUpDivide[T constraints.Integer](a, b T) T { return (a + b - 1) / b diff --git a/encoding/utils/reverseBits/reverseBits.go b/encoding/utils/reverseBits/reverseBits.go index 25da11260b..d08d1bf1f6 100644 --- a/encoding/utils/reverseBits/reverseBits.go +++ b/encoding/utils/reverseBits/reverseBits.go @@ -5,7 +5,8 @@ package reverseBits import ( "errors" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) const ( @@ -116,21 +117,24 @@ func ReverseBitOrder(length uint32, swap func(i, j uint32)) error { } // rearrange Fr elements in reverse bit order. Supports 2**31 max element count. -func ReverseBitOrderFr(values []bls.Fr) error { +func ReverseBitOrderFr(values []fr.Element) error { if len(values) > (1 << 31) { return ErrFrRBOListTooLarge } - var tmp bls.Fr + var tmp fr.Element err := ReverseBitOrder(uint32(len(values)), func(i, j uint32) { - bls.CopyFr(&tmp, &values[i]) - bls.CopyFr(&values[i], &values[j]) - bls.CopyFr(&values[j], &tmp) + tmp.Set(&values[i]) + + values[i].Set(&values[j]) + + values[j].Set(&tmp) + }) return err } // rearrange Fr ptr elements in reverse bit order. Supports 2**31 max element count. -func ReverseBitOrderFrPtr(values []*bls.Fr) error { +func ReverseBitOrderFrPtr(values []*fr.Element) error { if len(values) > (1 << 31) { return ErrFrRBOListTooLarge } @@ -140,15 +144,16 @@ func ReverseBitOrderFrPtr(values []*bls.Fr) error { return err } -func ReverseBitOrderG1Point(values []bls.G1Point) error { +func ReverseBitOrderG1Point(values []bn254.G1Affine) error { if len(values) > (1 << 31) { return ErrG1RBOListTooLarge } - var tmp bls.G1Point + var tmp bn254.G1Affine err := ReverseBitOrder(uint32(len(values)), func(i, j uint32) { - bls.CopyG1(&tmp, &values[i]) - bls.CopyG1(&values[i], &values[j]) - bls.CopyG1(&values[j], &tmp) + tmp.Set(&values[i]) + values[i].Set(&values[j]) + values[j].Set(&tmp) + }) return err } diff --git a/encoding/utils/toeplitz/cir.go b/encoding/utils/toeplitz/cir.go index 2a78bb8c3d..639ea66ca1 100644 --- a/encoding/utils/toeplitz/cir.go +++ b/encoding/utils/toeplitz/cir.go @@ -3,16 +3,16 @@ package toeplitz import ( "errors" - kzg "github.com/Layr-Labs/eigenda/pkg/kzg" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/Layr-Labs/eigenda/encoding/fft" + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) type Circular struct { - V []bls.Fr - Fs *kzg.FFTSettings + V []fr.Element + Fs *fft.FFTSettings } -func NewCircular(v []bls.Fr, fs *kzg.FFTSettings) *Circular { +func NewCircular(v []fr.Element, fs *fft.FFTSettings) *Circular { return &Circular{ V: v, Fs: fs, @@ -20,13 +20,13 @@ func NewCircular(v []bls.Fr, fs *kzg.FFTSettings) *Circular { } // Matrix multiplication between a circular matrix and a vector using FFT -func (c *Circular) Multiply(x []bls.Fr) ([]bls.Fr, error) { +func (c *Circular) Multiply(x []fr.Element) ([]fr.Element, error) { if len(x) != len(c.V) { return nil, errors.New("dimension inconsistent") } n := len(x) - colV := make([]bls.Fr, n) + colV := make([]fr.Element, n) for i := 0; i < n; i++ { colV[i] = c.V[(n-i)%n] } @@ -39,7 +39,7 @@ func (c *Circular) Multiply(x []bls.Fr) ([]bls.Fr, error) { if err != nil { return nil, err } - u := make([]bls.Fr, n) + u := make([]fr.Element, n) err = Hadamard(y, v, u) if err != nil { return nil, err @@ -52,49 +52,11 @@ func (c *Circular) Multiply(x []bls.Fr) ([]bls.Fr, error) { return r, nil } -// Matrix Multiplication between a circular matrix of Fr element, -// and a vector of G1 points being supplied in the argument. This method uses FFT to -// compute matrix multiplication. On the optimization side, the -// function allows for using precomputed FFT as its input. -func (c *Circular) MultiplyPoints(x []bls.G1Point, inv bool, usePrecompute bool) ([]bls.G1Point, error) { - if len(x) != len(c.V) { - return nil, errors.New("dimension inconsistent. Input != vector") - } - n := len(x) - - colV := make([]bls.Fr, n) - for i := 0; i < n; i++ { - colV[i] = c.V[(n-i)%n] - } - - y := x - - v, err := c.Fs.FFT(colV, false) - if err != nil { - return nil, err - } - u := make([]bls.G1Point, n) - err = HadamardPoints(y, v, u) - if err != nil { - return nil, err - } - - if inv { - r, err := c.Fs.FFTG1(u, true) - if err != nil { - return nil, err - } - return r, nil - } else { - return u, nil - } -} - // Taking FFT on the circular matrix vector -func (c *Circular) GetFFTCoeff() ([]bls.Fr, error) { +func (c *Circular) GetFFTCoeff() ([]fr.Element, error) { n := len(c.V) - colV := make([]bls.Fr, n) + colV := make([]fr.Element, n) for i := 0; i < n; i++ { colV[i] = c.V[(n-i)%n] } @@ -106,46 +68,25 @@ func (c *Circular) GetFFTCoeff() ([]bls.Fr, error) { return out, nil } -// Hadamard product between 2 vectors, one contains G1 points, the other contains Fr element -func HadamardPoints(a []bls.G1Point, b []bls.Fr, u []bls.G1Point) error { - if len(a) != len(b) { - return errors.New("dimension inconsistent. Cannot do Hadamard Product on Points") - } +// Taking FFT on the circular matrix vector +func (c *Circular) GetCoeff() ([]fr.Element, error) { + n := len(c.V) - for i := 0; i < len(a); i++ { - bls.MulG1(&u[i], &a[i], &b[i]) + colV := make([]fr.Element, n) + for i := 0; i < n; i++ { + colV[i] = c.V[(n-i)%n] } - return nil + return colV, nil } // Hadamard product between 2 vectors containing Fr elements -func Hadamard(a, b, u []bls.Fr) error { +func Hadamard(a, b, u []fr.Element) error { if len(a) != len(b) { return errors.New("dimension inconsistent. Cannot do Hadamard Product on Fr") } for i := 0; i < len(a); i++ { - bls.MulModFr(&u[i], &a[i], &b[i]) + u[i].Mul(&a[i], &b[i]) } return nil } - -// Naive implementation of a Multiplication between a matrix and vector. -// both contains Fr elements -func (c *Circular) DirectMultiply(x []bls.Fr) []bls.Fr { - n := len(x) - - out := make([]bls.Fr, n) - for i := 0; i < n; i++ { - var sum bls.Fr - bls.CopyFr(&sum, &bls.ZERO) - for j := 0; j < n; j++ { - idx := (j - i + n) % n - var product bls.Fr - bls.MulModFr(&product, &c.V[idx], &x[j]) - bls.AddModFr(&sum, &product, &sum) - } - bls.CopyFr(&out[i], &sum) - } - return out -} diff --git a/encoding/utils/toeplitz/cir_test.go b/encoding/utils/toeplitz/cir_test.go index ff63da4ff4..48fb3363e2 100644 --- a/encoding/utils/toeplitz/cir_test.go +++ b/encoding/utils/toeplitz/cir_test.go @@ -3,20 +3,20 @@ package toeplitz_test import ( "testing" + "github.com/Layr-Labs/eigenda/encoding/fft" "github.com/Layr-Labs/eigenda/encoding/utils/toeplitz" - kzg "github.com/Layr-Labs/eigenda/pkg/kzg" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + + "github.com/consensys/gnark-crypto/ecc/bn254/fr" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestNewCircular(t *testing.T) { - v := make([]bls.Fr, 4) - v[0] = bls.ToFr("7") - v[1] = bls.ToFr("6") - v[2] = bls.ToFr("5") - v[3] = bls.ToFr("11") - fs := kzg.NewFFTSettings(4) + v := make([]fr.Element, 4) + v[0].SetInt64(int64(7)) + v[1].SetInt64(int64(6)) + v[2].SetInt64(int64(5)) + v[3].SetInt64(int64(11)) + fs := fft.NewFFTSettings(4) c := toeplitz.NewCircular(v, fs) @@ -26,134 +26,42 @@ func TestNewCircular(t *testing.T) { assert.Equal(t, v[3], c.V[3]) } -func TestMultiplyCircular(t *testing.T) { - v := make([]bls.Fr, 4) - v[0] = bls.ToFr("7") - v[1] = bls.ToFr("11") - v[2] = bls.ToFr("5") - v[3] = bls.ToFr("6") - fs := kzg.NewFFTSettings(4) - - c := toeplitz.NewCircular(v, fs) - - x := make([]bls.Fr, 4) - x[0] = bls.ToFr("1") - x[1] = bls.ToFr("2") - x[2] = bls.ToFr("3") - x[3] = bls.ToFr("4") - b, err := c.Multiply(x) - require.Nil(t, err) - - assert.Equal(t, b[0], bls.ToFr("68")) - assert.Equal(t, b[1], bls.ToFr("73")) - assert.Equal(t, b[2], bls.ToFr("82")) - assert.Equal(t, b[3], bls.ToFr("67")) - - // Assert with direct multiplication - b2 := c.DirectMultiply(x) - assert.Equal(t, b, b2) -} - func TestMultiplyCircular_InvalidDimensions(t *testing.T) { - v := make([]bls.Fr, 2) - v[0] = bls.ToFr("7") - v[1] = bls.ToFr("11") - fs := kzg.NewFFTSettings(2) + v := make([]fr.Element, 2) + v[0].SetInt64(int64(7)) + v[1].SetInt64(int64(11)) + fs := fft.NewFFTSettings(2) c := toeplitz.NewCircular(v, fs) - x := make([]bls.Fr, 4) - x[0] = bls.ToFr("1") - x[1] = bls.ToFr("2") - x[2] = bls.ToFr("3") - x[3] = bls.ToFr("4") + x := make([]fr.Element, 4) + x[0].SetInt64(int64(1)) + x[1].SetInt64(int64(2)) + x[2].SetInt64(int64(3)) + x[3].SetInt64(int64(4)) _, err := c.Multiply(x) assert.EqualError(t, err, "dimension inconsistent") } -func TestMultiplyPointsCircular(t *testing.T) { - v := make([]bls.Fr, 4) - v[0] = bls.ToFr("7") - v[1] = bls.ToFr("6") - v[2] = bls.ToFr("5") - v[3] = bls.ToFr("11") - fs := kzg.NewFFTSettings(4) - - c := toeplitz.NewCircular(v, fs) - - x := make([]bls.G1Point, 4) - x[0] = bls.GenG1 - x[1] = bls.GenG1 - x[2] = bls.GenG1 - x[3] = bls.GenG1 - - b, err := c.MultiplyPoints(x, false, true) - require.Nil(t, err) - - sum := bls.LinCombG1(x, v) - assert.Equal(t, &b[0], sum) -} - -func TestMultiplyPointsCircular_InvalidDimension(t *testing.T) { - v := make([]bls.Fr, 2) - v[0] = bls.ToFr("7") - v[1] = bls.ToFr("6") - fs := kzg.NewFFTSettings(2) - - c := toeplitz.NewCircular(v, fs) - - x := make([]bls.G1Point, 4) - x[0] = bls.GenG1 - x[1] = bls.GenG1 - x[2] = bls.GenG1 - x[3] = bls.GenG1 - - _, err := c.MultiplyPoints(x, false, true) - assert.EqualError(t, err, "dimension inconsistent. Input != vector") -} - func TestHadamard_InvalidDimension(t *testing.T) { - a := make([]bls.Fr, 2) - a[0] = bls.ToFr("1") - a[1] = bls.ToFr("2") + a := make([]fr.Element, 2) + a[0].SetInt64(int64(1)) + a[1].SetInt64(int64(2)) - b := make([]bls.Fr, 1) - b[0] = bls.ToFr("3") + b := make([]fr.Element, 1) + b[0].SetInt64(int64(3)) - c := make([]bls.Fr, 3) + c := make([]fr.Element, 3) err := toeplitz.Hadamard(a, b, c) assert.EqualError(t, err, "dimension inconsistent. Cannot do Hadamard Product on Fr") // TODO: This causes a panic because there are no checks on the size of c - // b = make([]bls.Fr, 2) - // b[0] = bls.ToFr("3") - // b[1] = bls.ToFr("4") - - // c = make([]bls.Fr, 1) - // fmt.Println(len(a), len(b), len(c)) - // err = kzgRs.Hadamard(a, b, c) - // require.Nil(t, err) -} - -func TestHadamardPoint_InvalidDimension(t *testing.T) { - a := make([]bls.G1Point, 2) - a[0] = bls.GenG1 - a[1] = bls.GenG1 - - b := make([]bls.Fr, 1) - b[0] = bls.ToFr("1") - - c := make([]bls.G1Point, 3) - err := toeplitz.HadamardPoints(a, b, c) - assert.EqualError(t, err, "dimension inconsistent. Cannot do Hadamard Product on Points") - - // TODO: This causes a panic because there are no checks on the size of c - // b = make([]bls.Fr, 2) + // b = make([]fr.Element, 2) // b[0] = bls.ToFr("3") // b[1] = bls.ToFr("4") - // c = make([]bls.Fr, 1) + // c = make([]fr.Element, 1) // fmt.Println(len(a), len(b), len(c)) - // err = kzgRs.Hadamard(a, b, c) + // err = kzg.Hadamard(a, b, c) // require.Nil(t, err) } diff --git a/encoding/utils/toeplitz/toeplitz.go b/encoding/utils/toeplitz/toeplitz.go index 6edfd63cc4..7145c3541a 100644 --- a/encoding/utils/toeplitz/toeplitz.go +++ b/encoding/utils/toeplitz/toeplitz.go @@ -3,10 +3,10 @@ package toeplitz import ( "errors" "log" - // "fmt" - kzg "github.com/Layr-Labs/eigenda/pkg/kzg" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + "github.com/Layr-Labs/eigenda/encoding/fft" + + "github.com/consensys/gnark-crypto/ecc/bn254/fr" ) // V is ordered as (v_0, .., v_6), so it creates a @@ -16,11 +16,11 @@ import ( // v_5 v_6 v_0 v_1 // v_4 v_5 v_6 v_0 type Toeplitz struct { - V []bls.Fr - Fs *kzg.FFTSettings + V []fr.Element + Fs *fft.FFTSettings } -func NewToeplitz(v []bls.Fr, fs *kzg.FFTSettings) (*Toeplitz, error) { +func NewToeplitz(v []fr.Element, fs *fft.FFTSettings) (*Toeplitz, error) { if len(v)%2 != 1 { log.Println("num diagonal vector must be odd") return nil, errors.New("num diagonal vector must be odd") @@ -35,18 +35,18 @@ func NewToeplitz(v []bls.Fr, fs *kzg.FFTSettings) (*Toeplitz, error) { // Mutliplication of a matrix and a vector, both elements are Fr Element // good info about FFT and Toeplitz, // https://alinush.github.io/2020/03/19/multiplying-a-vector-by-a-toeplitz-matrix.html -func (t *Toeplitz) Multiply(x []bls.Fr) ([]bls.Fr, error) { +func (t *Toeplitz) Multiply(x []fr.Element) ([]fr.Element, error) { cv := t.ExtendCircularVec() rv := t.FromColVToRowV(cv) cir := NewCircular(rv, t.Fs) - xE := make([]bls.Fr, len(cv)) + xE := make([]fr.Element, len(cv)) for i := 0; i < len(x); i++ { - bls.CopyFr(&xE[i], &x[i]) + xE[i].Set(&x[i]) } for i := len(x); i < len(cv); i++ { - bls.CopyFr(&xE[i], &bls.ZERO) + xE[i].SetZero() } product, err := cir.Multiply(xE) @@ -57,32 +57,24 @@ func (t *Toeplitz) Multiply(x []bls.Fr) ([]bls.Fr, error) { return product[:len(x)], nil } -// Mutliplication of a matrix and a vector, where the matrix contains Fr elements, vectors are -// G1 Points. It supports precomputed -func (t *Toeplitz) MultiplyPoints(x []bls.G1Point, inv bool, usePrecompute bool) ([]bls.G1Point, error) { +// Take FFT on Toeplitz vector, coefficient is used for computing hadamard product +// but carried with multi scalar multiplication +func (t *Toeplitz) GetFFTCoeff() ([]fr.Element, error) { cv := t.ExtendCircularVec() rv := t.FromColVToRowV(cv) cir := NewCircular(rv, t.Fs) - //for i := range x { - //fmt.Printf("%v", x[i].String()) - //} - //fmt.Println("x", len(x)) - //fmt.Println("vc", len(cv)) - - return cir.MultiplyPoints(x, inv, true) + return cir.GetFFTCoeff() } -// Take FFT on Toeplitz vector, coefficient is used for computing hadamard product -// but carried with multi scalar multiplication -func (t *Toeplitz) GetFFTCoeff() ([]bls.Fr, error) { +func (t *Toeplitz) GetCoeff() ([]fr.Element, error) { cv := t.ExtendCircularVec() rv := t.FromColVToRowV(cv) cir := NewCircular(rv, t.Fs) - return cir.GetFFTCoeff() + return cir.GetCoeff() } // Expand toeplitz matrix into circular matrix @@ -99,22 +91,22 @@ func (t *Toeplitz) GetFFTCoeff() ([]bls.Fr, error) { // [v_5, v_4, 0 , v_3, v_2, v_1, v_0, v_6 ] // [v_6, v_5, v_4, 0 , v_3, v_2, v_1, v_0 ] -func (t *Toeplitz) ExtendCircularVec() []bls.Fr { - E := make([]bls.Fr, len(t.V)+1) // extra 1 from extended, equal to 2*dimE +func (t *Toeplitz) ExtendCircularVec() []fr.Element { + E := make([]fr.Element, len(t.V)+1) // extra 1 from extended, equal to 2*dimE numRow := t.GetMatDim() - - bls.CopyFr(&E[0], &t.V[0]) + E[0].Set(&t.V[0]) for i := 1; i < numRow; i++ { - bls.CopyFr(&E[i], &t.V[len(t.V)-i]) + + E[i].Set(&t.V[len(t.V)-i]) } // assign some value to the extra dimension - bls.CopyFr(&E[numRow], &bls.ZERO) + E[numRow].SetZero() // numRow == numCol for i := 1; i < numRow; i++ { - bls.CopyFr(&E[numRow+i], &t.V[numRow-i]) + E[numRow+i].Set(&t.V[numRow-i]) } return E @@ -124,13 +116,15 @@ func (t *Toeplitz) ExtendCircularVec() []bls.Fr { // then row Vector is [v_0, v_6, v_5, v_4, 0, v_3, v_2, v_1] // this operation is involutory. i.e. f(f(v)) = v -func (t *Toeplitz) FromColVToRowV(cv []bls.Fr) []bls.Fr { +func (t *Toeplitz) FromColVToRowV(cv []fr.Element) []fr.Element { n := len(cv) - rv := make([]bls.Fr, n) - bls.CopyFr(&rv[0], &cv[0]) + rv := make([]fr.Element, n) + + rv[0].Set(&cv[0]) for i := 1; i < n; i++ { - bls.CopyFr(&rv[i], &cv[n-i]) + + rv[i].Set(&cv[n-i]) } return rv @@ -141,22 +135,26 @@ func (t *Toeplitz) GetMatDim() int { } // naive implementation for multiplication. Used for testing -func (t *Toeplitz) DirectMultiply(x []bls.Fr) []bls.Fr { +func (t *Toeplitz) DirectMultiply(x []fr.Element) []fr.Element { numCol := t.GetMatDim() n := len(t.V) - out := make([]bls.Fr, numCol) + out := make([]fr.Element, numCol) for i := 0; i < numCol; i++ { - var sum bls.Fr - bls.CopyFr(&sum, &bls.ZERO) + var sum fr.Element + sum.SetZero() + for j := 0; j < numCol; j++ { idx := (j - i + n) % n - var product bls.Fr - bls.MulModFr(&product, &t.V[idx], &x[j]) - bls.AddModFr(&sum, &product, &sum) + var product fr.Element + product.Mul(&t.V[idx], &x[j]) + + sum.Add(&product, &sum) + } - bls.CopyFr(&out[i], &sum) + + out[i].Set(&sum) } return out diff --git a/encoding/utils/toeplitz/toeplitz_test.go b/encoding/utils/toeplitz/toeplitz_test.go index 13b932d2af..3398d173b7 100644 --- a/encoding/utils/toeplitz/toeplitz_test.go +++ b/encoding/utils/toeplitz/toeplitz_test.go @@ -3,9 +3,11 @@ package toeplitz_test import ( "testing" + "github.com/Layr-Labs/eigenda/encoding" + "github.com/Layr-Labs/eigenda/encoding/fft" "github.com/Layr-Labs/eigenda/encoding/utils/toeplitz" - kzg "github.com/Layr-Labs/eigenda/pkg/kzg" - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" + + "github.com/consensys/gnark-crypto/ecc/bn254/fr" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -17,15 +19,15 @@ import ( // v_5 v_6 v_0 v_1 // v_4 v_5 v_6 v_0 func TestNewToeplitz(t *testing.T) { - v := make([]bls.Fr, 7) - v[0] = bls.ToFr("7") - v[1] = bls.ToFr("11") - v[2] = bls.ToFr("5") - v[3] = bls.ToFr("6") - v[4] = bls.ToFr("3") - v[5] = bls.ToFr("8") - v[6] = bls.ToFr("1") - fs := kzg.NewFFTSettings(4) + v := make([]fr.Element, 7) + v[0].SetInt64(int64(7)) + v[1].SetInt64(int64(11)) + v[2].SetInt64(int64(5)) + v[3].SetInt64(int64(6)) + v[4].SetInt64(int64(3)) + v[5].SetInt64(int64(8)) + v[6].SetInt64(int64(1)) + fs := fft.NewFFTSettings(4) toe, err := toeplitz.NewToeplitz(v, fs) require.Nil(t, err) @@ -39,10 +41,10 @@ func TestNewToeplitz(t *testing.T) { } func TestNewToeplitz_InvalidSize(t *testing.T) { - v := make([]bls.Fr, 2) - v[0] = bls.ToFr("4") - v[1] = bls.ToFr("2") - fs := kzg.NewFFTSettings(4) + v := make([]fr.Element, 2) + v[0].SetInt64(int64(4)) + v[1].SetInt64(int64(2)) + fs := fft.NewFFTSettings(4) _, err := toeplitz.NewToeplitz(v, fs) assert.EqualError(t, err, "num diagonal vector must be odd") @@ -53,16 +55,16 @@ func TestNewToeplitz_InvalidSize(t *testing.T) { // if V is (v_0, v_1, v_2, v_3, v_4, v_5, v_6) // then E is (v_0, v_6, v_5, v_4, 0, v_3, v_2, v_1) func TestExtendCircularVec(t *testing.T) { - v := make([]bls.Fr, 7) - v[0] = bls.ToFr("7") - v[1] = bls.ToFr("11") - v[2] = bls.ToFr("5") - v[3] = bls.ToFr("6") - v[4] = bls.ToFr("3") - v[5] = bls.ToFr("8") - v[6] = bls.ToFr("1") - - fs := kzg.NewFFTSettings(4) + v := make([]fr.Element, 7) + v[0].SetInt64(int64(7)) + v[1].SetInt64(int64(11)) + v[2].SetInt64(int64(5)) + v[3].SetInt64(int64(6)) + v[4].SetInt64(int64(3)) + v[5].SetInt64(int64(8)) + v[6].SetInt64(int64(1)) + + fs := fft.NewFFTSettings(4) c, err := toeplitz.NewToeplitz(v, fs) require.Nil(t, err) @@ -71,7 +73,7 @@ func TestExtendCircularVec(t *testing.T) { assert.Equal(t, cVec[1], v[6]) assert.Equal(t, cVec[2], v[5]) assert.Equal(t, cVec[3], v[4]) - assert.Equal(t, cVec[4], bls.ZERO) + assert.Equal(t, cVec[4], encoding.ZERO) assert.Equal(t, cVec[5], v[3]) assert.Equal(t, cVec[6], v[2]) assert.Equal(t, cVec[7], v[1]) @@ -81,16 +83,16 @@ func TestExtendCircularVec(t *testing.T) { // then row Vector is [v_0, v_6, v_5, v_4, 0, v_3, v_2, v_1] // this operation is involutory. i.e. f(f(v)) = v func TestFromColVToRowV(t *testing.T) { - v := make([]bls.Fr, 7) - v[0] = bls.ToFr("7") - v[1] = bls.ToFr("11") - v[2] = bls.ToFr("5") - v[3] = bls.ToFr("6") - v[4] = bls.ToFr("3") - v[5] = bls.ToFr("8") - v[6] = bls.ToFr("1") - - fs := kzg.NewFFTSettings(4) + v := make([]fr.Element, 7) + v[0].SetInt64(int64(7)) + v[1].SetInt64(int64(11)) + v[2].SetInt64(int64(5)) + v[3].SetInt64(int64(6)) + v[4].SetInt64(int64(3)) + v[5].SetInt64(int64(8)) + v[6].SetInt64(int64(1)) + + fs := fft.NewFFTSettings(4) c, err := toeplitz.NewToeplitz(v, fs) require.Nil(t, err) @@ -101,7 +103,7 @@ func TestFromColVToRowV(t *testing.T) { assert.Equal(t, rVec[1], v[1]) assert.Equal(t, rVec[2], v[2]) assert.Equal(t, rVec[3], v[3]) - assert.Equal(t, rVec[4], bls.ZERO) + assert.Equal(t, rVec[4], encoding.ZERO) assert.Equal(t, rVec[5], v[4]) assert.Equal(t, rVec[6], v[5]) assert.Equal(t, rVec[7], v[6]) @@ -112,83 +114,48 @@ func TestFromColVToRowV(t *testing.T) { assert.Equal(t, cVec[1], v[6]) assert.Equal(t, cVec[2], v[5]) assert.Equal(t, cVec[3], v[4]) - assert.Equal(t, cVec[4], bls.ZERO) + assert.Equal(t, cVec[4], encoding.ZERO) assert.Equal(t, cVec[5], v[3]) assert.Equal(t, cVec[6], v[2]) assert.Equal(t, cVec[7], v[1]) } func TestMultiplyToeplitz(t *testing.T) { - v := make([]bls.Fr, 7) - v[0] = bls.ToFr("7") - v[1] = bls.ToFr("11") - v[2] = bls.ToFr("5") - v[3] = bls.ToFr("6") - v[4] = bls.ToFr("3") - v[5] = bls.ToFr("8") - v[6] = bls.ToFr("1") - - fs := kzg.NewFFTSettings(4) + v := make([]fr.Element, 7) + v[0].SetInt64(int64(7)) + v[1].SetInt64(int64(11)) + v[2].SetInt64(int64(5)) + v[3].SetInt64(int64(6)) + v[4].SetInt64(int64(3)) + v[5].SetInt64(int64(8)) + v[6].SetInt64(int64(1)) + + fs := fft.NewFFTSettings(4) toe, err := toeplitz.NewToeplitz(v, fs) require.Nil(t, err) - x := make([]bls.Fr, 4) - x[0] = bls.ToFr("1") - x[1] = bls.ToFr("2") - x[2] = bls.ToFr("3") - x[3] = bls.ToFr("4") + x := make([]fr.Element, 4) + x[0].SetInt64(int64(1)) + x[1].SetInt64(int64(2)) + x[2].SetInt64(int64(3)) + x[3].SetInt64(int64(4)) b, err := toe.Multiply(x) require.Nil(t, err) - assert.Equal(t, b[0], bls.ToFr("68")) - assert.Equal(t, b[1], bls.ToFr("68")) - assert.Equal(t, b[2], bls.ToFr("75")) - assert.Equal(t, b[3], bls.ToFr("50")) + p := make([]fr.Element, 4) + p[0].SetInt64(int64(68)) + p[1].SetInt64(int64(68)) + p[2].SetInt64(int64(75)) + p[3].SetInt64(int64(50)) + + assert.Equal(t, b[0], p[0]) + assert.Equal(t, b[1], p[1]) + assert.Equal(t, b[2], p[2]) + assert.Equal(t, b[3], p[3]) // Assert with direct multiplication b2 := toe.DirectMultiply(x) assert.Equal(t, b, b2) } - -func TestMultiplyPointsToeplitz(t *testing.T) { - v := make([]bls.Fr, 7) - v[0] = bls.ToFr("7") - v[1] = bls.ToFr("11") - v[2] = bls.ToFr("5") - v[3] = bls.ToFr("6") - v[4] = bls.ToFr("3") - v[5] = bls.ToFr("8") - v[6] = bls.ToFr("1") - fs := kzg.NewFFTSettings(4) - toe, err := toeplitz.NewToeplitz(v, fs) - require.Nil(t, err) - - x := make([]bls.G1Point, 8) - x[0] = bls.GenG1 - x[1] = bls.GenG1 - x[2] = bls.GenG1 - x[3] = bls.GenG1 - x[4] = bls.GenG1 - x[5] = bls.GenG1 - x[6] = bls.GenG1 - x[7] = bls.GenG1 - - b1, err := toe.MultiplyPoints(x, false, true) - require.Nil(t, err) - - //b2, err := toe.MultiplyPoints(x, false, false) - require.Nil(t, err) - - sum := bls.LinCombG1(x[:7], toe.V) - assert.Equal(t, &b1[0], sum) - - // TODO: Calculate inverse - // b2, err := toe.MultiplyPoints(x, true, true) - // require.Nil(t, err) - - // res, err := toe.MultiplyPoints(b2, false, true) - // require.Nil(t, err) - // assert.Equal(t, res[0].X.String(), x[0].X.String()) -} diff --git a/inabox/tests/integration_suite_test.go b/inabox/tests/integration_suite_test.go index d1c9165a47..379daa7c06 100644 --- a/inabox/tests/integration_suite_test.go +++ b/inabox/tests/integration_suite_test.go @@ -18,8 +18,8 @@ import ( "github.com/Layr-Labs/eigenda/core" "github.com/Layr-Labs/eigenda/core/eth" coreindexer "github.com/Layr-Labs/eigenda/core/indexer" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/Layr-Labs/eigenda/inabox/deploy" "github.com/Layr-Labs/eigenda/indexer" gcommon "github.com/ethereum/go-ethereum/common" @@ -156,7 +156,7 @@ func setupRetrievalClient(testConfig *deploy.Config) error { if err != nil { return err } - v, err := verifier.NewVerifier(&kzgrs.KzgConfig{ + v, err := verifier.NewVerifier(&kzg.KzgConfig{ G1Path: testConfig.Retriever.RETRIEVER_G1_PATH, G2Path: testConfig.Retriever.RETRIEVER_G2_PATH, G2PowerOf2Path: testConfig.Retriever.RETRIEVER_G2_POWER_OF_2_PATH, diff --git a/node/config.go b/node/config.go index b77e676fe3..36bfc5681f 100644 --- a/node/config.go +++ b/node/config.go @@ -11,7 +11,7 @@ import ( "github.com/Layr-Labs/eigenda/common/geth" "github.com/Layr-Labs/eigenda/common/logging" "github.com/Layr-Labs/eigenda/core" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" + "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/Layr-Labs/eigenda/node/flags" "github.com/Layr-Labs/eigensdk-go/crypto/bls" "github.com/ethereum/go-ethereum/accounts/keystore" @@ -70,7 +70,7 @@ type Config struct { EthClientConfig geth.EthClientConfig LoggingConfig logging.Config - EncoderConfig kzgrs.KzgConfig + EncoderConfig kzg.KzgConfig } // NewConfig parses the Config from the provided flags or environment variables and @@ -156,7 +156,7 @@ func NewConfig(ctx *cli.Context) (*Config, error) { DbPath: ctx.GlobalString(flags.DbPathFlag.Name), PrivateBls: privateBls, EthClientConfig: ethClientConfig, - EncoderConfig: kzgrs.ReadCLIConfig(ctx), + EncoderConfig: kzg.ReadCLIConfig(ctx), LoggingConfig: logging.ReadCLIConfig(ctx, flags.FlagPrefix), BLSOperatorStateRetrieverAddr: ctx.GlobalString(flags.BlsOperatorStateRetrieverFlag.Name), EigenDAServiceManagerAddr: ctx.GlobalString(flags.EigenDAServiceManagerFlag.Name), diff --git a/node/flags/flags.go b/node/flags/flags.go index c813053b98..2d70246330 100644 --- a/node/flags/flags.go +++ b/node/flags/flags.go @@ -6,7 +6,7 @@ import ( "github.com/Layr-Labs/eigenda/common" "github.com/Layr-Labs/eigenda/common/geth" "github.com/Layr-Labs/eigenda/common/logging" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" + "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/urfave/cli" ) @@ -271,7 +271,7 @@ var optionalFlags = []cli.Flag{ func init() { Flags = append(requiredFlags, optionalFlags...) - Flags = append(Flags, kzgrs.CLIFlags(EnvVarPrefix)...) + Flags = append(Flags, kzg.CLIFlags(EnvVarPrefix)...) Flags = append(Flags, geth.EthClientFlags(EnvVarPrefix)...) Flags = append(Flags, logging.CLIFlags(EnvVarPrefix, FlagPrefix)...) } diff --git a/node/grpc/server_test.go b/node/grpc/server_test.go index b2b48d2da2..6fabce4dbb 100644 --- a/node/grpc/server_test.go +++ b/node/grpc/server_test.go @@ -16,9 +16,9 @@ import ( "github.com/Layr-Labs/eigenda/core" core_mock "github.com/Layr-Labs/eigenda/core/mock" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/Layr-Labs/eigenda/node" "github.com/Layr-Labs/eigenda/node/grpc" "github.com/Layr-Labs/eigensdk-go/metrics" @@ -46,7 +46,7 @@ func TestMain(m *testing.M) { // makeTestVerifier makes a verifier currently using the only supported backend. func makeTestComponents() (encoding.Prover, encoding.Verifier, error) { - config := &kzgrs.KzgConfig{ + config := &kzg.KzgConfig{ G1Path: "../../inabox/resources/kzg/g1.point.300000", G2Path: "../../inabox/resources/kzg/g2.point.300000", CacheDir: "../../inabox/resources/kzg/SRSTables", diff --git a/node/node.go b/node/node.go index 66105f41b6..728b06d3de 100644 --- a/node/node.go +++ b/node/node.go @@ -11,7 +11,7 @@ import ( "time" "github.com/Layr-Labs/eigenda/common/pubip" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/prometheus/client_golang/prometheus" diff --git a/node/store_test.go b/node/store_test.go index c2e746ea43..ac60ef4981 100644 --- a/node/store_test.go +++ b/node/store_test.go @@ -11,9 +11,10 @@ import ( "github.com/Layr-Labs/eigenda/common/mock" "github.com/Layr-Labs/eigenda/core" "github.com/Layr-Labs/eigenda/encoding" + "github.com/Layr-Labs/eigenda/node" - "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" "github.com/Layr-Labs/eigensdk-go/metrics" + "github.com/consensys/gnark-crypto/ecc/bn254" "github.com/consensys/gnark-crypto/ecc/bn254/fp" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/assert" @@ -42,7 +43,7 @@ func CreateBatch(t *testing.T) (*core.BatchHeader, []*core.BlobMessage, []*pb.Bl _, err = lengthYA1.SetString("4082367875863433681332203403145435568316851327593401208105741076214120093531") assert.NoError(t, err) - var lengthProof, lengthCommitment bn254.G2Point + var lengthProof, lengthCommitment bn254.G2Affine lengthProof.X.A0 = lengthXA0 lengthProof.X.A1 = lengthXA1 lengthProof.Y.A0 = lengthYA0 @@ -50,7 +51,7 @@ func CreateBatch(t *testing.T) (*core.BatchHeader, []*core.BlobMessage, []*pb.Bl lengthCommitment = lengthProof - commitment := bn254.G1Point{ + commitment := bn254.G1Affine{ X: commitX, Y: commitY, } @@ -68,7 +69,7 @@ func CreateBatch(t *testing.T) (*core.BatchHeader, []*core.BlobMessage, []*pb.Bl } chunk1 := &encoding.Frame{ Proof: commitment, - Coeffs: []encoding.Symbol{bn254.ONE}, + Coeffs: []encoding.Symbol{encoding.ONE}, } blobMessage := []*core.BlobMessage{ diff --git a/pkg/kzg/LICENSE b/pkg/kzg/LICENSE deleted file mode 100644 index a5497ea1a6..0000000000 --- a/pkg/kzg/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 @protolambda - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/pkg/kzg/README.md b/pkg/kzg/README.md deleted file mode 100644 index fbdd3c6acf..0000000000 --- a/pkg/kzg/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# KZG and FFT utils - -This repo is *super experimental*. - -This is an implementation in Go, initially aimed at chunkification and extension of data, -and building/verifying KZG proofs for the output data. -The KZG proofs, or Kate proofs, are built on top of BLS12-381. - -Part of a low-latency data-availability sampling network prototype for Eth2 Phase 1. -See https://github.com/protolambda/eth2-das - -Code is based on: -- [KZG Data availability code by Dankrad](https://github.com/ethereum/research/tree/master/kzg_data_availability) -- [Verkle and FFT code by Dankrad and Vitalik](https://github.com/ethereum/research/tree/master/verkle) -- [Reed solomon erasure code recovery with FFTs by Vitalik](https://ethresear.ch/t/reed-solomon-erasure-code-recovery-in-n-log-2-n-time-with-ffts/3039) -- [FFT explainer by Vitalik](https://vitalik.eth.limo/general/2019/05/12/fft.html) -- [Kate explainer by Dankrad](https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html) -- [Kate amortized paper by Dankrad and Dmitry](https://github.com/khovratovich/Kate/blob/master/Kate_amortized.pdf) - -Features: -- (I)FFT on `F_r` -- (I)FFT on `G1` -- Specialized FFT for extension of `F_r` data -- KZG - - commitments - - generate/verify proof for single point - - generate/verify proofs for multiple points - - generate/verify proofs for all points, using FK20 - - generate/verify proofs for ranges (cosets) of points, using FK20 -- Data recovery: given an arbitrary subset of data (at least half), recover the rest -- Optimized for Data-availability usage -- Change Bignum / BLS with build tags. - -## BLS - -Currently supported BLS implementations: Herumi BLS and Kilic BLS (default). - -## Field elements (Fr) - -The BLS curve order is used for the modulo math, different libraries could be used to provide this functionality. -Note: some of these libraries do not have full BLS functionality, only Bignum / uint256. The KZG code will be excluded when compiling with a non-BLS build tag. - -Build tag options: -- (no build tags, default): Use Kilic BLS library. Previously used by `bignum_kilic` build tag. [`kilic/bls12-381`](https://github.com/kilic/bls12-381) -- `-tags bignum_hbls`: use Herumi BLS library. [`herumi/bls-eth-go-binary`](https://github.com/herumi/bls-eth-go-binary/) -- `-tags bignum_hol256`: Use the uint256 code that Geth uses, [`holiman/uint256`](https://github.com/holiman/uint256) -- `-tags bignum_pure`: Use the native Go Bignum implementation. - - -## Benchmarks - -See [`BENCH.md`](./BENCH.md) for benchmarks of FFT, FFT in G1, FFT-extension, zero polynomials, and sample recovery. - -## License - -MIT, see [`LICENSE`](./LICENSE) file. - diff --git a/pkg/kzg/bn254/bignum_gnark.go b/pkg/kzg/bn254/bignum_gnark.go deleted file mode 100644 index 9ae6e51a7b..0000000000 --- a/pkg/kzg/bn254/bignum_gnark.go +++ /dev/null @@ -1,126 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package bn254 - -import ( - "github.com/consensys/gnark-crypto/ecc/bn254/fr" -) - -type Fr fr.Element - -func init() { - initGlobals() - ClearG1(&ZERO_G1) - ClearG2(&ZERO_G2) - initG1G2() -} - -func (fr *Fr) String() string { - return FrStr(fr) -} - -func SetFr(dst *Fr, v string) { - // Bad practice to ignore error! - _, _ = (*fr.Element)(dst).SetString(v) -} - -func FrToBytes(src *Fr) [32]byte { - return (*fr.Element)(src).Bytes() -} - -func FrSetBytes(dst *Fr, v []byte) { - (*fr.Element)(dst).SetBytes(v) -} - -func FrFrom32(dst *Fr, v [32]byte) (ok bool) { - (*fr.Element)(dst).SetBytes(v[:]) - return true -} - -func FrTo32(src *Fr) [32]byte { - return (*fr.Element)(src).Bytes() -} - -func CopyFr(dst *Fr, v *Fr) { - *dst = *v -} - -func AsFr(dst *Fr, i uint64) { - //var data [8]byte - //binary.BigEndian.PutUint64(data[:], i) - //(*kbls.Fr)(dst).SetBytes(data[:]) - (*fr.Element)(dst).SetUint64(i) -} - -func HashToSingleField(dst *Fr, msg []byte) error { - DST := []byte("-") - randomFr, err := fr.Hash(msg, DST, 1) - randomFrBytes := (randomFr[0]).Bytes() - FrSetBytes(dst, randomFrBytes[:]) - return err -} - -func FrStr(b *Fr) string { - if b == nil { - return "" - } - return (*fr.Element)(b).String() -} - -func EqualOne(v *Fr) bool { - return (*fr.Element)(v).IsOne() -} - -func EqualZero(v *Fr) bool { - return (*fr.Element)(v).IsZero() -} - -func EqualFr(a *Fr, b *Fr) bool { - return (*fr.Element)(a).Equal((*fr.Element)(b)) -} - -func SubModFr(dst *Fr, a, b *Fr) { - (*fr.Element)(dst).Sub((*fr.Element)(a), (*fr.Element)(b)) -} - -func AddModFr(dst *Fr, a, b *Fr) { - (*fr.Element)(dst).Add((*fr.Element)(a), (*fr.Element)(b)) -} - -func DivModFr(dst *Fr, a, b *Fr) { - (*fr.Element)(dst).Div((*fr.Element)(a), (*fr.Element)(b)) -} - -func MulModFr(dst *Fr, a, b *Fr) { - (*fr.Element)(dst).Mul((*fr.Element)(a), (*fr.Element)(b)) -} - -func InvModFr(dst *Fr, v *Fr) { - (*fr.Element)(dst).Inverse((*fr.Element)(v)) -} - -func EvalPolyAt(dst *Fr, p []Fr, x *Fr) { - EvalPolyAtUnoptimized(dst, p, x) -} diff --git a/pkg/kzg/bn254/bignum_gnark_test.go b/pkg/kzg/bn254/bignum_gnark_test.go deleted file mode 100644 index 100066b4e9..0000000000 --- a/pkg/kzg/bn254/bignum_gnark_test.go +++ /dev/null @@ -1,193 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -package bn254 - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestString(t *testing.T) { - two := ToFr("2") - expected := "2" - - assert.Equal(t, two.String(), expected) -} - -func TestFrToBytes(t *testing.T) { - two := ToFr("2") - b := FrToBytes(&two) - expected := [32]byte{} - expected[31] = 2 - - assert.Equal(t, b, expected) -} - -func TestFrSetBytes(t *testing.T) { - two := make([]byte, 32) - two[31] = 2 - var dst Fr - FrSetBytes(&dst, two) - expected := ToFr("2") - - assert.Equal(t, dst, expected) -} - -func TestFrFrom32(t *testing.T) { - one := [32]byte{} - one[31] = 1 - var dst Fr - FrFrom32(&dst, one) - expected := ToFr("1") - - assert.Equal(t, dst, expected) -} - -func TestFrTo32(t *testing.T) { - one := ToFr("1") - b := FrTo32(&one) - expected := [32]byte{} - expected[31] = 1 - - assert.Equal(t, b, expected) -} - -func TestCopyFrStr(t *testing.T) { - one := ToFr("1") - var dst Fr - CopyFr(&dst, &one) - - assert.Equal(t, dst, one) -} - -func TestFrStr(t *testing.T) { - s := FrStr(nil) - expected := "" - - assert.Equal(t, s, expected) - - one := ToFr("1") - s = FrStr(&one) - expected = "1" - - assert.Equal(t, s, expected) -} - -func TestEqualZero(t *testing.T) { - zero := ToFr("0") - eq := EqualZero(&zero) - - assert.True(t, eq) -} - -func TestEqualOne(t *testing.T) { - one := ToFr("1") - eq := EqualOne(&one) - - assert.True(t, eq) -} - -func TestEqualFr(t *testing.T) { - one := ToFr("1") - two := ToFr("2") - - eq := EqualFr(&one, &two) - assert.False(t, eq) - - eq = EqualFr(&one, &one) - assert.True(t, eq) -} - -func TestAddFr(t *testing.T) { - one := ToFr("1") - two := ToFr("2") - three := ToFr("3") - - var res Fr - AsFr(&res, 0) - AddModFr(&res, &one, &two) - - assert.Equal(t, res, three) -} - -func TestSubFr(t *testing.T) { - one := ToFr("1") - two := ToFr("2") - three := ToFr("3") - - var res Fr - AsFr(&res, 0) - SubModFr(&res, &three, &two) - - assert.Equal(t, res, one) -} - -func TestDivModFr(t *testing.T) { - two := ToFr("2") - three := ToFr("3") - six := ToFr("6") - - var res Fr - AsFr(&res, 0) - DivModFr(&res, &six, &three) - - assert.Equal(t, res, two) -} - -func TestMulModFr(t *testing.T) { - two := ToFr("2") - three := ToFr("3") - six := ToFr("6") - - var res Fr - AsFr(&res, 0) - MulModFr(&res, &two, &three) - - assert.Equal(t, res, six) -} - -func TestInvModFr(t *testing.T) { - two := ToFr("2") - invTwo := ToFr("10944121435919637611123202872628637544274182200208017171849102093287904247809") - - var res Fr - AsFr(&res, 0) - InvModFr(&res, &two) - - assert.Equal(t, res, invTwo) -} - -func TestEvalPolyAt(t *testing.T) { - one := ToFr("1") - var dst Fr - p := []Fr{ - ToFr("1"), - ToFr("2"), - ToFr("3"), - } - EvalPolyAt(&dst, p, &one) - - assert.Equal(t, dst, ToFr("6")) -} diff --git a/pkg/kzg/bn254/bn254_all.go b/pkg/kzg/bn254/bn254_all.go deleted file mode 100644 index 347070085e..0000000000 --- a/pkg/kzg/bn254/bn254_all.go +++ /dev/null @@ -1,64 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package bn254 - -import ( - "errors" -) - -func (p *G1Point) MarshalText() []byte { - return ToCompressedG1(p) -} - -// UnmarshalText decodes hex formatted text (no 0x prefix) into a G1Point -func (p *G1Point) UnmarshalText(text []byte) error { - if p == nil { - return errors.New("cannot decode into nil G1Point") - } - d, err := FromCompressedG1(text) - if err != nil { - return err - } - *p = *d - return nil -} - -// MarshalText encodes G2Point into hex formatted text (no 0x prefix) -func (p *G2Point) MarshalText() []byte { - return ToCompressedG2(p) -} - -// UnmarshalText decodes hex formatted text (no 0x prefix) into a G2Point -func (p *G2Point) UnmarshalText(text []byte) error { - if p == nil { - return errors.New("cannot decode into nil G2Point") - } - d, err := FromCompressedG2(text) - if err != nil { - return err - } - *p = *d - return nil -} diff --git a/pkg/kzg/bn254/bn254_all_test.go b/pkg/kzg/bn254/bn254_all_test.go deleted file mode 100644 index 9978f81171..0000000000 --- a/pkg/kzg/bn254/bn254_all_test.go +++ /dev/null @@ -1,96 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -package bn254 - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestPointG1Marshalling(t *testing.T) { - var x Fr - SetFr(&x, "44689111813071777962210527909085028157792767057343609826799812096627770269092") - var point G1Point - MulG1(&point, &GenG1, &x) - - bytes := point.MarshalText() - - // The point is serialized to raw bytes and it should be 32 bytes. - assert.Equal(t, len(bytes), 32) - - var anotherPoint G1Point - err := anotherPoint.UnmarshalText(bytes) - require.Nil(t, err) - - assert.True(t, EqualG1(&point, &anotherPoint), "G1 points did not match\n%s\n%s", StrG1(&point), StrG1(&anotherPoint)) -} - -func TestPointG1Marshalling_InvalidG1(t *testing.T) { - var g1 *G1Point - err := g1.UnmarshalText([]byte("")) - assert.EqualError(t, err, "cannot decode into nil G1Point") - - g1 = new(G1Point) - err = g1.UnmarshalText([]byte("G")) - assert.EqualError(t, err, "short buffer") - - err = g1.UnmarshalText([]byte("8000000000000000000000000000000000000000000000000000000000000099")) - assert.EqualError(t, err, "invalid fp.Element encoding") -} - -func TestPointG2Marshalling(t *testing.T) { - var x Fr - SetFr(&x, "44689111813071777962210527909085028157792767057343609826799812096627770269092") - var point G2Point - MulG2(&point, &GenG2, &x) - - bytes := point.MarshalText() - // The point is serialized to raw bytes and it should be 64 bytes (2x the G1). - assert.Equal(t, len(bytes), 64) - - var anotherPoint G2Point - err := anotherPoint.UnmarshalText(bytes) - require.Nil(t, err) - - assert.True(t, EqualG2(&point, &anotherPoint), "G2 points did not match:\n%s\n%s", StrG2(&point), StrG2(&anotherPoint)) -} - -func TestPointG2Marshalling_InvalidG2(t *testing.T) { - var g2 *G2Point - err := g2.UnmarshalText([]byte("")) - assert.EqualError(t, err, "cannot decode into nil G2Point") - - g2 = new(G2Point) - err = g2.UnmarshalText([]byte("G")) - assert.EqualError(t, err, "short buffer") - - err = g2.UnmarshalText([]byte("898e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed")) - assert.EqualError(t, err, "invalid fp.Element encoding") - - err = g2.UnmarshalText([]byte("998e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992ffff")) - assert.EqualError(t, err, "invalid fp.Element encoding") - -} diff --git a/pkg/kzg/bn254/bn254_gnark.go b/pkg/kzg/bn254/bn254_gnark.go deleted file mode 100644 index 7e480e8db7..0000000000 --- a/pkg/kzg/bn254/bn254_gnark.go +++ /dev/null @@ -1,277 +0,0 @@ -package bn254 - -import ( - "log" - "math/big" - - "github.com/consensys/gnark-crypto/ecc" - bn "github.com/consensys/gnark-crypto/ecc/bn254" - "github.com/consensys/gnark-crypto/ecc/bn254/fr" -) - -func (p *G1Point) String() string { - return StrG1(p) -} - -func (p *G2Point) String() string { - return StrG2(p) -} - -var ZERO_G1 G1Point -var ZERO_G2 G2Point - -var GenG1 G1Point -var GenG2 G2Point - -var ZeroG1 G1Point -var ZeroG2 G2Point - -//var InfG1 G1Point -//var InfG2 G2Point - -func initG1G2() { - - _, _, genG1, genG2 := bn.Generators() - - GenG1 = *(*G1Point)(&genG1) - GenG2 = *(*G2Point)(&genG2) - - //InfG1.X.SetOne() - //InfG1.Y.SetOne() - - //ZeroG1 = G1Point(*kbls.NewG1().Zero()) - //ZeroG2 = G2Point(*kbls.NewG2().Zero()) - - var g1Jac bn.G1Jac - g1Jac.X.SetZero() - g1Jac.Y.SetOne() - g1Jac.Z.SetZero() - - var g1Aff bn.G1Affine - g1Aff.FromJacobian(&g1Jac) - ZeroG1 = *(*G1Point)(&g1Aff) - - var g2Jac bn.G2Jac - g2Jac.X.SetZero() - g2Jac.Y.SetOne() - g2Jac.Z.SetZero() - var g2Aff bn.G2Affine - g2Aff.FromJacobian(&g2Jac) - ZeroG2 = *(*G2Point)(&g2Aff) -} - -type G1Point bn.G1Affine - -// zeroes the point (like herumi BLS does with theirs). This is not co-factor clearing. -func ClearG1(x *G1Point) { - (*bn.G1Affine)(x).Sub((*bn.G1Affine)(x), (*bn.G1Affine)(x)) -} - -func CopyG1(dst *G1Point, v *G1Point) { - *dst = *v -} - -func MulG1(dst *G1Point, a *G1Point, b *Fr) { - //tmp := (kbls.Fr)(*b) // copy, we want to leave the original in mont-red form - //(&tmp).FromRed() - //kbls.NewG1().MulScalar((*kbls.PointG1)(dst), (*kbls.PointG1)(a), &tmp) - - var t big.Int - (*fr.Element)(b).BigInt(&t) - (*bn.G1Affine)(dst).ScalarMultiplication((*bn.G1Affine)(a), &t) -} - -func AddG1(dst *G1Point, a *G1Point, b *G1Point) { - var sum, bJac bn.G1Jac - sum.FromAffine((*bn.G1Affine)(a)) - bJac.FromAffine((*bn.G1Affine)(b)) - sum.AddAssign(&bJac) - (*bn.G1Affine)(dst).FromJacobian(&sum) -} - -func SubG1(dst *G1Point, a *G1Point, b *G1Point) { - var diff, bJac bn.G1Jac - diff.FromAffine((*bn.G1Affine)(a)) - bJac.FromAffine((*bn.G1Affine)(b)) - diff.SubAssign(&bJac) - (*bn.G1Affine)(dst).FromJacobian(&diff) -} - -func StrG1(v *G1Point) string { - return (*bn.G1Affine)(v).String() + "\n" -} - -func NegG1(dst *G1Point) { - // in-place should be safe here (TODO double check) - (*bn.G1Affine)(dst).Neg((*bn.G1Affine)(dst)) -} - -type G2Point bn.G2Affine - -func ClearG2(x *G2Point) { - (*bn.G2Affine)(x).Sub((*bn.G2Affine)(x), (*bn.G2Affine)(x)) -} - -func CopyG2(dst *G2Point, v *G2Point) { - *dst = *v -} - -func MulG2(dst *G2Point, a *G2Point, b *Fr) { - //tmp := (kbls.Fr)(*b) // copy, we want to leave the original in mont-red form - //(&tmp).FromRed() - //kbls.NewG2().MulScalar((*kbls.PointG2)(dst), (*kbls.PointG2)(a), &tmp) - var t big.Int - (*fr.Element)(b).BigInt(&t) - (*bn.G2Affine)(dst).ScalarMultiplication((*bn.G2Affine)(a), &t) -} - -func AddG2(dst *G2Point, a *G2Point, b *G2Point) { - var sum, bJac bn.G2Jac - sum.FromAffine((*bn.G2Affine)(a)) - bJac.FromAffine((*bn.G2Affine)(b)) - sum.AddAssign(&bJac) - (*bn.G2Affine)(dst).FromJacobian(&sum) -} - -func SubG2(dst *G2Point, a *G2Point, b *G2Point) { - var diff, bJac bn.G2Jac - diff.FromAffine((*bn.G2Affine)(a)) - bJac.FromAffine((*bn.G2Affine)(b)) - diff.SubAssign(&bJac) - (*bn.G2Affine)(dst).FromJacobian(&diff) -} - -func StrG2(v *G2Point) string { - return (*bn.G2Affine)(v).String() -} - -func NegG2(dst *G2Point) { - // in-place should be safe here (TODO double check) - (*bn.G2Affine)(dst).Neg((*bn.G2Affine)(dst)) -} - -func EqualG1(a *G1Point, b *G1Point) bool { - return (*bn.G1Affine)(a).Equal((*bn.G1Affine)(b)) -} - -func EqualG2(a *G2Point, b *G2Point) bool { - return (*bn.G2Affine)(a).Equal((*bn.G2Affine)(b)) -} - -func ToCompressedG1(p *G1Point) []byte { - d := (*bn.G1Affine)(p).Bytes() - return d[:] -} - -func FromCompressedG1(v []byte) (*G1Point, error) { - - p := new(bn.G1Affine) - _, err := p.SetBytes(v) - - return (*G1Point)(p), err -} - -func ToCompressedG2(p *G2Point) []byte { - //return hbls.CastToSign((*hbls.G2)(p)).Serialize() - d := (*bn.G2Affine)(p).Bytes() - return d[:] -} - -func FromCompressedG2(v []byte) (*G2Point, error) { - //p, err := kbls.NewG1().FromCompressed(v) - - p := new(bn.G2Affine) - _, err := p.SetBytes(v) - - return (*G2Point)(p), err -} - -func LinCombG1(numbers []G1Point, factors []Fr) *G1Point { - out := new(G1Point) - CopyG1(out, &ZeroG1) - out1 := *(*bn.G1Affine)(out) - - np := make([]bn.G1Affine, len(numbers)) - fs := make([]fr.Element, len(factors)) - - for i := 0; i < len(np); i++ { - np[i] = *(*bn.G1Affine)(&numbers[i]) - } - for i := 0; i < len(fs); i++ { - fs[i] = *(*fr.Element)(&factors[i]) - } - - config := ecc.MultiExpConfig{} - _, err := out1.MultiExp(np, fs, config) - if err != nil { - log.Fatal(err) - } - return (*G1Point)(&out1) -} - -func LinCombG2(numbers []G2Point, factors []Fr) *G2Point { - out := new(G2Point) - CopyG2(out, &ZeroG2) - out1 := *(*bn.G2Affine)(out) - - np := make([]bn.G2Affine, len(numbers)) - fs := make([]fr.Element, len(factors)) - - for i := 0; i < len(np); i++ { - np[i] = *(*bn.G2Affine)(&numbers[i]) - } - for i := 0; i < len(fs); i++ { - fs[i] = *(*fr.Element)(&factors[i]) - } - - config := ecc.MultiExpConfig{} - _, err := out1.MultiExp(np, fs, config) - if err != nil { - log.Fatal(err) - } - return (*G2Point)(&out1) -} - -func PairingsVerify(a1 *G1Point, a2 *G2Point, b1 *G1Point, b2 *G2Point) bool { - //var tmp hbls.GT - //hbls.Pairing(&tmp, (*hbls.G1)(a1), (*hbls.G2)(a2)) - ////fmt.Println("tmp", tmp.GetString(10)) - //var tmp2 hbls.GT - //hbls.Pairing(&tmp2, (*hbls.G1)(b1), (*hbls.G2)(b2)) - - //// invert left pairing - //var tmp3 hbls.GT - //hbls.GTInv(&tmp3, &tmp) - - //// multiply the two - //var tmp4 hbls.GT - //hbls.GTMul(&tmp4, &tmp3, &tmp2) - - //// final exp. - //var tmp5 hbls.GT - //hbls.FinalExp(&tmp5, &tmp4) - - // = 1_T - //return tmp5.IsOne() - - // TODO, alternatively use the equal check (faster or slower?): - ////fmt.Println("tmp2", tmp2.GetString(10)) - //return tmp.IsEqual(&tmp2) - - var negB1 bn.G1Affine - negB1.Neg((*bn.G1Affine)(b1)) - - P := [2]bn.G1Affine{*(*bn.G1Affine)(a1), negB1} - Q := [2]bn.G2Affine{*(*bn.G2Affine)(a2), *(*bn.G2Affine)(b2)} - - ok, err := bn.PairingCheck(P[:], Q[:]) - if err != nil { - log.Fatal(err) - } - return ok -} - -func Generators() (G1Point, G2Point) { - _, _, g1, g2 := bn.Generators() - return *(*G1Point)(&g1), *(*G2Point)(&g2) -} diff --git a/pkg/kzg/bn254/bn254_gnark_test.go b/pkg/kzg/bn254/bn254_gnark_test.go deleted file mode 100644 index 826a87c7e5..0000000000 --- a/pkg/kzg/bn254/bn254_gnark_test.go +++ /dev/null @@ -1,295 +0,0 @@ -//go:build !bignum_pure && !bignum_hol256 -// +build !bignum_pure,!bignum_hol256 - -package bn254 - -import ( - "bytes" - "encoding/hex" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestPointCompression(t *testing.T) { - var x Fr - SetFr(&x, "44689111813071777962210527909085028157792767057343609826799812096627770269092") - var point G1Point - MulG1(&point, &GenG1, &x) - got := ToCompressedG1(&point) - - expected, err := hex.DecodeString("cb6a192085f84b7f34e29b5e5056927581f573201abb1ce1b8ee132c71fae1e2") - if !bytes.Equal(expected, got) || err != nil { - t.Fatalf("Invalid compression result, %x != %x", got, expected) - } -} - -func TestZeroG1(t *testing.T) { - zero := ZeroG1 - expected := "0" - if zero.X != zero.Y || zero.X.String() != expected { - t.Fatalf("ZeroG1 is not zero! expected %s, but got: %s", expected, zero.X.String()) - } -} - -func TestGenG1(t *testing.T) { - one := GenG1 - expectedX := "1" - expectedY := "2" - - if one.X.String() != expectedX { - t.Fatalf("expected %s, but got: %s", expectedX, one.X.String()) - } - - if one.Y.String() != expectedY { - t.Fatalf("expected %s, but got: %s", expectedY, one.Y.String()) - } -} - -func TestClearG1(t *testing.T) { - clear := GenG1 - ClearG1(&clear) - - if clear != ZERO_G1 { - t.Fatalf("ClearG1 failed %v", clear.X.String()) - } -} - -func TestCopyG1(t *testing.T) { - one := GenG1 - var dst G1Point - CopyG1(&dst, &one) - - if one != dst { - t.Fatalf("CopyG1 failed %v", dst.X.String()) - } -} - -func TestMulG1(t *testing.T) { - g1 := GenG1 - two := ToFr("2") - var prod G1Point - MulG1(&prod, &g1, &two) - - var add G1Point - AddG1(&add, &g1, &g1) - - if add != prod { - t.Fatalf("MulG1 failed") - } -} - -func TestAddG1(t *testing.T) { - zero := ZERO_G1 - one := GenG1 - var dst G1Point - AddG1(&dst, &zero, &one) - - if dst != one { - t.Fatalf("AddG1 failed %v", dst.X.String()) - } -} - -func TestSubG1(t *testing.T) { - one := GenG1 - var dst G1Point - SubG1(&dst, &one, &one) - - if dst != ZERO_G1 { - t.Fatalf("SubG1 failed %v", dst.X.String()) - } -} - -func TestStrG1(t *testing.T) { - g1 := GenG1 - g1Str := StrG1(&g1) - expected := "E([1,2])\n" - if g1Str != expected { - t.Fatalf("StrG1 failed, %v %v", g1Str, expected) - } -} - -func TestStringG1(t *testing.T) { - g1 := GenG1 - g1Str := g1.String() - expected := "E([1,2])\n" - if g1Str != expected { - t.Fatalf("StrG1 failed, %v %v", g1Str, expected) - } -} - -func TestNegG1(t *testing.T) { - negG1 := GenG1 - NegG1(&negG1) - - // Add - var res G1Point - AddG1(&res, &GenG1, &negG1) - if res != ZERO_G1 { - t.Fatal("NegG1 failed") - } -} - -func TestLinCombG1(t *testing.T) { - // TODO: use random poly and g1 points - poly := []Fr{ - ToFr("1"), ToFr("2"), ToFr("3"), ToFr("4"), ToFr("5"), - } - one := GenG1 - val := []G1Point{ - one, one, one, one, one, - } - lin := LinCombG1(val, poly) - - var scalar Fr - AsFr(&scalar, uint64(15)) - var product G1Point - MulG1(&product, &one, &scalar) - if *lin != product { - t.Fatal("Linear combination != product!") - } -} - -func TestZeroG2(t *testing.T) { - zero := ZeroG2 - expected := "0+0*u" - - if zero.X != zero.Y || zero.X.String() != expected { - t.Fatalf("ZeroG2 is not zero! expected %s, but got: %s", expected, zero.X.String()) - } -} - -func TestGenG2(t *testing.T) { - two := GenG2 - expectedTwoX := "10857046999023057135944570762232829481370756359578518086990519993285655852781+11559732032986387107991004021392285783925812861821192530917403151452391805634*u" - expectedTwoY := "8495653923123431417604973247489272438418190587263600148770280649306958101930+4082367875863433681332203403145435568316851327593401208105741076214120093531*u" - - if two.X.String() != expectedTwoX { - t.Fatalf("expected %s, but got: %s", expectedTwoX, two.X.String()) - } - - if two.Y.String() != expectedTwoY { - t.Fatalf("expected %s, but got: %s", expectedTwoY, two.Y.String()) - } -} - -func TestClearG2(t *testing.T) { - clear := GenG2 - ClearG2(&clear) - - if clear != ZERO_G2 { - t.Fatalf("ClearG2 failed %v", clear.X.String()) - } -} - -func TestCopyG2(t *testing.T) { - two := GenG2 - var dst G2Point - CopyG2(&dst, &two) - - if two != dst { - t.Fatalf("CopyG2 failed %v", dst.X.String()) - } -} - -func TestMulG2(t *testing.T) { - g2 := GenG2 - two := ToFr("2") - var prod G2Point - MulG2(&prod, &g2, &two) - - var add G2Point - AddG2(&add, &g2, &g2) - - if add != prod { - t.Fatalf("MulG2 failed") - } -} - -func TestAddG2(t *testing.T) { - zero := ZERO_G2 - one := GenG2 - var dst G2Point - AddG2(&dst, &zero, &one) - - if dst != one { - t.Fatalf("AddG2 failed %v", dst.X.String()) - } -} - -func TestSubG2(t *testing.T) { - one := GenG2 - var dst G2Point - SubG2(&dst, &one, &one) - - if dst != ZERO_G2 { - t.Fatalf("SubG1 failed %v", dst.X.String()) - } -} - -func TestStrG2(t *testing.T) { - g2 := GenG2 - g2Str := StrG2(&g2) - expected := "E([10857046999023057135944570762232829481370756359578518086990519993285655852781+11559732032986387107991004021392285783925812861821192530917403151452391805634*u,8495653923123431417604973247489272438418190587263600148770280649306958101930+4082367875863433681332203403145435568316851327593401208105741076214120093531*u])" - if g2Str != expected { - t.Fatalf("StrG2 failed, %v %v", g2Str, expected) - } -} - -func TestStringG2(t *testing.T) { - g2 := GenG2 - g2Str := g2.String() - expected := "E([10857046999023057135944570762232829481370756359578518086990519993285655852781+11559732032986387107991004021392285783925812861821192530917403151452391805634*u,8495653923123431417604973247489272438418190587263600148770280649306958101930+4082367875863433681332203403145435568316851327593401208105741076214120093531*u])" - if g2Str != expected { - t.Fatalf("StrG2 failed, %v %v", g2Str, expected) - } -} - -func TestNegG2(t *testing.T) { - negG2 := GenG2 - NegG2(&negG2) - - // Add - var res G2Point - AddG2(&res, &GenG2, &negG2) - if res != ZERO_G2 { - t.Fatal("NegG2 failed") - } -} - -func TestLinCombG2(t *testing.T) { - // TODO: use random poly and g1 points - poly := []Fr{ - ToFr("1"), ToFr("2"), ToFr("3"), ToFr("4"), ToFr("5"), - } - one := GenG2 - val := []G2Point{ - one, one, one, one, one, - } - lin := LinCombG2(val, poly) - - var scalar Fr - AsFr(&scalar, uint64(15)) - var product G2Point - MulG2(&product, &one, &scalar) - if *lin != product { - t.Fatal("Linear combination != product!") - } -} - -func TestGenerators(t *testing.T) { - g1, g2 := Generators() - if g1 != GenG1 && g2 != GenG2 { - t.Fatal("Setup failed") - } -} - -func TestPairingsVerify(t *testing.T) { - g1, g2 := Generators() - - // Invalid pairing - val := PairingsVerify(&g1, &g2, &ZeroG1, &ZeroG2) - assert.False(t, val) - - // TODO: test valid pairing -} diff --git a/pkg/kzg/bn254/globals_test.go b/pkg/kzg/bn254/globals_test.go deleted file mode 100644 index d7a16b991d..0000000000 --- a/pkg/kzg/bn254/globals_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package bn254 - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -// TODO: slow test -// func TestRootOfUnity(t *testing.T) { -// one := ToFr("1") - -// for i := 0; i < len(Scale2RootOfUnity); i++ { -// u := Scale2RootOfUnity[i] -// var product Fr -// CopyFr(&product, &one) - -// //log.Println("multiply of ", i*i) -// order := int(math.Pow(2.0, float64(i))) -// for j := 0; j < order; j++ { -// MulModFr(&product, &product, &u) -// } - -// if !EqualOne(&product) { -// log.Fatalf("%v point is not a root of unity", i) -// } -// } - -// log.Printf("all %v root of unity pass", len(Scale2RootOfUnity)) -// } - -func TestIsPowerOf2(t *testing.T) { - if !IsPowerOfTwo(2) { - t.Fatal("2 is not a power of 2") - } -} - -func TestEvalPolyAtUnoptimized(t *testing.T) { - one := ToFr("1") - coeffs := []Fr{} - res := ONE - EvalPolyAtUnoptimized(&res, coeffs, &one) - assert.Equal(t, res, ZERO) - - coeffs = []Fr{ - ToFr("1"), - ToFr("2"), - ToFr("3"), - } - res = ZERO - EvalPolyAtUnoptimized(&res, coeffs, &one) - assert.Equal(t, res, ToFr("6")) - - zero := ZERO - EvalPolyAtUnoptimized(&res, coeffs, &zero) - assert.Equal(t, res, coeffs[0]) -} diff --git a/pkg/kzg/das_extension.go b/pkg/kzg/das_extension.go deleted file mode 100644 index 7c8e0cc68d..0000000000 --- a/pkg/kzg/das_extension.go +++ /dev/null @@ -1,108 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package kzg - -import bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" - -// warning: the values in `a` are modified in-place to become the outputs. -// Make a deep copy first if you need to use them later. -func (fs *FFTSettings) dASFFTExtension(ab []bls.Fr, domainStride uint64) { - if len(ab) == 2 { - aHalf0 := &ab[0] - aHalf1 := &ab[1] - var x bls.Fr - bls.AddModFr(&x, aHalf0, aHalf1) - var y bls.Fr - bls.SubModFr(&y, aHalf0, aHalf1) - var tmp bls.Fr - bls.MulModFr(&tmp, &y, &fs.ExpandedRootsOfUnity[domainStride]) - bls.AddModFr(&ab[0], &x, &tmp) - bls.SubModFr(&ab[1], &x, &tmp) - return - } - - if len(ab) < 2 { - panic("bad usage") - } - - half := uint64(len(ab)) - halfHalf := half >> 1 - abHalf0s := ab[:halfHalf] - abHalf1s := ab[halfHalf:half] - // Instead of allocating L0 and L1, just modify a in-place. - //L0[i] = (((a_half0 + a_half1) % modulus) * inv2) % modulus - //R0[i] = (((a_half0 - L0[i]) % modulus) * inverse_domain[i * 2]) % modulus - var tmp1, tmp2 bls.Fr - for i := uint64(0); i < halfHalf; i++ { - aHalf0 := &abHalf0s[i] - aHalf1 := &abHalf1s[i] - bls.AddModFr(&tmp1, aHalf0, aHalf1) - bls.SubModFr(&tmp2, aHalf0, aHalf1) - bls.MulModFr(aHalf1, &tmp2, &fs.ReverseRootsOfUnity[i*2*domainStride]) - bls.CopyFr(aHalf0, &tmp1) - } - - // L will be the left half of out - fs.dASFFTExtension(abHalf0s, domainStride<<1) - // R will be the right half of out - fs.dASFFTExtension(abHalf1s, domainStride<<1) - - // The odd deduced outputs are written to the output array already, but then updated in-place - // L1 = b[:halfHalf] - // R1 = b[halfHalf:] - - // Half the work of a regular FFT: only deal with uneven-index outputs - var yTimesRoot bls.Fr - var x, y bls.Fr - for i := uint64(0); i < halfHalf; i++ { - // Temporary copies, so that writing to output doesn't conflict with input. - // Note that one hand is from L1, the other R1 - bls.CopyFr(&x, &abHalf0s[i]) - bls.CopyFr(&y, &abHalf1s[i]) - root := &fs.ExpandedRootsOfUnity[(1+2*i)*domainStride] - bls.MulModFr(&yTimesRoot, &y, root) - // write outputs in place, avoid unnecessary list allocations - bls.AddModFr(&abHalf0s[i], &x, &yTimesRoot) - bls.SubModFr(&abHalf1s[i], &x, &yTimesRoot) - } -} - -// Takes vals as input, the values of the even indices. -// Then computes the values for the odd indices, which combined would make the right half of coefficients zero. -// Warning: the odd results are written back to the vals slice. -func (fs *FFTSettings) DASFFTExtension(vals []bls.Fr) { - if uint64(len(vals))*2 > fs.MaxWidth { - panic("domain too small for extending requested values") - } - fs.dASFFTExtension(vals, 1) - // The above function didn't perform the divide by 2 on every layer. - // So now do it all at once, by dividing by 2**depth (=length). - var invLen bls.Fr - bls.AsFr(&invLen, uint64(len(vals))) - bls.InvModFr(&invLen, &invLen) - for i := 0; i < len(vals); i++ { - bls.MulModFr(&vals[i], &vals[i], &invLen) - } -} diff --git a/pkg/kzg/das_extension_test.go b/pkg/kzg/das_extension_test.go deleted file mode 100644 index 5c697a8e7c..0000000000 --- a/pkg/kzg/das_extension_test.go +++ /dev/null @@ -1,99 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -package kzg - -import ( - "fmt" - "math/rand" - "testing" - - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestDASFFTExtension(t *testing.T) { - fs := NewFFTSettings(4) - half := fs.MaxWidth / 2 - data := make([]bls.Fr, half) - for i := uint64(0); i < half; i++ { - bls.AsFr(&data[i], i) - } - fs.DASFFTExtension(data) - - expected := []bls.Fr{ - bls.ToFr("9455244345631016631523862383826656817909262240618707851288319855253023724498"), - bls.ToFr("10961351032263120273117550959237409754492768732192557560880754261368126052154"), - bls.ToFr("12432998526208258595130464331726862113180416131685271896346981464741203555841"), - bls.ToFr("8526477789819225339470181130720054257555649678225561659213114114555273578201"), - bls.ToFr("12432998526208258595130464331726862113180416131685271896346981464741203555841"), - bls.ToFr("10961351032263120273117550959237409754492768732192557560880754261368126052154"), - bls.ToFr("9455244345631016631523862383826656817909262240618707851288319855253023724498"), - bls.ToFr("13327305889333084549971686500727188725472913714445501098547591469023253739309"), - } - - for i := range data { - assert.True(t, bls.EqualFr(&data[i], &expected[i])) - } -} - -func TestParametrizedDASFFTExtension(t *testing.T) { - testScale := func(seed int64, scale uint8, t *testing.T) { - fs := NewFFTSettings(scale) - evenData := make([]bls.Fr, fs.MaxWidth/2) - rng := rand.New(rand.NewSource(seed)) - for i := uint64(0); i < fs.MaxWidth/2; i++ { - bls.AsFr(&evenData[i], rng.Uint64()) // TODO could be a full random F_r instead of uint64 - } - // we don't want to modify the original input, and the inner function would modify it in-place, so make a copy. - oddData := make([]bls.Fr, fs.MaxWidth/2) - for i := 0; i < len(oddData); i++ { - bls.CopyFr(&oddData[i], &evenData[i]) - } - fs.DASFFTExtension(oddData) - - // reconstruct data - data := make([]bls.Fr, fs.MaxWidth) - for i := uint64(0); i < fs.MaxWidth; i += 2 { - bls.CopyFr(&data[i], &evenData[i>>1]) - bls.CopyFr(&data[i+1], &oddData[i>>1]) - } - // get coefficients of reconstructed data with inverse FFT - coeffs, err := fs.FFT(data, true) - require.Nil(t, err) - require.NotNil(t, coeffs) - - // second half of all coefficients should be zero - for i := fs.MaxWidth / 2; i < fs.MaxWidth; i++ { - assert.True(t, bls.EqualZero(&coeffs[i]), "expected zero coefficient on index %d", i) - } - } - for scale := uint8(4); scale < 10; scale++ { - for i := int64(0); i < 4; i++ { - t.Run(fmt.Sprintf("scale_%d_i_%d", scale, i), func(t *testing.T) { - testScale(i, scale, t) - }) - } - } -} diff --git a/pkg/kzg/fft_fr_test.go b/pkg/kzg/fft_fr_test.go deleted file mode 100644 index fe70ce5dbe..0000000000 --- a/pkg/kzg/fft_fr_test.go +++ /dev/null @@ -1,89 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -package kzg - -import ( - "testing" - - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestFFTRoundtrip(t *testing.T) { - fs := NewFFTSettings(4) - data := make([]bls.Fr, fs.MaxWidth) - for i := uint64(0); i < fs.MaxWidth; i++ { - bls.AsFr(&data[i], i) - } - coeffs, err := fs.FFT(data, false) - require.Nil(t, err) - require.NotNil(t, coeffs) - - res, err := fs.FFT(coeffs, true) - require.Nil(t, err) - require.NotNil(t, coeffs) - - for i := range res { - assert.True(t, bls.EqualFr(&res[i], &data[i])) - } - - t.Log("zero", bls.FrStr(&bls.ZERO)) - t.Log("zero", bls.FrStr(&bls.ONE)) -} - -func TestInvFFT(t *testing.T) { - fs := NewFFTSettings(4) - data := make([]bls.Fr, fs.MaxWidth) - for i := uint64(0); i < fs.MaxWidth; i++ { - bls.AsFr(&data[i], i) - } - - res, err := fs.FFT(data, true) - require.Nil(t, err) - require.NotNil(t, res) - - expected := []bls.Fr{ - bls.ToFr("10944121435919637611123202872628637544274182200208017171849102093287904247816"), - bls.ToFr("1936030771851033959223912058450265953781825736913396623629635806885115007405"), - bls.ToFr("16407567355707715082381689537916387329395994555403796510305004205827931381005"), - bls.ToFr("10191068092603585790326358584923261075982428954421092317052884890230353083980"), - bls.ToFr("21888242871839275220042445260109153167277707414472061641729655619866599103259"), - bls.ToFr("21152419124866706061239949059012548909204540700669677175965090584889269743773"), - bls.ToFr("16407567355707715086789610508212631171937308527291741914242101339246350165720"), - bls.ToFr("12897381804114154238953344473132041472086565426937872290416035768380869236628"), - bls.ToFr("10944121435919637611123202872628637544274182200208017171849102093287904247808"), - bls.ToFr("8990861067725120983293061272125233616461798973478162053282168418194939258988"), - bls.ToFr("5480675516131560135456795237044643916611055873124292429456102847329458329896"), - bls.ToFr("735823746972569161006456686244726179343823699746357167733113601686538751843"), - bls.ToFr("2203960485148121921270656985943972701968548566709209392357"), - bls.ToFr("11697174779235689431920047160334014012565935445994942026645319296345455411636"), - bls.ToFr("5480675516131560139864716207340887759152369845012237833393199980747877114611"), - bls.ToFr("19952212099988241263022493686807009134766538663502637720068568379690693488211"), - } - - for i := range res { - assert.True(t, bls.EqualFr(&res[i], &expected[i])) - } -} diff --git a/pkg/kzg/fk20_multi.go b/pkg/kzg/fk20_multi.go deleted file mode 100644 index f6a1cbf798..0000000000 --- a/pkg/kzg/fk20_multi.go +++ /dev/null @@ -1,155 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -// Original: https://github.com/ethereum/research/blob/master/kzg_data_availability/fk20_multi.py - -//go:build !bignum_pure && !bignum_hol256 -// +build !bignum_pure,!bignum_hol256 - -package kzg - -import ( - "fmt" - - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" -) - -// FK20 Method to compute all proofs -// Toeplitz multiplication via http://www.netlib.org/utk/people/JackDongarra/etemplates/node384.html -// Multi proof method - -// For a polynomial of size n, let w be a n-th root of unity. Then this method will return -// k=n/l KZG proofs for the points -// -// proof[0]: w^(0*l + 0), w^(0*l + 1), ... w^(0*l + l - 1) -// proof[0]: w^(0*l + 0), w^(0*l + 1), ... w^(0*l + l - 1) -// ... -// proof[i]: w^(i*l + 0), w^(i*l + 1), ... w^(i*l + l - 1) -// ... -// func (ks *FK20MultiSettings) FK20Multi(polynomial []bls.Fr) []bls.G1Point { -// n := uint64(len(polynomial)) -// n2 := n * 2 -// if ks.MaxWidth < n2 { -// panic(fmt.Errorf("KZGSettings are set to MaxWidth %d but got half polynomial of length %d", -// ks.MaxWidth, n)) -// } - -// hExtFFT := make([]bls.G1Point, n2, n2) -// for i := uint64(0); i < n2; i++ { -// bls.CopyG1(&hExtFFT[i], &bls.ZeroG1) -// } - -// var tmp bls.G1Point -// for i := uint64(0); i < ks.chunkLen; i++ { -// toeplitzCoeffs := ks.toeplitzCoeffsStepStrided(polynomial, i, ks.chunkLen) -// hExtFFTFile := ks.ToeplitzPart2(toeplitzCoeffs, ks.xExtFFTFiles[i]) -// for j := uint64(0); j < n2; j++ { -// bls.AddG1(&tmp, &hExtFFT[j], &hExtFFTFile[j]) -// bls.CopyG1(&hExtFFT[j], &tmp) -// } -// } -// h := ks.ToeplitzPart3(hExtFFT) - -// out, err := ks.FFTG1(h, false) -// if err != nil { -// panic(err) -// } -// return out -// } - -// FK20MultiDAOptimized is FK20 multi-proof method, optimized for dava availability where the top half of polynomial -// coefficients == 0 -func (ks *FK20MultiSettings) FK20MultiDAOptimized(polynomial []bls.Fr) []bls.G1Point { - n2 := uint64(len(polynomial)) - if ks.MaxWidth < n2 { - panic(fmt.Errorf("KZGSettings are set to MaxWidth %d but got polynomial of length %d", - ks.MaxWidth, n2)) - } - n := n2 / 2 - for i := n; i < n2; i++ { - if !bls.EqualZero(&polynomial[i]) { - panic("bad input, second half should be zeroed") - } - } - - k := n / ks.chunkLen - k2 := k * 2 - hExtFFT := make([]bls.G1Point, k2) - for i := uint64(0); i < k2; i++ { - bls.CopyG1(&hExtFFT[i], &bls.ZeroG1) - } - - reducedPoly := polynomial[:n] - var tmp bls.G1Point - for i := uint64(0); i < ks.chunkLen; i++ { - toeplitzCoeffs := ks.toeplitzCoeffsStepStrided(reducedPoly, i, ks.chunkLen) - hExtFFTFile := ks.ToeplitzPart2(toeplitzCoeffs, ks.xExtFFTFiles[i]) - for j := uint64(0); j < k2; j++ { - bls.AddG1(&tmp, &hExtFFT[j], &hExtFFTFile[j]) - bls.CopyG1(&hExtFFT[j], &tmp) - } - } - h := ks.ToeplitzPart3(hExtFFT) - - // TODO: maybe use a G1 version of the DAS extension FFT to perform the h -> output conversion? - - // Now redo the padding before final step. - // Instead of copying h into a new extended array, just reuse the old capacity. - h = h[:k2] - for i := k; i < k2; i++ { - bls.CopyG1(&h[i], &bls.ZeroG1) - } - out, err := ks.FFTG1(h, false) - if err != nil { - panic(err) - } - return out -} - -// DAUsingFK20Multi computes all the KZG proofs for data availability checks. This involves sampling on the double domain -// and reordering according to reverse bit order -func (ks *FK20MultiSettings) DAUsingFK20Multi(polynomial []bls.Fr) ([]bls.G1Point, error) { - n := uint64(len(polynomial)) - if n > ks.MaxWidth/2 { - return nil, ErrInvalidPolyLengthTooLarge - } - if !bls.IsPowerOfTwo(n) { - return nil, ErrInvalidPolyLengthPowerOfTwo - } - n2 := n * 2 - extendedPolynomial := make([]bls.Fr, n2) - for i := uint64(0); i < n; i++ { - bls.CopyFr(&extendedPolynomial[i], &polynomial[i]) - } - for i := n; i < n2; i++ { - bls.CopyFr(&extendedPolynomial[i], &bls.ZERO) - } - allProofs := ks.FK20MultiDAOptimized(extendedPolynomial) - // change to reverse bit order. - err := reverseBitOrderG1(allProofs) - if err != nil { - return nil, err - } - return allProofs, nil -} diff --git a/pkg/kzg/fk20_multi_test.go b/pkg/kzg/fk20_multi_test.go deleted file mode 100644 index 1241abcf0d..0000000000 --- a/pkg/kzg/fk20_multi_test.go +++ /dev/null @@ -1,116 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -//go:build !bignum_pure && !bignum_hol256 -// +build !bignum_pure,!bignum_hol256 - -package kzg - -import ( - "testing" - - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestKZGSettings_DAUsingFK20Multi(t *testing.T) { - fs := NewFFTSettings(4 + 5 + 1) - chunkLen := uint64(16) - chunkCount := uint64(32) - n := chunkLen * chunkCount - s1, s2 := GenerateTestingSetup("1927409816240961209460912649124", chunkLen*chunkCount*2) - srs, _ := NewSrs(s1, s2) - ks, _ := NewKZGSettings(fs, srs) - fk := NewFK20MultiSettings(ks, n*2, chunkLen) - - // replicate same polynomial as in python test - polynomial := make([]bls.Fr, n) - var tmp134 bls.Fr - bls.AsFr(&tmp134, 134) - for i := uint64(0); i < chunkCount; i++ { - // Note: different contents from older python test, make each section different, - // to cover toeplitz coefficient edge cases better. - for j, v := range []uint64{1, 2, 3, 4 + i, 7, 8 + i*i, 9, 10, 13, 14, 1, 15, 0, 1000, 0, 33} { - bls.AsFr(&polynomial[i*chunkLen+uint64(j)], v) - } - bls.SubModFr(&polynomial[i*chunkLen+12], &bls.ZERO, &bls.ONE) // "MODULUS - 1" - bls.SubModFr(&polynomial[i*chunkLen+14], &bls.ZERO, &tmp134) // "MODULUS - 134" - } - - commitment := ks.CommitToPoly(polynomial) - - allProofs, err := fk.DAUsingFK20Multi(polynomial) - require.Nil(t, err, "could not compute proof") - require.NotNil(t, allProofs) - - // We have the data in polynomial form already, - // no need to use the DAS FFT (which extends data directly, not coeffs). - extendedCoeffs := make([]bls.Fr, n*2) - for i := uint64(0); i < n; i++ { - bls.CopyFr(&extendedCoeffs[i], &polynomial[i]) - } - for i := n; i < n*2; i++ { - bls.CopyFr(&extendedCoeffs[i], &bls.ZERO) - } - extendedData, err := ks.FFT(extendedCoeffs, false) - require.Nil(t, err) - require.NotNil(t, extendedData) - - err = reverseBitOrderFr(extendedData) - assert.Nil(t, err) - - n2 := n * 2 - domainStride := fk.MaxWidth / n2 - for pos := uint64(0); pos < 2*chunkCount; pos++ { - domainPos := reverseBitsLimited(uint32(2*chunkCount), uint32(pos)) - var x bls.Fr - bls.CopyFr(&x, &ks.ExpandedRootsOfUnity[uint64(domainPos)*domainStride]) - ys := extendedData[chunkLen*pos : chunkLen*(pos+1)] - // ys, but constructed by evaluating the polynomial in the sub-domain range - ys2 := make([]bls.Fr, chunkLen) - // don't recompute the subgroup domain, just select it from the bigger domain by applying a stride - stride := ks.MaxWidth / chunkLen - coset := make([]bls.Fr, chunkLen) - for i := uint64(0); i < chunkLen; i++ { - var z bls.Fr // a value of the coset list - bls.MulModFr(&z, &x, &ks.ExpandedRootsOfUnity[i*stride]) - bls.CopyFr(&coset[i], &z) - bls.EvalPolyAt(&ys2[i], polynomial, &z) - } - // permanently change order of ys values - err := reverseBitOrderFr(ys) - assert.Nil(t, err) - for i := 0; i < len(ys); i++ { - assert.True(t, bls.EqualFr(&ys[i], &ys2[i]), "failed to reproduce matching y values for subgroup") - } - - proof := &allProofs[pos] - val, err := ks.CheckProofMulti(commitment, proof, &x, ys) - require.Nil(t, err, "could not verify proof") - assert.True(t, val, "could not verify proof") - - t.Logf("Data availability check %d passed", pos) - } -} diff --git a/pkg/kzg/fk20_single.go b/pkg/kzg/fk20_single.go deleted file mode 100644 index 8dc1b99f2e..0000000000 --- a/pkg/kzg/fk20_single.go +++ /dev/null @@ -1,217 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -// Original: https://github.com/ethereum/research/blob/master/kzg_data_availability/fk20_single.py - -//go:build !bignum_pure && !bignum_hol256 -// +build !bignum_pure,!bignum_hol256 - -package kzg - -import ( - "fmt" - - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" -) - -// FK20 Method to compute all proofs -// Toeplitz multiplication via http://www.netlib.org/utk/people/JackDongarra/etemplates/node384.html -// Single proof method - -// A Toeplitz matrix is of the form -// -// t_0 t_(-1) t_(-2) ... t_(1-n) -// t_1 t_0 t_(-1) ... t_(2-n) -// t_2 t_1 . -// . . . -// . . . -// . . t(-1) -// t_(n-1) ... t_1 t_0 -// -// The vector [t_0, t_1, ..., t_(n-2), t_(n-1), 0, t_(1-n), t_(2-n), ..., t_(-2), t_(-1)] -// completely determines the Toeplitz matrix and is called the "toeplitz_coefficients" below - -// The composition toeplitz_part3(toeplitz_part2(toeplitz_coefficients, toeplitz_part1(x))) -// compute the matrix-vector multiplication T * x -// -// The algorithm here is written under the assumption x = G1 elements, T scalars -// -// For clarity, vectors in "Fourier space" are written with _fft. So for example, the vector -// xext is the extended x vector (padded with zero), and xext_fft is its Fourier transform. - -// Performs the first part of the Toeplitz matrix multiplication algorithm, which is a Fourier -// transform of the vector x extended -func (ks *KZGSettings) toeplitzPart1(x []bls.G1Point) []bls.G1Point { - n := uint64(len(x)) - n2 := n * 2 - // Extend x with zeros (neutral element of G1) - xExt := make([]bls.G1Point, n2) - for i := uint64(0); i < n; i++ { - bls.CopyG1(&xExt[i], &x[i]) - } - for i := n; i < n2; i++ { - bls.CopyG1(&xExt[i], &bls.ZeroG1) - } - xExtFFT, err := ks.FFTG1(xExt, false) - if err != nil { - panic(fmt.Errorf("FFT G1 failed in toeplitz part 1: %v", err)) - } - return xExtFFT -} - -// Performs the second part of the Toeplitz matrix multiplication algorithm -func (ks *KZGSettings) ToeplitzPart2(toeplitzCoeffs []bls.Fr, xExtFFT []bls.G1Point) (hExtFFT []bls.G1Point) { - if uint64(len(toeplitzCoeffs)) != uint64(len(xExtFFT)) { - panic("expected toeplitz coeffs to match xExtFFT length") - } - toeplitzCoeffsFFT, err := ks.FFT(toeplitzCoeffs, false) - if err != nil { - panic(fmt.Errorf("FFT failed in toeplitz part 2: %v", err)) - } - n := uint64(len(toeplitzCoeffsFFT)) - hExtFFT = make([]bls.G1Point, n) - for i := uint64(0); i < n; i++ { - bls.MulG1(&hExtFFT[i], &xExtFFT[i], &toeplitzCoeffsFFT[i]) - } - return hExtFFT -} - -// Transform back and return the first half of the vector -func (ks *KZGSettings) ToeplitzPart3(hExtFFT []bls.G1Point) []bls.G1Point { - out, err := ks.FFTG1(hExtFFT, true) - if err != nil { - panic(fmt.Errorf("toeplitz part 3 err: %v", err)) - } - // Only the top half is the Toeplitz product, the rest is padding - return out[:len(out)/2] -} - -func (ks *KZGSettings) toeplitzCoeffsStepStrided(polynomial []bls.Fr, offset uint64, stride uint64) []bls.Fr { - n := uint64(len(polynomial)) - k := n / stride - k2 := k * 2 - // [last poly item] + [0]*(n+1) + [poly items except first and last] - toeplitzCoeffs := make([]bls.Fr, k2) - bls.CopyFr(&toeplitzCoeffs[0], &polynomial[n-1-offset]) - for i := uint64(1); i <= k+1; i++ { - bls.CopyFr(&toeplitzCoeffs[i], &bls.ZERO) - } - for i, j := k+2, 2*stride-offset-1; i < k2; i, j = i+1, j+stride { - bls.CopyFr(&toeplitzCoeffs[i], &polynomial[j]) - } - return toeplitzCoeffs -} - -// TODO: call above with offset=0, stride=1 -func (ks *KZGSettings) toeplitzCoeffsStep(polynomial []bls.Fr) []bls.Fr { - n := uint64(len(polynomial)) - n2 := n * 2 - // [last poly item] + [0]*(n+1) + [poly items except first and last] - toeplitzCoeffs := make([]bls.Fr, n2) - bls.CopyFr(&toeplitzCoeffs[0], &polynomial[n-1]) - for i := uint64(1); i <= n+1; i++ { - bls.CopyFr(&toeplitzCoeffs[i], &bls.ZERO) - } - for i, j := n+2, 1; i < n2; i, j = i+1, j+1 { - bls.CopyFr(&toeplitzCoeffs[i], &polynomial[j]) - } - return toeplitzCoeffs -} - -// Compute all n (single) proofs according to FK20 method -// func (fk *FK20SingleSettings) FK20Single(polynomial []bls.Fr) []bls.G1Point { -// toeplitzCoeffs := fk.toeplitzCoeffsStep(polynomial) -// // Compute the vector h from the paper using a Toeplitz matrix multiplication -// hExtFFT := fk.ToeplitzPart2(toeplitzCoeffs, fk.xExtFFT) -// h := fk.ToeplitzPart3(hExtFFT) - -// // TODO: correct? It will pad up implicitly again, but -// out, err := fk.FFTG1(h, false) -// if err != nil { -// panic(err) -// } -// return out -// } - -// Special version of the FK20 for the situation of data availability checks: -// The upper half of the polynomial coefficients is always 0, so we do not need to extend to twice the size -// for Toeplitz matrix multiplication -func (fk *FK20SingleSettings) FK20SingleDAOptimized(polynomial []bls.Fr) []bls.G1Point { - if uint64(len(polynomial)) > fk.MaxWidth { - panic(fmt.Errorf( - "expected input of length %d (incl half of zeroes) to not exceed precomputed settings length %d", - len(polynomial), fk.MaxWidth)) - } - n2 := uint64(len(polynomial)) - if !bls.IsPowerOfTwo(n2) { - panic(fmt.Errorf("expected input length to be power of two, got %d", n2)) - } - n := n2 / 2 - for i := n; i < n2; i++ { - if !bls.EqualZero(&polynomial[i]) { - panic("bad input, second half should be zeroed") - } - } - reducedPoly := polynomial[:n] - toeplitzCoeffs := fk.toeplitzCoeffsStep(reducedPoly) - // Compute the vector h from the paper using a Toeplitz matrix multiplication - hExtFFT := fk.ToeplitzPart2(toeplitzCoeffs, fk.xExtFFT) - h := fk.ToeplitzPart3(hExtFFT) - - // Now redo the padding before final step. - // Instead of copying h into a new extended array, just reuse the old capacity. - h = h[:n2] - for i := n; i < n2; i++ { - bls.CopyG1(&h[i], &bls.ZeroG1) - } - out, err := fk.FFTG1(h, false) - if err != nil { - panic(err) - } - return out -} - -// Computes all the KZG proofs for data availability checks. This involves sampling on the double domain -// and reordering according to reverse bit order -func (fk *FK20SingleSettings) DAUsingFK20(polynomial []bls.Fr) ([]bls.G1Point, error) { - n := uint64(len(polynomial)) - if n > fk.MaxWidth/2 { - panic("expected poly contents not bigger than half the size of the FK20-single settings") - } - if !bls.IsPowerOfTwo(n) { - panic("expected poly length to be power of two") - } - n2 := n * 2 - extendedPolynomial := make([]bls.Fr, n2) - for i := uint64(0); i < n; i++ { - bls.CopyFr(&extendedPolynomial[i], &polynomial[i]) - } - for i := n; i < n2; i++ { - bls.CopyFr(&extendedPolynomial[i], &bls.ZERO) - } - allProofs := fk.FK20SingleDAOptimized(extendedPolynomial) - // change to reverse bit order. - err := reverseBitOrderG1(allProofs) - return allProofs, err -} diff --git a/pkg/kzg/fk20_single_test.go b/pkg/kzg/fk20_single_test.go deleted file mode 100644 index bb51743a30..0000000000 --- a/pkg/kzg/fk20_single_test.go +++ /dev/null @@ -1,62 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -//go:build !bignum_pure && !bignum_hol256 -// +build !bignum_pure,!bignum_hol256 - -package kzg - -import ( - "testing" - - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestKZGSettings_DAUsingFK20(t *testing.T) { - fs := NewFFTSettings(5) - s1, s2 := GenerateTestingSetup("1927409816240961209460912649124", 32+1) - srs, _ := NewSrs(s1, s2) - ks, _ := NewKZGSettings(fs, srs) - fk := NewFK20SingleSettings(ks, 32) - - polynomial := testPoly(1, 2, 3, 4, 7, 7, 7, 7, 13, 13, 13, 13, 13, 13, 13, 13) - commitment := ks.CommitToPoly(polynomial) - allProofs, err := fk.DAUsingFK20(polynomial) - require.Nil(t, err, "could not compute proof") - require.NotNil(t, allProofs) - - // Now check a random position - pos := uint64(9) - var posFr bls.Fr - bls.AsFr(&posFr, pos) - var x bls.Fr - bls.CopyFr(&x, &ks.ExpandedRootsOfUnity[pos]) - var y bls.Fr - bls.EvalPolyAt(&y, polynomial, &x) - - proof := &allProofs[reverseBitsLimited(uint32(2*16), uint32(pos))] - assert.True(t, ks.CheckProofSingle(commitment, proof, &x, &y), "could not verify proof") -} diff --git a/pkg/kzg/integration_test.go b/pkg/kzg/integration_test.go deleted file mode 100644 index 23ff80d44b..0000000000 --- a/pkg/kzg/integration_test.go +++ /dev/null @@ -1,184 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//go:build !bignum_pure && !bignum_hol256 -// +build !bignum_pure,!bignum_hol256 - -package kzg - -import ( - "testing" -) - -// setup: -// alloc random application data -// change to reverse bit order -// extend data -// compute commitment over extended data -// func integrationTestSetup(scale uint8, seed int64) (data []byte, extended []bls.Fr, extendedAsPoly []bls.Fr, commit *bls.G1Point, ks *KZGSettings) { -// points := 1 << scale -// size := points * 31 -// data = make([]byte, size) -// rng := rand.New(rand.NewSource(seed)) -// rng.Read(data) -// for i := 0; i < 100; i++ { -// data[i] = 0 -// } -// evenPoints := make([]bls.Fr, points) -// // fr nums are set from little-endian ints. The upper byte is always zero for input data. -// // 5/8 top bits are unused, other 3 out of range for modulus. -// var tmp [32]byte -// for i := 0; i < points; i++ { -// copy(tmp[:31], data[i*31:(i+1)*31]) -// bls.FrFrom32(&evenPoints[i], tmp) -// } -// reverseBitOrderFr(evenPoints) -// oddPoints := make([]bls.Fr, points) -// for i := 0; i < points; i++ { -// bls.CopyFr(&oddPoints[i], &evenPoints[i]) -// } -// // scale is 1 bigger here, since extended data is twice as big -// fs := NewFFTSettings(scale + 1) -// // convert even points (previous contents of array) to odd points -// fs.DASFFTExtension(oddPoints) -// extended = make([]bls.Fr, points*2) -// for i := 0; i < len(extended); i += 2 { -// bls.CopyFr(&extended[i], &evenPoints[i/2]) -// bls.CopyFr(&extended[i+1], &oddPoints[i/2]) -// } -// s1, s2 := GenerateTestingSetup("1927409816240961209460912649124", uint64(len(extended))) -// srs, _ := NewSrs(s1, s2) -// ks, _ = NewKZGSettings(fs, srs) -// // get coefficient form (half of this is zeroes, but ok) -// coeffs, err := ks.FFT(extended, true) -// if err != nil { -// panic(err) -// } -// debugFrs("poly", coeffs) -// extendedAsPoly = coeffs -// // the 2nd half is all zeroes, can ignore it for faster commitment. -// commit = ks.CommitToPoly(coeffs[:points]) -// return -// } - -// TODO: make it pass? -// func TestFullDAS(t *testing.T) { -// data, extended, extendedAsPoly, commit, ks := integrationTestSetup(10, 1234) -// // undo the bit-reverse ordering of the extended data (which was prepared after reverse-bit ordering the input data) -// reverseBitOrderFr(extended) -// debugFrs("extended data (reordered to original)", extended) - -// cosetWidth := uint64(128) -// fk := NewFK20MultiSettings(ks, ks.MaxWidth, cosetWidth) -// // compute proofs for cosets -// proofs := fk.FK20MultiDAOptimized(extendedAsPoly) - -// // package data of cosets with respective proofs -// sampleCount := uint64(len(extended)) / cosetWidth -// samples := make([]sample, sampleCount, sampleCount) -// for i := uint64(0); i < sampleCount; i++ { -// sample := &samples[i] - -// // we can just select it from the original points -// sample.sub = make([]bls.Fr, cosetWidth, cosetWidth) -// for j := uint64(0); j < cosetWidth; j++ { -// bls.CopyFr(&sample.sub[j], &extended[i*cosetWidth+j]) -// } -// debugFrs("sample pre-order", sample.sub) - -// // construct that same coset from the polynomial form, to make sure we have the correct points. -// domainPos := reverseBitsLimited(uint32(sampleCount), uint32(i)) - -// sample.proof = &proofs[domainPos] -// } -// // skip sample serialization/deserialization, no network to transfer data here. - -// // verify cosets individually -// extSize := sampleCount * cosetWidth -// domainStride := ks.MaxWidth / extSize -// for i, sample := range samples { -// var x bls.Fr -// domainPos := uint64(reverseBitsLimited(uint32(sampleCount), uint32(i))) -// bls.CopyFr(&x, &ks.ExpandedRootsOfUnity[domainPos*domainStride]) -// reverseBitOrderFr(sample.sub) // match poly order -// val, err := ks.CheckProofMulti(commit, sample.proof, &x, sample.sub) - -// require.Nil(t, err, "failed to verify proof of sample %d", i) -// assert.True(t, val, "failed to verify proof of sample %d", i) - -// reverseBitOrderFr(sample.sub) // match original data order -// } - -// // make some samples go missing -// partialReconstructed := make([]*bls.Fr, extSize, extSize) -// rng := rand.New(rand.NewSource(42)) -// missing := 0 -// for i, sample := range samples { // samples are already ordered in original data order -// // make a random subset (but <= 1/2) go missing. -// if rng.Int31n(2) == 0 && missing < len(samples)/2 { -// t.Logf("not using sample %d", i) -// missing++ -// continue -// } - -// offset := uint64(i) * cosetWidth -// for j := uint64(0); j < cosetWidth; j++ { -// partialReconstructed[offset+j] = &sample.sub[j] -// } -// } -// // samples were slices of reverse-bit-ordered data. Undo that order first, then IFFT will match the polynomial. -// reverseBitOrderFrPtr(partialReconstructed) -// // recover missing data -// recovered, err := ks.ErasureCodeRecover(partialReconstructed) -// require.Nil(t, err) - -// // apply reverse bit-ordering again to get original data into first half -// reverseBitOrderFr(recovered) -// debugFrs("recovered", recovered) - -// for i := 0; i < len(recovered); i++ { -// assert.True(t, bls.EqualFr(&extended[i], &recovered[i]), -// "diff %d: %s <> %s", i, bls.FrStr(&extended[i]), bls.FrStr(&recovered[i])) -// } -// // take first half, convert back to bytes -// size := extSize / 2 -// reconstructedData := make([]byte, size*31, size*31) -// for i := uint64(0); i < size; i++ { -// p := bls.FrTo32(&recovered[i]) -// copy(reconstructedData[i*31:(i+1)*31], p[:31]) -// } - -// // check that data matches original -// assert.Equal(t, data, reconstructedData, "failed to reconstruct original data") -// } - -func TestFullUser(t *testing.T) { - // setup: - // alloc random application data - // change to reverse bit order - // extend data - // compute commitment over extended data - - // construct application-layer proof for some random points - // verify application-layer proof -} diff --git a/pkg/kzg/kzg.go b/pkg/kzg/kzg.go deleted file mode 100644 index 77f55cac50..0000000000 --- a/pkg/kzg/kzg.go +++ /dev/null @@ -1,129 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -//go:build !bignum_pure && !bignum_hol256 -// +build !bignum_pure,!bignum_hol256 - -package kzg - -import ( - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" -) - -type KZGSettings struct { - *FFTSettings - - Srs *SRS - // setup values -} - -func NewKZGSettings(fs *FFTSettings, srs *SRS) (*KZGSettings, error) { - - ks := &KZGSettings{ - FFTSettings: fs, - Srs: srs, - } - - return ks, nil -} - -type FK20SingleSettings struct { - *KZGSettings - xExtFFT []bls.G1Point -} - -func NewFK20SingleSettings(ks *KZGSettings, n2 uint64) *FK20SingleSettings { - if n2 > ks.MaxWidth { - panic("extended size is larger than kzg settings supports") - } - if !bls.IsPowerOfTwo(n2) { - panic("extended size is not a power of two") - } - if n2 < 2 { - panic("extended size is too small") - } - n := n2 / 2 - fk := &FK20SingleSettings{ - KZGSettings: ks, - } - x := make([]bls.G1Point, n) - for i, j := uint64(0), n-2; i < n-1; i, j = i+1, j-1 { - bls.CopyG1(&x[i], &ks.Srs.G1[j]) - } - bls.CopyG1(&x[n-1], &bls.ZeroG1) - fk.xExtFFT = fk.toeplitzPart1(x) - return fk -} - -type FK20MultiSettings struct { - *KZGSettings - chunkLen uint64 - // chunkLen files, each of size MaxWidth - xExtFFTFiles [][]bls.G1Point -} - -func NewFK20MultiSettings(ks *KZGSettings, n2 uint64, chunkLen uint64) *FK20MultiSettings { - if n2 > ks.MaxWidth { - panic("extended size is larger than kzg settings supports") - } - if !bls.IsPowerOfTwo(n2) { - panic("extended size is not a power of two") - } - if n2 < 2 { - panic("extended size is too small") - } - if chunkLen > n2/2 { - panic("chunk length is too large") - } - if !bls.IsPowerOfTwo(chunkLen) { - panic("chunk length must be power of two") - } - if chunkLen < 1 { - panic("chunk length is too small") - } - fk := &FK20MultiSettings{ - KZGSettings: ks, - chunkLen: chunkLen, - xExtFFTFiles: make([][]bls.G1Point, chunkLen), - } - // xext_fft = [] - // for i in range(l): - // x = setup[0][n - l - 1 - i::-l] + [b.Z1] - // xext_fft.append(toeplitz_part1(x)) - n := n2 / 2 - k := n / chunkLen - xExtFFTPrecompute := func(offset uint64) []bls.G1Point { - x := make([]bls.G1Point, k) - start := n - chunkLen - 1 - offset - for i, j := uint64(0), start; i+1 < k; i, j = i+1, j-chunkLen { - bls.CopyG1(&x[i], &ks.Srs.G1[j]) - } - bls.CopyG1(&x[k-1], &bls.ZeroG1) - return ks.toeplitzPart1(x) - } - for i := uint64(0); i < chunkLen; i++ { - fk.xExtFFTFiles[i] = xExtFFTPrecompute(i) - } - return fk -} diff --git a/pkg/kzg/kzg_multi_proofs.go b/pkg/kzg/kzg_multi_proofs.go deleted file mode 100644 index b82c8386e1..0000000000 --- a/pkg/kzg/kzg_multi_proofs.go +++ /dev/null @@ -1,123 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -// Original: https://github.com/ethereum/research/blob/master/kzg_data_availability/kzg_proofs.py - -//go:build !bignum_pure && !bignum_hol256 -// +build !bignum_pure,!bignum_hol256 - -package kzg - -import ( - "log" - - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" -) - -// Compute KZG proof for polynomial in coefficient form at positions x * w^y where w is -// an n-th root of unity (this is the proof for one data availability sample, which consists -// of several polynomial evaluations) -func (ks *KZGSettings) ComputeProofMulti(poly []bls.Fr, x uint64, n uint64) *bls.G1Point { - // divisor = [-pow(x, n, MODULUS)] + [0] * (n - 1) + [1] - divisor := make([]bls.Fr, n+1) - var xFr bls.Fr - bls.AsFr(&xFr, x) - // TODO: inefficient, could use squaring, or maybe BLS lib offers a power method? - // TODO: for small ranges, maybe compute pow(x, n, mod) in uint64? - var xPowN, tmp bls.Fr - for i := uint64(0); i < n; i++ { - bls.MulModFr(&tmp, &xPowN, &xFr) - bls.CopyFr(&xPowN, &tmp) - } - - // -pow(x, n, MODULUS) - bls.SubModFr(&divisor[0], &bls.ZERO, &xPowN) - // [0] * (n - 1) - for i := uint64(1); i < n; i++ { - bls.CopyFr(&divisor[i], &bls.ZERO) - } - // 1 - bls.CopyFr(&divisor[n], &bls.ONE) - - // quot = poly / divisor - quotientPolynomial := PolyLongDiv(poly, divisor[:]) - //for i := 0; i < len(quotientPolynomial); i++ { - // fmt.Printf("quot poly %d: %s\n", i, FrStr("ientPolynomial[i])) - //} - - // evaluate quotient poly at shared secret, in G1 - return bls.LinCombG1(ks.Srs.G1[:len(quotientPolynomial)], quotientPolynomial) -} - -// Check a proof for a KZG commitment for an evaluation f(x w^i) = y_i -// The ys must have a power of 2 length -func (ks *KZGSettings) CheckProofMulti(commitment *bls.G1Point, proof *bls.G1Point, x *bls.Fr, ys []bls.Fr) (bool, error) { - // Interpolate at a coset. Note because it is a coset, not the subgroup, we have to multiply the - // polynomial coefficients by x^i - interpolationPoly, err := ks.FFT(ys, true) - if err != nil { - log.Println("ys is bad, cannot compute FFT", err) - return false, err - } - // TODO: can probably be optimized - // apply div(c, pow(x, i, MODULUS)) to every coeff c in interpolationPoly - // x^0 at first, then up to x^n - var xPow bls.Fr - bls.CopyFr(&xPow, &bls.ONE) - - var tmp, tmp2 bls.Fr - for i := 0; i < len(interpolationPoly); i++ { - bls.InvModFr(&tmp, &xPow) - bls.MulModFr(&tmp2, &interpolationPoly[i], &tmp) - bls.CopyFr(&interpolationPoly[i], &tmp2) - bls.MulModFr(&tmp, &xPow, x) - bls.CopyFr(&xPow, &tmp) - } - // [x^n]_2 - var xn2 bls.G2Point - bls.MulG2(&xn2, &bls.GenG2, &xPow) - // [s^n - x^n]_2 - var xnMinusYn bls.G2Point - bls.SubG2(&xnMinusYn, &ks.Srs.G2[len(ys)], &xn2) - - // fmt.Println("CheckMultiProof") - // for i := 0; i < len(interpolationPoly); i++ { - // fmt.Println(i, interpolationPoly[i].String()) - // } - - // [interpolation_polynomial(s)]_1 - is1 := bls.LinCombG1(ks.Srs.G1[:len(interpolationPoly)], interpolationPoly) - // [commitment - interpolation_polynomial(s)]_1 = [commit]_1 - [interpolation_polynomial(s)]_1 - var commitMinusInterpolation bls.G1Point - bls.SubG1(&commitMinusInterpolation, commitment, is1) - - // Verify the pairing equation - // - // e([commitment - interpolation_polynomial(s)], [1]) = e([proof], [s^n - x^n]) - // equivalent to - // e([commitment - interpolation_polynomial]^(-1), [1]) * e([proof], [s^n - x^n]) = 1_T - // - - return bls.PairingsVerify(&commitMinusInterpolation, &bls.GenG2, proof, &xnMinusYn), nil -} diff --git a/pkg/kzg/kzg_multi_proofs_test.go b/pkg/kzg/kzg_multi_proofs_test.go deleted file mode 100644 index 4634337dd6..0000000000 --- a/pkg/kzg/kzg_multi_proofs_test.go +++ /dev/null @@ -1,67 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -//go:build !bignum_pure && !bignum_hol256 -// +build !bignum_pure,!bignum_hol256 - -package kzg - -import ( - "testing" - - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestKZGSettings_CheckProofMulti(t *testing.T) { - fs := NewFFTSettings(4) - s1, s2 := GenerateTestingSetup("1927409816240961209460912649124", 16+1) - srs, _ := NewSrs(s1, s2) - ks, _ := NewKZGSettings(fs, srs) - polynomial := testPoly(1, 2, 3, 4, 7, 7, 7, 7, 13, 13, 13, 13, 13, 13, 13, 13) - - commitment := ks.CommitToPoly(polynomial) - - x := uint64(5431) - var xFr bls.Fr - bls.AsFr(&xFr, x) - cosetScale := uint8(3) - coset := make([]bls.Fr, 1< 0; i-- { - bls.MulModFr(&outputs[i-1], &partials[i-1], &inv) - bls.CopyFr(&tmp, &inv) - bls.MulModFr(&inv, &tmp, &values[i-1]) - } - return outputs -} - -// Generates q(x) = poly(k * x) -func pOfKX(poly []bls.Fr, k *bls.Fr) []bls.Fr { - out := make([]bls.Fr, len(poly)) - powerOfK := bls.ONE - var tmp bls.Fr - for i := range poly { - bls.MulModFr(&out[i], &poly[i], &powerOfK) - bls.CopyFr(&tmp, &powerOfK) - bls.MulModFr(&powerOfK, &tmp, k) - } - return out -} - -func inefficientOddEvenDiv2(positions []uint64) (even []uint64, odd []uint64) { // TODO optimize away - for _, p := range positions { - if p&1 == 0 { - even = append(even, p>>1) - } else { - odd = append(odd, p>>1) - } - } - return -} - -// Return (x - root**positions[0]) * (x - root**positions[1]) * ... -// possibly with a constant factor offset -func (fs *FFTSettings) _zPoly(positions []uint64, rootsOfUnityStride uint64) []bls.Fr { - // If there are not more than 4 positions, use the naive - // O(n^2) algorithm as it is faster - if len(positions) <= 4 { - /* - root = [1] - for pos in positions: - x = roots_of_unity[pos] - root.insert(0, 0) - for j in range(len(root)-1): - root[j] -= root[j+1] * x - return [x % modulus for x in root] - */ - root := make([]bls.Fr, len(positions)+1) - root[0] = bls.ONE - i := 1 - var v bls.Fr - var tmp bls.Fr - for _, pos := range positions { - x := &fs.ExpandedRootsOfUnity[pos*rootsOfUnityStride] - root[i] = bls.ZERO - for j := i; j >= 1; j-- { - bls.MulModFr(&v, &root[j-1], x) - bls.CopyFr(&tmp, &root[j]) - bls.SubModFr(&root[j], &tmp, &v) - } - i++ - } - // We did the reverse representation of 'root' as the python code, to not insert at the start all the time. - // Now turn it back around. - for i, j := 0, len(root)-1; i < j; i, j = i+1, j-1 { - root[i], root[j] = root[j], root[i] - } - return root - } - // Recursively find the zpoly for even indices and odd - // indices, operating over a half-size subgroup in each case - evenPositions, oddPositions := inefficientOddEvenDiv2(positions) - left := fs._zPoly(evenPositions, rootsOfUnityStride<<1) - right := fs._zPoly(oddPositions, rootsOfUnityStride<<1) - invRoot := &fs.ReverseRootsOfUnity[rootsOfUnityStride] - // Offset the result for the odd indices, and combine the two - out := fs.mulPolysWithFFT(left, pOfKX(right, invRoot), rootsOfUnityStride) - // Deal with the special case where mul_polys returns zero - // when it should return x ^ (2 ** k) - 1 - isZero := true - for i := range out { - if !bls.EqualZero(&out[i]) { - isZero = false - break - } - } - if isZero { - // TODO: it's [1] + [0] * (len(out) - 1) + [modulus - 1] in python, but strange it's 1 larger than out - out[0] = bls.ONE - for i := 1; i < len(out); i++ { - out[i] = bls.ZERO - } - last := bls.MODULUS_MINUS1 - out = append(out, last) - return out - } else { - return out - } -} - -// TODO test unhappy case -const maxRecoverAttempts = 10 - -func (fs *FFTSettings) ErasureCodeRecover(vals []*bls.Fr) ([]bls.Fr, error) { - // Generate the polynomial that is zero at the roots of unity - // corresponding to the indices where vals[i] is None - positions := make([]uint64, 0) - for i := uint64(0); i < uint64(len(vals)); i++ { - if vals[i] == nil { - positions = append(positions, i) - } - } - // TODO: handle len(positions)==0 case - z := fs._zPoly(positions, fs.MaxWidth/uint64(len(vals))) - zVals, err := fs.FFT(z, false) - if err != nil { - return nil, err - } - - // Pointwise-multiply (vals filling in zero at missing spots) * z - // By construction, this equals vals * z - pTimesZVals := make([]bls.Fr, len(vals)) - for i := uint(0); i < uint(len(vals)); i++ { - if vals[i] == nil { - // 0 * zVals[i] == 0 - pTimesZVals[i] = bls.ZERO - } else { - bls.MulModFr(&pTimesZVals[i], vals[i], &zVals[i]) - } - } - pTimesZ, err := fs.FFT(pTimesZVals, true) - if err != nil { - return nil, err - } - - // Keep choosing k values until the algorithm does not fail - // Check only with primitive roots of unity - attempts := 0 - var kFr bls.Fr - var tmp bls.Fr - for k := uint64(2); attempts < maxRecoverAttempts; k++ { - bls.AsFr(&kFr, k) - // // TODO: implement this, translation of 'if pow(k, (modulus - 1) // 2, modulus) == 1:' - //someOp(&tmp, &kFr) - //if EqualOne(&tmp) { - // continue - //} - var invk bls.Fr - bls.InvModFr(&invk, &kFr) - // Convert p_times_z(x) and z(x) into new polynomials - // q1(x) = p_times_z(k*x) and q2(x) = z(k*x) - // These are likely to not be 0 at any of the evaluation points. - pTimesZOfKX := pOfKX(pTimesZ, &kFr) - pTimesZOfKXVals, err := fs.FFT(pTimesZOfKX, false) - if err != nil { - return nil, err - } - zOfKX := pOfKX(z, &kFr) - zOfKXVals, err := fs.FFT(zOfKX, false) - if err != nil { - return nil, err - } - - // Compute q1(x) / q2(x) = p(k*x) - invZOfKXVals := multiInv(zOfKXVals) - pOfKxVals := make([]bls.Fr, len(pTimesZOfKXVals)) - for i := 0; i < len(pOfKxVals); i++ { - bls.MulModFr(&pOfKxVals[i], &pTimesZOfKXVals[i], &invZOfKXVals[i]) - } - pOfKx, err := fs.FFT(pOfKxVals, true) - if err != nil { - return nil, err - } - - // Given q3(x) = p(k*x), recover p(x) - pOfX := make([]bls.Fr, len(pOfKx)) - if len(pOfKx) >= 1 { - pOfX[0] = pOfKx[0] - } - if len(pOfKx) >= 2 { - bls.MulModFr(&pOfX[1], &pOfKx[1], &invk) - invKPowI := invk - for i := 2; i < len(pOfKx); i++ { - bls.CopyFr(&tmp, &invKPowI) - bls.MulModFr(&invKPowI, &tmp, &invk) - bls.MulModFr(&pOfX[i], &pOfKx[i], &invKPowI) - } - } - output, err := fs.FFT(pOfX, false) - if err != nil { - return nil, err - } - - // Check that the output matches the input - success := true - for i, inpd := range vals { - if inpd == nil { - continue - } - if !bls.EqualFr(inpd, &output[i]) { - success = false - break - } - } - - if !success { - attempts += 1 - continue - } - // Output the evaluations if all good - return output, nil - } - return nil, fmt.Errorf("max attempts reached: %d", attempts) -} diff --git a/pkg/kzg/reverse_bit_order.go b/pkg/kzg/reverse_bit_order.go deleted file mode 100644 index b9d74fcacc..0000000000 --- a/pkg/kzg/reverse_bit_order.go +++ /dev/null @@ -1,126 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package kzg - -const ( - mask0 = ^uint32((1 << (1 << iota)) - 1) - mask1 - mask2 - mask3 - mask4 - //mask5 -) - -const ( - bit0 = uint8(1 << iota) - bit1 - bit2 - bit3 - bit4 - //bit5 -) - -// bitmagic: binary search through a uint32 to find the index (least bit being 0) of the first set bit. -// Zero is a special case, it has a 0 bit index. -// Example: -// -// (in out): (0 0), (1 0), (2 1), (3 1), (4 2), (5 2), (6 2), (7 2), (8 3), (9 3) -func bitIndex(v uint32) (out uint8) { - if v == 0 { - return 0 - } - //if v&mask5 != 0 { - // v >>= bit5 - // out |= bit5 - //} - if v&mask4 != 0 { - v >>= bit4 - out |= bit4 - } - if v&mask3 != 0 { - v >>= bit3 - out |= bit3 - } - if v&mask2 != 0 { - v >>= bit2 - out |= bit2 - } - if v&mask1 != 0 { - v >>= bit1 - out |= bit1 - } - if v&mask0 != 0 { - out |= bit0 - } - return -} - -var revByte = [256]byte{ - 0b00000000, 0b10000000, 0b01000000, 0b11000000, 0b00100000, 0b10100000, 0b01100000, 0b11100000, 0b00010000, 0b10010000, 0b01010000, 0b11010000, 0b00110000, 0b10110000, 0b01110000, 0b11110000, - 0b00001000, 0b10001000, 0b01001000, 0b11001000, 0b00101000, 0b10101000, 0b01101000, 0b11101000, 0b00011000, 0b10011000, 0b01011000, 0b11011000, 0b00111000, 0b10111000, 0b01111000, 0b11111000, - 0b00000100, 0b10000100, 0b01000100, 0b11000100, 0b00100100, 0b10100100, 0b01100100, 0b11100100, 0b00010100, 0b10010100, 0b01010100, 0b11010100, 0b00110100, 0b10110100, 0b01110100, 0b11110100, - 0b00001100, 0b10001100, 0b01001100, 0b11001100, 0b00101100, 0b10101100, 0b01101100, 0b11101100, 0b00011100, 0b10011100, 0b01011100, 0b11011100, 0b00111100, 0b10111100, 0b01111100, 0b11111100, - 0b00000010, 0b10000010, 0b01000010, 0b11000010, 0b00100010, 0b10100010, 0b01100010, 0b11100010, 0b00010010, 0b10010010, 0b01010010, 0b11010010, 0b00110010, 0b10110010, 0b01110010, 0b11110010, - 0b00001010, 0b10001010, 0b01001010, 0b11001010, 0b00101010, 0b10101010, 0b01101010, 0b11101010, 0b00011010, 0b10011010, 0b01011010, 0b11011010, 0b00111010, 0b10111010, 0b01111010, 0b11111010, - 0b00000110, 0b10000110, 0b01000110, 0b11000110, 0b00100110, 0b10100110, 0b01100110, 0b11100110, 0b00010110, 0b10010110, 0b01010110, 0b11010110, 0b00110110, 0b10110110, 0b01110110, 0b11110110, - 0b00001110, 0b10001110, 0b01001110, 0b11001110, 0b00101110, 0b10101110, 0b01101110, 0b11101110, 0b00011110, 0b10011110, 0b01011110, 0b11011110, 0b00111110, 0b10111110, 0b01111110, 0b11111110, - 0b00000001, 0b10000001, 0b01000001, 0b11000001, 0b00100001, 0b10100001, 0b01100001, 0b11100001, 0b00010001, 0b10010001, 0b01010001, 0b11010001, 0b00110001, 0b10110001, 0b01110001, 0b11110001, - 0b00001001, 0b10001001, 0b01001001, 0b11001001, 0b00101001, 0b10101001, 0b01101001, 0b11101001, 0b00011001, 0b10011001, 0b01011001, 0b11011001, 0b00111001, 0b10111001, 0b01111001, 0b11111001, - 0b00000101, 0b10000101, 0b01000101, 0b11000101, 0b00100101, 0b10100101, 0b01100101, 0b11100101, 0b00010101, 0b10010101, 0b01010101, 0b11010101, 0b00110101, 0b10110101, 0b01110101, 0b11110101, - 0b00001101, 0b10001101, 0b01001101, 0b11001101, 0b00101101, 0b10101101, 0b01101101, 0b11101101, 0b00011101, 0b10011101, 0b01011101, 0b11011101, 0b00111101, 0b10111101, 0b01111101, 0b11111101, - 0b00000011, 0b10000011, 0b01000011, 0b11000011, 0b00100011, 0b10100011, 0b01100011, 0b11100011, 0b00010011, 0b10010011, 0b01010011, 0b11010011, 0b00110011, 0b10110011, 0b01110011, 0b11110011, - 0b00001011, 0b10001011, 0b01001011, 0b11001011, 0b00101011, 0b10101011, 0b01101011, 0b11101011, 0b00011011, 0b10011011, 0b01011011, 0b11011011, 0b00111011, 0b10111011, 0b01111011, 0b11111011, - 0b00000111, 0b10000111, 0b01000111, 0b11000111, 0b00100111, 0b10100111, 0b01100111, 0b11100111, 0b00010111, 0b10010111, 0b01010111, 0b11010111, 0b00110111, 0b10110111, 0b01110111, 0b11110111, - 0b00001111, 0b10001111, 0b01001111, 0b11001111, 0b00101111, 0b10101111, 0b01101111, 0b11101111, 0b00011111, 0b10011111, 0b01011111, 0b11011111, 0b00111111, 0b10111111, 0b01111111, 0b11111111, -} - -func reverseBits(b uint32) uint32 { - return (uint32(revByte[uint8(b)]) << 24) | - (uint32(revByte[uint8(b>>8)]) << 16) | - (uint32(revByte[uint8(b>>16)]) << 8) | - uint32(revByte[uint8(b>>24)]) -} - -func reverseBitsLimited(length uint32, value uint32) uint32 { - unusedBitLen := 32 - bitIndex(length) - return reverseBits(value) >> unusedBitLen -} - -func reverseBitOrder(length uint32, swap func(i, j uint32)) { - if !(length > 0 || (length&(length-1) == 0)) { - panic("length is not a power of 2") - } - // swap bits: - // 00000000000000000000000000000001 -> 10000000000000000000000000000000 - // then adjust, e.g. we may only want to swap the first 4 bits: - // 10000000000000000000000000000000 >> (32 - 4) = 1000 - unusedBitLen := 32 - bitIndex(length) - for i := uint32(0); i < length; i++ { - // only swap every pair once. If pair items are equal, nothing to do, skip work. - if r := reverseBits(i) >> unusedBitLen; r > i { - swap(r, i) - } - } -} diff --git a/pkg/kzg/reverse_bit_order_test.go b/pkg/kzg/reverse_bit_order_test.go deleted file mode 100644 index 541e68bf46..0000000000 --- a/pkg/kzg/reverse_bit_order_test.go +++ /dev/null @@ -1,84 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -package kzg - -import ( - "fmt" - "math/rand" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestReverseBitOrder(t *testing.T) { - for s := 2; s < 2048; s *= 2 { - t.Run(fmt.Sprintf("size_%d", s), func(t *testing.T) { - data := make([]uint32, s) - for i := 0; i < s; i++ { - data[i] = uint32(i) - } - - reverseBitOrder(uint32(s), func(i, j uint32) { - data[i], data[j] = data[j], data[i] - }) - - for i := 0; i < s; i++ { - assert.Equal(t, reverseBitsLimited(uint32(s), uint32(i)), data[i], "bad reversal at %d", i) - expected := fmt.Sprintf("%0"+fmt.Sprintf("%d", s)+"b", i) - got := fmt.Sprintf("%0"+fmt.Sprintf("%d", s)+"b", data[i]) - assert.Equal(t, len(expected), len(got), "bad length: %d, expected %d", len(got), len(expected)) - - for j := 0; j < len(expected); j++ { - // TODO: add check - } - } - }) - } -} - -func TestRevBitorderBitIndex(t *testing.T) { - for i := 0; i < 32; i++ { - got := bitIndex(uint32(1 << i)) - assert.Equal(t, got, uint8(i), "bit index %d is wrong: %d", i, got) - } -} - -func TestReverseBits(t *testing.T) { - rng := rand.New(rand.NewSource(1234)) - for i := 0; i < 10000; i++ { - v := rng.Uint32() - expected := revStr(fmt.Sprintf("%032b", v)) - out := reverseBits(v) - got := fmt.Sprintf("%032b", out) - assert.Equal(t, expected, got, "bit mismatch: expected: %s, got: %s ", expected, got) - } -} - -func revStr(v string) string { - out := make([]byte, len(v)) - for i := 0; i < len(v); i++ { - out[i] = v[len(v)-1-i] - } - return string(out) -} diff --git a/pkg/kzg/setup.go b/pkg/kzg/setup.go deleted file mode 100644 index 96ce8a031b..0000000000 --- a/pkg/kzg/setup.go +++ /dev/null @@ -1,204 +0,0 @@ -// This code is sourced from the go-kzg Repository by protolambda. -// Original code: https://github.com/protolambda/go-kzg -// MIT License -// -// Copyright (c) 2020 @protolambda -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -//go:build !bignum_pure && !bignum_hol256 -// +build !bignum_pure,!bignum_hol256 - -package kzg - -import ( - bls "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" - - "bufio" - "fmt" - "log" - "os" - "strconv" - "time" -) - -// GenerateTestingSetup creates a setup of n values from the given secret. **for testing purposes only** -func GenerateTestingSetup(secret string, n uint64) ([]bls.G1Point, []bls.G2Point) { - var s bls.Fr - bls.SetFr(&s, secret) - - var sPow bls.Fr - bls.CopyFr(&sPow, &bls.ONE) - - s1Out := make([]bls.G1Point, n) - s2Out := make([]bls.G2Point, n) - for i := uint64(0); i < n; i++ { - bls.MulG1(&s1Out[i], &bls.GenG1, &sPow) - bls.MulG2(&s2Out[i], &bls.GenG2, &sPow) - var tmp bls.Fr - bls.CopyFr(&tmp, &sPow) - bls.MulModFr(&sPow, &tmp, &s) - } - return s1Out, s2Out -} - -// func ReadGeneatorPoints(n uint64, g1FilePath, g2FilePath string) ([]bls.G1Point, []bls.G2Point, error) { -// g1f, err := os.Open(g1FilePath) -// if err != nil { -// log.Println("ReadGeneatorPoints.ERR.0", err) -// return nil, nil, err -// } -// g2f, err := os.Open(g2FilePath) -// if err != nil { -// log.Println("ReadGeneatorPoints.ERR.1", err) -// return nil, nil, err -// } -// //todo: handle panic -// defer func() { -// if err := g1f.Close(); err != nil { -// panic(err) -// } -// if err := g2f.Close(); err != nil { -// panic(err) -// } -// }() - -// start := time.Now() -// g1r := bufio.NewReaderSize(g1f, int(n*64)) -// g2r := bufio.NewReaderSize(g2f, int(n*128)) - -// g1Bytes, _, err := g1r.ReadLine() -// if err != nil { -// log.Println("ReadGeneatorPoints.ERR.2", err) -// return nil, nil, err -// } - -// g2Bytes, _, err := g2r.ReadLine() -// if err != nil { -// log.Println("ReadGeneatorPoints.ERR.3", err) -// return nil, nil, err -// } - -// if uint64(len(g1Bytes)) < 64*n { -// log.Printf("Error. Insufficient G1 points. Only contains %v. Requesting %v\n", len(g1Bytes)/64, n) -// log.Println() -// log.Println("ReadGeneatorPoints.ERR.4", err) -// return nil, nil, err -// } -// if uint64(len(g2Bytes)) < 128*n { -// log.Printf("Error. Insufficient G2 points. Only contains %v. Requesting %v\n", len(g1Bytes)/128, n) -// log.Println() -// log.Println("ReadGeneatorPoints.ERR.5", err) -// return nil, nil, err -// } - -// // measure reading time -// t := time.Now() -// elapsed := t.Sub(start) -// fmt.Println(" Reading G1 G2 raw points takes", elapsed) -// start = time.Now() - -// s1Outs := make([]bls.G1Point, n, n) -// s2Outs := make([]bls.G2Point, n, n) -// for i := uint64(0); i < n; i++ { -// g1 := g1Bytes[i*64 : (i+1)*128] -// err := s1Outs[i].UnmarshalText(g1[:]) -// if err != nil { -// log.Println("ReadGeneatorPoints.ERR.6", err) -// return nil, nil, err -// } - -// g2 := g2Bytes[i*128 : (i+1)*128] -// err = s2Outs[i].UnmarshalText(g2[:]) -// if err != nil { -// log.Println("ReadGeneatorPoints.ERR.7", err) -// return nil, nil, err -// } -// } - -// // measure parsing time -// t = time.Now() -// elapsed = t.Sub(start) -// fmt.Println(" Parsing G1 G2 to crypto data struct takes", elapsed) -// return s1Outs, s2Outs, nil -// } - -func WriteGeneratorPoints(n uint64) error { - secret := "1927409816240961209460912649125" - ns := strconv.Itoa(int(n)) - - var s bls.Fr - bls.SetFr(&s, secret) - - var sPow bls.Fr - bls.CopyFr(&sPow, &bls.ONE) - - g1f, err := os.Create("g1.point." + ns) - if err != nil { - log.Println("WriteGeneratorPoints.ERR.0", err) - return err - } - - g1w := bufio.NewWriter(g1f) - g2f, err := os.Create("g2.point." + ns) - if err != nil { - log.Println("WriteGeneratorPoints.ERR.1", err) - return err - } - g2w := bufio.NewWriter(g2f) - - //delimiter := [1]byte{'\n'} - - start := time.Now() - for i := uint64(0); i < n; i++ { - var s1Out bls.G1Point - var s2Out bls.G2Point - bls.MulG1(&s1Out, &bls.GenG1, &sPow) - bls.MulG2(&s2Out, &bls.GenG2, &sPow) - - g1Byte := s1Out.MarshalText() - if _, err := g1w.Write(g1Byte); err != nil { - log.Println("WriteGeneratorPoints.ERR.3", err) - return err - } - - g2Byte := s2Out.MarshalText() - if _, err := g2w.Write(g2Byte); err != nil { - log.Println("WriteGeneratorPoints.ERR.5", err) - return err - } - - var tmp bls.Fr - bls.CopyFr(&tmp, &sPow) - bls.MulModFr(&sPow, &tmp, &s) - } - - if err = g1w.Flush(); err != nil { - log.Println("WriteGeneratorPoints.ERR.6", err) - return err - } - if err = g2w.Flush(); err != nil { - log.Println("WriteGeneratorPoints.ERR.7", err) - return err - } - t := time.Now() - elapsed := t.Sub(start) - fmt.Println("Generating takes", elapsed) - return nil -} diff --git a/retriever/cmd/main.go b/retriever/cmd/main.go index 089dd2e99b..4748d9e8e0 100644 --- a/retriever/cmd/main.go +++ b/retriever/cmd/main.go @@ -16,7 +16,7 @@ import ( "github.com/Layr-Labs/eigenda/core/eth" coreindexer "github.com/Layr-Labs/eigenda/core/indexer" "github.com/Layr-Labs/eigenda/core/thegraph" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/Layr-Labs/eigenda/retriever" retrivereth "github.com/Layr-Labs/eigenda/retriever/eth" "github.com/Layr-Labs/eigenda/retriever/flags" diff --git a/retriever/config.go b/retriever/config.go index 94f0ab4998..ddf040e142 100644 --- a/retriever/config.go +++ b/retriever/config.go @@ -5,14 +5,14 @@ import ( "github.com/Layr-Labs/eigenda/common/geth" "github.com/Layr-Labs/eigenda/common/logging" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" + "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/Layr-Labs/eigenda/indexer" "github.com/Layr-Labs/eigenda/retriever/flags" "github.com/urfave/cli" ) type Config struct { - EncoderConfig kzgrs.KzgConfig + EncoderConfig kzg.KzgConfig EthClientConfig geth.EthClientConfig LoggerConfig logging.Config IndexerConfig indexer.Config @@ -29,7 +29,7 @@ type Config struct { func NewConfig(ctx *cli.Context) *Config { return &Config{ - EncoderConfig: kzgrs.ReadCLIConfig(ctx), + EncoderConfig: kzg.ReadCLIConfig(ctx), EthClientConfig: geth.ReadEthClientConfig(ctx), LoggerConfig: logging.ReadCLIConfig(ctx, flags.FlagPrefix), IndexerConfig: indexer.ReadIndexerConfig(ctx), diff --git a/retriever/flags/flags.go b/retriever/flags/flags.go index fb18b9f048..f04b88c486 100644 --- a/retriever/flags/flags.go +++ b/retriever/flags/flags.go @@ -4,7 +4,7 @@ import ( "github.com/Layr-Labs/eigenda/common" "github.com/Layr-Labs/eigenda/common/geth" "github.com/Layr-Labs/eigenda/common/logging" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" + "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/Layr-Labs/eigenda/indexer" "github.com/urfave/cli" ) @@ -103,7 +103,7 @@ var Flags []cli.Flag func init() { Flags = append(requiredFlags, optionalFlags...) - Flags = append(Flags, kzgrs.CLIFlags(envPrefix)...) + Flags = append(Flags, kzg.CLIFlags(envPrefix)...) Flags = append(Flags, geth.EthClientFlags(envPrefix)...) Flags = append(Flags, logging.CLIFlags(envPrefix, FlagPrefix)...) Flags = append(Flags, indexer.CLIFlags(envPrefix)...) diff --git a/retriever/server_test.go b/retriever/server_test.go index e7aaac67dd..2a864201f1 100644 --- a/retriever/server_test.go +++ b/retriever/server_test.go @@ -13,9 +13,9 @@ import ( "github.com/Layr-Labs/eigenda/core" coremock "github.com/Layr-Labs/eigenda/core/mock" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/Layr-Labs/eigenda/retriever" "github.com/Layr-Labs/eigenda/retriever/mock" "github.com/stretchr/testify/assert" @@ -33,7 +33,7 @@ var ( ) func makeTestComponents() (encoding.Prover, encoding.Verifier, error) { - config := &kzgrs.KzgConfig{ + config := &kzg.KzgConfig{ G1Path: "../inabox/resources/kzg/g1.point", G2Path: "../inabox/resources/kzg/g2.point", CacheDir: "../inabox/resources/kzg/SRSTables", diff --git a/test/integration_test.go b/test/integration_test.go index 24c1b1b2a2..fe6ea9d0b7 100644 --- a/test/integration_test.go +++ b/test/integration_test.go @@ -16,9 +16,9 @@ import ( "time" "github.com/Layr-Labs/eigenda/common/pubip" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/prover" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/prover" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" "github.com/consensys/gnark-crypto/ecc/bn254/fp" clientsmock "github.com/Layr-Labs/eigenda/clients/mock" @@ -43,7 +43,6 @@ import ( "github.com/Layr-Labs/eigenda/encoding" "github.com/Layr-Labs/eigenda/node" nodegrpc "github.com/Layr-Labs/eigenda/node/grpc" - "github.com/Layr-Labs/eigenda/pkg/kzg/bn254" nodepb "github.com/Layr-Labs/eigenda/api/grpc/node" @@ -81,7 +80,7 @@ func init() { // makeTestEncoder makes an encoder currently using the only supported backend. func mustMakeTestComponents() (encoding.Prover, encoding.Verifier) { - config := &kzgrs.KzgConfig{ + config := &kzg.KzgConfig{ G1Path: "../inabox/resources/kzg/g1.point", G2Path: "../inabox/resources/kzg/g2.point", CacheDir: "../inabox/resources/kzg/SRSTables", @@ -561,7 +560,7 @@ func TestDispersalAndRetrieval(t *testing.T) { encodingParams := encoding.ParamsFromMins(chunkLength, info.TotalChunks) assert.NoError(t, err) - recovered, err := v.Decode(chunks, indices, encodingParams, uint64(blobHeader.Length)*bn254.BYTES_PER_COEFFICIENT) + recovered, err := v.Decode(chunks, indices, encodingParams, uint64(blobHeader.Length)*encoding.BYTES_PER_COEFFICIENT) assert.NoError(t, err) recovered = bytes.TrimRight(recovered, "\x00") assert.Equal(t, gettysburgAddressBytes, recovered) diff --git a/test/synthetic-test/synthetic_client_test.go b/test/synthetic-test/synthetic_client_test.go index 9b6b4316ab..457e87631f 100644 --- a/test/synthetic-test/synthetic_client_test.go +++ b/test/synthetic-test/synthetic_client_test.go @@ -35,8 +35,8 @@ import ( "github.com/Layr-Labs/eigenda/core/thegraph" encoder_rpc "github.com/Layr-Labs/eigenda/disperser/api/grpc/encoder" "github.com/Layr-Labs/eigenda/encoding" - "github.com/Layr-Labs/eigenda/encoding/kzgrs" - "github.com/Layr-Labs/eigenda/encoding/kzgrs/verifier" + "github.com/Layr-Labs/eigenda/encoding/kzg" + "github.com/Layr-Labs/eigenda/encoding/kzg/verifier" gcommon "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" "google.golang.org/grpc" @@ -222,7 +222,7 @@ func setupRetrievalClient(ethClient common.EthClient, retrievalClientConfig *Ret if err != nil { return err } - v, err := verifier.NewVerifier(&kzgrs.KzgConfig{ + v, err := verifier.NewVerifier(&kzg.KzgConfig{ G1Path: retrievalClientConfig.RetrieverG1Path, G2Path: retrievalClientConfig.RetrieverG2Path, CacheDir: retrievalClientConfig.RetrieverCachePath, @@ -578,7 +578,7 @@ func TestEncodeBlob(t *testing.T) { } // Test Assumes below params set for Encoder - kzgConfig := kzgrs.KzgConfig{ + kzgConfig := kzg.KzgConfig{ G1Path: "/data/kzg/g1.point", G2Path: "/data/kzg/g2.point", CacheDir: "/data/kzg/SRSTables",