From 07cf7bd8572edfb9804ad5f4dd95cacdbe6522ff Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Tue, 10 Oct 2023 22:15:01 -0700 Subject: [PATCH 01/13] Upgraded dependencies --- go.mod | 26 +++++++++++++------------- go.sum | 26 ++++++++++++++++++++++++++ goldilocks/base_test.go | 6 +++--- poseidon/public_inputs_hash_test.go | 2 +- verifier/verifier_test.go | 4 ++-- 5 files changed, 45 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 82e406c..54d78eb 100644 --- a/go.mod +++ b/go.mod @@ -3,29 +3,29 @@ module github.com/succinctlabs/gnark-plonky2-verifier go 1.19 require ( - github.com/consensys/gnark v0.7.2-0.20230620211433-d5a7678bb74a - github.com/consensys/gnark-crypto v0.11.1-0.20230609175512-0ee617fa6d43 + github.com/consensys/gnark v0.9.0 + github.com/consensys/gnark-crypto v0.11.2 ) require ( - github.com/bits-and-blooms/bitset v1.5.0 // indirect + github.com/bits-and-blooms/bitset v1.8.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fxamacker/cbor/v2 v2.4.0 // indirect - github.com/google/pprof v0.0.0-20230309165930-d61513b1440d // indirect + github.com/fxamacker/cbor/v2 v2.5.0 // indirect + github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect github.com/kr/text v0.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect - github.com/rs/zerolog v1.29.0 // indirect - github.com/stretchr/testify v1.8.2 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/rs/zerolog v1.30.0 // indirect + github.com/stretchr/testify v1.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/crypto v0.6.0 // indirect - golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb // indirect - golang.org/x/sys v0.5.0 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect + golang.org/x/sys v0.11.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect -) \ No newline at end of file +) diff --git a/go.sum b/go.sum index 9e3d146..f53e8b5 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c= +github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -8,23 +10,32 @@ github.com/consensys/gnark v0.7.2-0.20230620211433-d5a7678bb74a h1:2fkBLd+kjuh0f github.com/consensys/gnark v0.7.2-0.20230620211433-d5a7678bb74a/go.mod h1:YUwaE3A1EfViSRMaJp5kyFow4rde64AKVtqRZNPkze8= github.com/consensys/gnark v0.8.0 h1:0bQ2MyDG4oNjMQpNyL8HjrrUSSL3yYJg0Elzo6LzmcU= github.com/consensys/gnark v0.8.0/go.mod h1:aKmA7dIiLbTm0OV37xTq0z+Bpe4xER8EhRLi6necrm8= +github.com/consensys/gnark v0.9.0 h1:OoOr0Q771mQINVdP3s1AF2Rs1y8gtXhWVkadz/9KmZc= +github.com/consensys/gnark v0.9.0/go.mod h1:Sy9jJjIaGJFfNeupyNOR9Ei2IbAB6cfCO78DfG27YvM= github.com/consensys/gnark-crypto v0.9.1 h1:mru55qKdWl3E035hAoh1jj9d7hVnYY5pfb6tmovSmII= github.com/consensys/gnark-crypto v0.9.1/go.mod h1:a2DQL4+5ywF6safEeZFEPGRiiGbjzGFRUN2sg06VuU4= github.com/consensys/gnark-crypto v0.11.1-0.20230609175512-0ee617fa6d43 h1:6VCNdjn2RmxgG2ZklMmSGov9BtCNfVF4VjqAngysiPU= github.com/consensys/gnark-crypto v0.11.1-0.20230609175512-0ee617fa6d43/go.mod h1:6C2ytC8zmP8uH2GKVfPOjf0Vw3KwMAaUxlCPK5WQqmw= +github.com/consensys/gnark-crypto v0.11.2 h1:GJjjtWJ+db1xGao7vTsOgAOGgjfPe7eRGPL+xxMX0qE= +github.com/consensys/gnark-crypto v0.11.2/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= +github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE= +github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/pprof v0.0.0-20230309165930-d61513b1440d h1:um9/pc7tKMINFfP1eE7Wv6PRGXlcCSJkVajF7KJw3uQ= github.com/google/pprof v0.0.0-20230309165930-d61513b1440d/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= +github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= +github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -36,6 +47,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= @@ -44,9 +57,13 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= +github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= +github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -56,19 +73,28 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/goldilocks/base_test.go b/goldilocks/base_test.go index 3a5f490..d2a34d3 100644 --- a/goldilocks/base_test.go +++ b/goldilocks/base_test.go @@ -25,13 +25,13 @@ func TestGoldilocksRangeCheck(t *testing.T) { var circuit, witness TestGoldilocksRangeCheckCircuit witness.X = 1 - assert.ProverSucceeded(&circuit, &witness, test.WithCurves(ecc.BN254), test.WithBackends(backend.GROTH16), test.NoSerialization()) + assert.ProverSucceeded(&circuit, &witness, test.WithCurves(ecc.BN254), test.WithBackends(backend.GROTH16), test.NoSerializationChecks()) witness.X = 0 - assert.ProverSucceeded(&circuit, &witness, test.WithCurves(ecc.BN254), test.WithBackends(backend.GROTH16), test.NoSerialization()) + assert.ProverSucceeded(&circuit, &witness, test.WithCurves(ecc.BN254), test.WithBackends(backend.GROTH16), test.NoSerializationChecks()) witness.X = MODULUS - assert.ProverFailed(&circuit, &witness, test.WithCurves(ecc.BN254), test.WithBackends(backend.GROTH16), test.NoSerialization()) + assert.ProverFailed(&circuit, &witness, test.WithCurves(ecc.BN254), test.WithBackends(backend.GROTH16), test.NoSerializationChecks()) one := big.NewInt(1) maxValidVal := new(big.Int).Sub(MODULUS, one) diff --git a/poseidon/public_inputs_hash_test.go b/poseidon/public_inputs_hash_test.go index 5ff7251..e68a3bc 100644 --- a/poseidon/public_inputs_hash_test.go +++ b/poseidon/public_inputs_hash_test.go @@ -78,6 +78,6 @@ func TestPublicInputsHashWitness2(t *testing.T) { test.WithBackends(backend.GROTH16), test.WithCurves(ecc.BN254), test.NoFuzzing(), - test.NoSerialization(), + test.NoSerializationChecks(), ) } diff --git a/verifier/verifier_test.go b/verifier/verifier_test.go index 10d1790..e9cd2d5 100644 --- a/verifier/verifier_test.go +++ b/verifier/verifier_test.go @@ -82,7 +82,7 @@ func TestStepVerifier2(t *testing.T) { test.WithBackends(backend.GROTH16), test.WithCurves(ecc.BN254), test.NoFuzzing(), - test.NoSerialization(), + test.NoSerializationChecks(), ) } @@ -117,6 +117,6 @@ func TestMain(t *testing.T) { test.WithBackends(backend.GROTH16), test.WithCurves(ecc.BN254), test.NoFuzzing(), - test.NoSerialization(), + test.NoSerializationChecks(), ) } From 1c0235b35adf12ee1912d601c17c387a028be5e3 Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Tue, 10 Oct 2023 22:32:54 -0700 Subject: [PATCH 02/13] Renamed symbol a bunch in goldilocks, goldilocks tests pass --- benchmark.go | 2 +- benchmark_plonk.go | 2 +- challenger/challenger.go | 32 +++--- fri/fri.go | 20 ++-- fri/fri_test.go | 2 +- fri/fri_utils.go | 2 +- goldilocks/base.go | 113 ++++++++++--------- goldilocks/base_test.go | 8 +- goldilocks/quadratic_extension.go | 52 ++++----- goldilocks/quadratic_extension_algebra.go | 10 +- goldilocks/quadratic_extension_test.go | 4 +- goldilocks/utils.go | 4 +- plonk/gates/arithmetic_extension_gate.go | 2 +- plonk/gates/arithmetic_gate.go | 2 +- plonk/gates/base_sum_gate.go | 2 +- plonk/gates/constant_gate.go | 2 +- plonk/gates/coset_interpolation_gate.go | 2 +- plonk/gates/evaluate_gates.go | 6 +- plonk/gates/exponentiation_gate.go | 2 +- plonk/gates/gates.go | 2 +- plonk/gates/gates_test.go | 2 +- plonk/gates/multiplication_extension_gate.go | 2 +- plonk/gates/noop_gate.go | 2 +- plonk/gates/poseidon_gate.go | 2 +- plonk/gates/poseidon_mds_gate.go | 4 +- plonk/gates/public_input_gate.go | 2 +- plonk/gates/random_access_gate.go | 2 +- plonk/gates/reducing_extension_gate.go | 2 +- plonk/gates/reducing_gate.go | 2 +- plonk/plonk.go | 14 +-- poseidon/bn254.go | 14 +-- poseidon/goldilocks.go | 24 ++-- poseidon/goldilocks_test.go | 2 +- poseidon/public_inputs_hash_test.go | 4 +- types/circuit.go | 4 +- types/fri.go | 10 +- types/plonk.go | 6 +- verifier/verifier.go | 8 +- verifier/verifier_test.go | 2 +- 39 files changed, 195 insertions(+), 184 deletions(-) diff --git a/benchmark.go b/benchmark.go index 9b60a3b..7ba592f 100644 --- a/benchmark.go +++ b/benchmark.go @@ -22,7 +22,7 @@ import ( type BenchmarkPlonky2VerifierCircuit struct { Proof types.Proof - PublicInputs []gl.Variable `gnark:",public"` + PublicInputs []gl.GoldilocksVariable `gnark:",public"` verifierChip *verifier.VerifierChip `gnark:"-"` plonky2CircuitName string `gnark:"-"` diff --git a/benchmark_plonk.go b/benchmark_plonk.go index 6f7df12..d4bacfd 100644 --- a/benchmark_plonk.go +++ b/benchmark_plonk.go @@ -23,7 +23,7 @@ import ( type BenchmarkPlonky2VerifierCircuitPlonk struct { Proof types.Proof - PublicInputs []gl.Variable `gnark:",public"` + PublicInputs []gl.GoldilocksVariable `gnark:",public"` verifierChip *verifier.VerifierChip `gnark:"-"` plonky2CircuitName string `gnark:"-"` diff --git a/challenger/challenger.go b/challenger/challenger.go index b1af60b..85a35e5 100644 --- a/challenger/challenger.go +++ b/challenger/challenger.go @@ -14,15 +14,15 @@ type Chip struct { api frontend.API `gnark:"-"` poseidonChip *poseidon.GoldilocksChip poseidonBN254Chip *poseidon.BN254Chip - spongeState [poseidon.SPONGE_WIDTH]gl.Variable - inputBuffer []gl.Variable - outputBuffer []gl.Variable + spongeState [poseidon.SPONGE_WIDTH]gl.GoldilocksVariable + inputBuffer []gl.GoldilocksVariable + outputBuffer []gl.GoldilocksVariable } func NewChip(api frontend.API) *Chip { - var spongeState [poseidon.SPONGE_WIDTH]gl.Variable - var inputBuffer []gl.Variable - var outputBuffer []gl.Variable + var spongeState [poseidon.SPONGE_WIDTH]gl.GoldilocksVariable + var inputBuffer []gl.GoldilocksVariable + var outputBuffer []gl.GoldilocksVariable for i := 0; i < poseidon.SPONGE_WIDTH; i++ { spongeState[i] = gl.Zero() } @@ -38,7 +38,7 @@ func NewChip(api frontend.API) *Chip { } } -func (c *Chip) ObserveElement(element gl.Variable) { +func (c *Chip) ObserveElement(element gl.GoldilocksVariable) { c.outputBuffer = clearBuffer(c.outputBuffer) c.inputBuffer = append(c.inputBuffer, element) if len(c.inputBuffer) == poseidon.SPONGE_RATE { @@ -46,7 +46,7 @@ func (c *Chip) ObserveElement(element gl.Variable) { } } -func (c *Chip) ObserveElements(elements []gl.Variable) { +func (c *Chip) ObserveElements(elements []gl.GoldilocksVariable) { for i := 0; i < len(elements); i++ { c.ObserveElement(elements[i]) } @@ -84,7 +84,7 @@ func (c *Chip) ObserveOpenings(openings fri.Openings) { } } -func (c *Chip) GetChallenge() gl.Variable { +func (c *Chip) GetChallenge() gl.GoldilocksVariable { if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 { c.duplexing() } @@ -95,8 +95,8 @@ func (c *Chip) GetChallenge() gl.Variable { return challenge } -func (c *Chip) GetNChallenges(n uint64) []gl.Variable { - challenges := make([]gl.Variable, n) +func (c *Chip) GetNChallenges(n uint64) []gl.GoldilocksVariable { + challenges := make([]gl.GoldilocksVariable, n) for i := uint64(0); i < n; i++ { challenges[i] = c.GetChallenge() } @@ -109,13 +109,13 @@ func (c *Chip) GetExtensionChallenge() gl.QuadraticExtensionVariable { } func (c *Chip) GetHash() poseidon.GoldilocksHashOut { - return [4]gl.Variable{c.GetChallenge(), c.GetChallenge(), c.GetChallenge(), c.GetChallenge()} + return [4]gl.GoldilocksVariable{c.GetChallenge(), c.GetChallenge(), c.GetChallenge(), c.GetChallenge()} } func (c *Chip) GetFriChallenges( commitPhaseMerkleCaps []types.FriMerkleCap, finalPoly types.PolynomialCoeffs, - powWitness gl.Variable, + powWitness gl.GoldilocksVariable, degreeBits uint64, config types.FriConfig, ) types.FriChallenges { @@ -142,8 +142,8 @@ func (c *Chip) GetFriChallenges( } } -func clearBuffer(buffer []gl.Variable) []gl.Variable { - return make([]gl.Variable, 0) +func clearBuffer(buffer []gl.GoldilocksVariable) []gl.GoldilocksVariable { + return make([]gl.GoldilocksVariable, 0) } func (c *Chip) duplexing() { @@ -152,7 +152,7 @@ func (c *Chip) duplexing() { panic("something went wrong") } - glApi := gl.NewChip(c.api) + glApi := gl.NewGoldilocksApi(c.api) for i := 0; i < len(c.inputBuffer); i++ { c.spongeState[i] = glApi.Reduce(c.inputBuffer[i]) diff --git a/fri/fri.go b/fri/fri.go index 373fe01..ab8255f 100644 --- a/fri/fri.go +++ b/fri/fri.go @@ -14,8 +14,8 @@ import ( ) type Chip struct { - api frontend.API `gnark:"-"` - gl gl.Chip `gnark:"-"` + api frontend.API `gnark:"-"` + gl gl.GoldilocksApi `gnark:"-"` poseidonBN254Chip *poseidon.BN254Chip friParams *types.FriParams `gnark:"-"` } @@ -29,11 +29,11 @@ func NewChip( api: api, poseidonBN254Chip: poseidonBN254Chip, friParams: friParams, - gl: *gl.NewChip(api), + gl: *gl.NewGoldilocksApi(api), } } -func (f *Chip) assertLeadingZeros(powWitness gl.Variable, friConfig types.FriConfig) { +func (f *Chip) assertLeadingZeros(powWitness gl.GoldilocksVariable, friConfig types.FriConfig) { // Asserts that powWitness'es big-endian bit representation has at least `leading_zeros` leading zeros. // Note that this is assuming that the Goldilocks field is being used. Specfically that the // field is 64 bits long @@ -58,7 +58,7 @@ func (f *Chip) fromOpeningsAndAlpha( } func (f *Chip) verifyMerkleProofToCapWithCapIndex( - leafData []gl.Variable, + leafData []gl.GoldilocksVariable, leafIndexBits []frontend.Variable, capIndexBits []frontend.Variable, merkleCap types.FriMerkleCap, @@ -139,7 +139,7 @@ func (f *Chip) assertNoncanonicalIndicesOK() { func (f *Chip) expFromBitsConstBase( base goldilocks.Element, exponentBits []frontend.Variable, -) gl.Variable { +) gl.GoldilocksVariable { product := gl.One() for i, bit := range exponentBits { // If the bit is on, we multiply product by base^pow. @@ -167,7 +167,7 @@ func (f *Chip) expFromBitsConstBase( func (f *Chip) calculateSubgroupX( xIndexBits []frontend.Variable, nLog uint64, -) gl.Variable { +) gl.GoldilocksVariable { // Compute x from its index // `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain. // TODO - Make these as global values @@ -284,7 +284,7 @@ func (f *Chip) interpolate( } func (f *Chip) computeEvaluation( - x gl.Variable, + x gl.GoldilocksVariable, xIndexWithinCosetBits []frontend.Variable, arityBits uint64, evals []gl.QuadraticExtensionVariable, @@ -359,7 +359,7 @@ func (f *Chip) verifyQueryRound( precomputedReducedEval []gl.QuadraticExtensionVariable, initialMerkleCaps []types.FriMerkleCap, proof *types.FriProof, - xIndex gl.Variable, + xIndex gl.GoldilocksVariable, n uint64, nLog uint64, roundProof *types.FriQueryRound, @@ -437,7 +437,7 @@ func (f *Chip) verifyQueryRound( ) // Convert evals (array of QE) to fields by taking their 0th degree coefficients - fieldEvals := make([]gl.Variable, 0, 2*len(evals)) + fieldEvals := make([]gl.GoldilocksVariable, 0, 2*len(evals)) for j := 0; j < len(evals); j++ { fieldEvals = append(fieldEvals, evals[j][0]) fieldEvals = append(fieldEvals, evals[j][1]) diff --git a/fri/fri_test.go b/fri/fri_test.go index d5c0033..2faf638 100644 --- a/fri/fri_test.go +++ b/fri/fri_test.go @@ -25,7 +25,7 @@ func (circuit *TestFriCircuit) Define(api frontend.API) error { commonCircuitData := verifier.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename) verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuit.verifierOnlyCircuitDataFilename) - glApi := gl.NewChip(api) + glApi := gl.NewGoldilocksApi(api) poseidonChip := poseidon.NewGoldilocksChip(api) friChip := fri.NewChip(api, &commonCircuitData.FriParams) challengerChip := challenger.NewChip(api) diff --git a/fri/fri_utils.go b/fri/fri_utils.go index 962a36b..4f5cdc8 100644 --- a/fri/fri_utils.go +++ b/fri/fri_utils.go @@ -178,7 +178,7 @@ func friAllPolys(c *types.CommonCircuitData) []PolynomialInfo { return returnArr } -func GetInstance(c *types.CommonCircuitData, glApi *gl.Chip, zeta gl.QuadraticExtensionVariable, degreeBits uint64) InstanceInfo { +func GetInstance(c *types.CommonCircuitData, glApi *gl.GoldilocksApi, zeta gl.QuadraticExtensionVariable, degreeBits uint64) InstanceInfo { zetaBatch := BatchInfo{ Point: zeta, Polynomials: friAllPolys(c), diff --git a/goldilocks/base.go b/goldilocks/base.go index ad7b0c6..f3c4ef5 100644 --- a/goldilocks/base.go +++ b/goldilocks/base.go @@ -13,13 +13,14 @@ package goldilocks import ( "fmt" + "math" "math/big" "github.com/consensys/gnark-crypto/field/goldilocks" "github.com/consensys/gnark/constraint/solver" "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/std/math/bits" "github.com/consensys/gnark/std/math/emulated" + "github.com/consensys/gnark/std/rangecheck" ) // The multiplicative group generator of the field. @@ -45,77 +46,78 @@ func init() { solver.RegisterHint(MulAddHint) solver.RegisterHint(ReduceHint) solver.RegisterHint(InverseHint) + solver.RegisterHint(SplitLimbsHint) } // A type alias used to represent Goldilocks field elements. -type Variable struct { +type GoldilocksVariable struct { Limb frontend.Variable } // Creates a new Goldilocks field element from an existing variable. Assumes that the element is // already reduced. -func NewVariable(x frontend.Variable) Variable { - return Variable{Limb: x} +func NewVariable(x frontend.Variable) GoldilocksVariable { + return GoldilocksVariable{Limb: x} } // The zero element in the Golidlocks field. -func Zero() Variable { +func Zero() GoldilocksVariable { return NewVariable(0) } // The one element in the Goldilocks field. -func One() Variable { +func One() GoldilocksVariable { return NewVariable(1) } // The negative one element in the Goldilocks field. -func NegOne() Variable { +func NegOne() GoldilocksVariable { return NewVariable(MODULUS.Uint64() - 1) } // The chip used for Goldilocks field operations. -type Chip struct { +type GoldilocksApi struct { api frontend.API } // Creates a new Goldilocks chip. -func NewChip(api frontend.API) *Chip { - return &Chip{api: api} +func NewGoldilocksApi(api frontend.API) *GoldilocksApi { + return &GoldilocksApi{api: api} } // Adds two field elements such that x + y = z within the Golidlocks field. -func (p *Chip) Add(a Variable, b Variable) Variable { +func (p *GoldilocksApi) Add(a GoldilocksVariable, b GoldilocksVariable) GoldilocksVariable { return p.MulAdd(a, NewVariable(1), b) } // Adds two field elements such that x + y = z within the Golidlocks field without reducing. -func (p *Chip) AddNoReduce(a Variable, b Variable) Variable { +func (p *GoldilocksApi) AddNoReduce(a GoldilocksVariable, b GoldilocksVariable) GoldilocksVariable { return NewVariable(p.api.Add(a.Limb, b.Limb)) } // Subtracts two field elements such that x + y = z within the Golidlocks field. -func (p *Chip) Sub(a Variable, b Variable) Variable { +func (p *GoldilocksApi) Sub(a GoldilocksVariable, b GoldilocksVariable) GoldilocksVariable { return p.MulAdd(b, NewVariable(MODULUS.Uint64()-1), a) } // Subtracts two field elements such that x + y = z within the Golidlocks field without reducing. -func (p *Chip) SubNoReduce(a Variable, b Variable) Variable { +func (p *GoldilocksApi) SubNoReduce(a GoldilocksVariable, b GoldilocksVariable) GoldilocksVariable { return NewVariable(p.api.Add(a.Limb, p.api.Mul(b.Limb, MODULUS.Uint64()-1))) } // Multiplies two field elements such that x * y = z within the Golidlocks field. -func (p *Chip) Mul(a Variable, b Variable) Variable { +func (p *GoldilocksApi) Mul(a GoldilocksVariable, b GoldilocksVariable) GoldilocksVariable { return p.MulAdd(a, b, Zero()) } // Multiplies two field elements such that x * y = z within the Golidlocks field without reducing. -func (p *Chip) MulNoReduce(a Variable, b Variable) Variable { +func (p *GoldilocksApi) MulNoReduce(a GoldilocksVariable, b GoldilocksVariable) GoldilocksVariable { return NewVariable(p.api.Mul(a.Limb, b.Limb)) } // Multiplies two field elements and adds a field element such that x * y + z = c within the // Golidlocks field. -func (p *Chip) MulAdd(a Variable, b Variable, c Variable) Variable { +func (p *GoldilocksApi) MulAdd(a GoldilocksVariable, b GoldilocksVariable, c GoldilocksVariable) GoldilocksVariable { result, err := p.api.Compiler().NewHint(MulAddHint, 2, a.Limb, b.Limb, c.Limb) if err != nil { panic(err) @@ -136,7 +138,7 @@ func (p *Chip) MulAdd(a Variable, b Variable, c Variable) Variable { // Multiplies two field elements and adds a field element such that x * y + z = c within the // Golidlocks field without reducing. -func (p *Chip) MulAddNoReduce(a Variable, b Variable, c Variable) Variable { +func (p *GoldilocksApi) MulAddNoReduce(a GoldilocksVariable, b GoldilocksVariable, c GoldilocksVariable) GoldilocksVariable { return p.AddNoReduce(p.MulNoReduce(a, b), c) } @@ -164,7 +166,7 @@ func MulAddHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { } // Reduces a field element x such that x % MODULUS = y. -func (p *Chip) Reduce(x Variable) Variable { +func (p *GoldilocksApi) Reduce(x GoldilocksVariable) GoldilocksVariable { // Witness a `quotient` and `remainder` such that: // // MODULUS * quotient + remainder = x @@ -189,7 +191,7 @@ func (p *Chip) Reduce(x Variable) Variable { } // Reduces a field element x such that x % MODULUS = y. -func (p *Chip) ReduceWithMaxBits(x Variable, maxNbBits uint64) Variable { +func (p *GoldilocksApi) ReduceWithMaxBits(x GoldilocksVariable, maxNbBits uint64) GoldilocksVariable { // Witness a `quotient` and `remainder` such that: // // MODULUS * quotient + remainder = x @@ -224,7 +226,7 @@ func ReduceHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { } // Computes the inverse of a field element x such that x * x^-1 = 1. -func (p *Chip) Inverse(x Variable) Variable { +func (p *GoldilocksApi) Inverse(x GoldilocksVariable) GoldilocksVariable { result, err := p.api.Compiler().NewHint(InverseHint, 1, x.Limb) if err != nil { panic(err) @@ -258,7 +260,7 @@ func InverseHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { } // Computes a field element raised to some power. -func (p *Chip) Exp(x Variable, k *big.Int) Variable { +func (p *GoldilocksApi) Exp(x GoldilocksVariable, k *big.Int) GoldilocksVariable { if k.IsUint64() && k.Uint64() == 0 { return One() } @@ -279,8 +281,31 @@ func (p *Chip) Exp(x Variable, k *big.Int) Variable { return z } +// The hint used to split a GoldilocksVariable into 2 32 bit limbs. +func SplitLimbsHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { + if len(inputs) != 1 { + panic("SplitLimbsHint expects 1 input operand") + } + + // The Goldilocks field element + input := inputs[0] + + if input.Cmp(MODULUS) == 0 || input.Cmp(MODULUS) == 1 { + return fmt.Errorf("input is not in the field") + } + + two_32 := big.NewInt(int64(math.Pow(2, 32))) + + // The most significant bits + results[0] = new(big.Int).Quo(input, two_32) + // The least significant bits + results[1] = new(big.Int).Rem(input, two_32) + + return nil +} + // Range checks a field element x to be less than the Golidlocks modulus 2 ^ 64 - 2 ^ 32 + 1. -func (p *Chip) RangeCheck(x Variable) { +func (p *GoldilocksApi) RangeCheck(x GoldilocksVariable) { // The Goldilocks' modulus is 2^64 - 2^32 + 1, which is: // // 1111111111111111111111111111111100000000000000000000000000000001 @@ -288,47 +313,33 @@ func (p *Chip) RangeCheck(x Variable) { // in big endian binary. This function will first verify that x is at most 64 bits wide. Then it // checks that if the bits[0:31] (in big-endian) are all 1, then bits[32:64] are all zero. - // First decompose x into 64 bits. The bits will be in little-endian order. - bits := bits.ToBinary(p.api, x.Limb, bits.WithNbDigits(64)) - - // Those bits should compose back to x. - reconstructedX := frontend.Variable(0) - c := uint64(1) - for i := 0; i < 64; i++ { - reconstructedX = p.api.Add(reconstructedX, p.api.Mul(bits[i], c)) - c = c << 1 - p.api.AssertIsBoolean(bits[i]) - } - p.api.AssertIsEqual(x.Limb, reconstructedX) + // Use the range checker component to range-check the variable. + rangeChecker := rangecheck.New(p.api) + rangeChecker.Check(x.Limb, 64) - mostSigBits32Sum := frontend.Variable(0) - for i := 32; i < 64; i++ { - mostSigBits32Sum = p.api.Add(mostSigBits32Sum, bits[i]) + result, err := p.api.Compiler().NewHint(SplitLimbsHint, 2, x.Limb) + if err != nil { + panic(err) } - leastSigBits32Sum := frontend.Variable(0) - for i := 0; i < 32; i++ { - leastSigBits32Sum = p.api.Add(leastSigBits32Sum, bits[i]) - } + mostSigBits := result[0] + leastSigBits := result[1] - // If mostSigBits32Sum < 32, then we know that: - // - // x < (2^63 + ... + 2^32 + 0 * 2^31 + ... + 0 * 2^0) - // - // which equals to 2^64 - 2^32. So in that case, we don't need to do any more checks. If - // mostSigBits32Sum == 32, then we need to check that x == 2^64 - 2^32 (max GL value). - shouldCheck := p.api.IsZero(p.api.Sub(mostSigBits32Sum, 32)) + // If the most significant bits are all 1, then we need to check that the least significant bits are all zero + // in order for element to be less than the Goldilock's modulus. + // Otherwise, we don't need to do any checks, since we already know that the element is less than the Goldilocks modulus. + shouldCheck := p.api.IsZero(p.api.Sub(mostSigBits, uint64(math.Pow(2, 32))-1)) p.api.AssertIsEqual( p.api.Select( shouldCheck, - leastSigBits32Sum, + leastSigBits, frontend.Variable(0), ), frontend.Variable(0), ) } -func (p *Chip) AssertIsEqual(x, y Variable) { +func (p *GoldilocksApi) AssertIsEqual(x, y GoldilocksVariable) { p.api.AssertIsEqual(x.Limb, y.Limb) } diff --git a/goldilocks/base_test.go b/goldilocks/base_test.go index d2a34d3..44d3ec0 100644 --- a/goldilocks/base_test.go +++ b/goldilocks/base_test.go @@ -15,8 +15,8 @@ type TestGoldilocksRangeCheckCircuit struct { } func (c *TestGoldilocksRangeCheckCircuit) Define(api frontend.API) error { - chip := NewChip(api) - chip.RangeCheck(NewVariable(c.X)) + glApi := NewGoldilocksApi(api) + glApi.RangeCheck(NewVariable(c.X)) return nil } func TestGoldilocksRangeCheck(t *testing.T) { @@ -45,8 +45,8 @@ type TestGoldilocksMulAddCircuit struct { } func (c *TestGoldilocksMulAddCircuit) Define(api frontend.API) error { - chip := NewChip(api) - calculateValue := chip.MulAdd(NewVariable(c.X), NewVariable(c.Y), NewVariable(c.Z)) + glApi := NewGoldilocksApi(api) + calculateValue := glApi.MulAdd(NewVariable(c.X), NewVariable(c.Y), NewVariable(c.Z)) api.AssertIsEqual(calculateValue.Limb, c.ExpectedResult) return nil } diff --git a/goldilocks/quadratic_extension.go b/goldilocks/quadratic_extension.go index d384300..3a4c80d 100644 --- a/goldilocks/quadratic_extension.go +++ b/goldilocks/quadratic_extension.go @@ -9,13 +9,13 @@ import ( const W uint64 = 7 const DTH_ROOT uint64 = 18446744069414584320 -type QuadraticExtensionVariable [2]Variable +type QuadraticExtensionVariable [2]GoldilocksVariable -func NewQuadraticExtensionVariable(x Variable, y Variable) QuadraticExtensionVariable { +func NewQuadraticExtensionVariable(x GoldilocksVariable, y GoldilocksVariable) QuadraticExtensionVariable { return QuadraticExtensionVariable{x, y} } -func (p Variable) ToQuadraticExtension() QuadraticExtensionVariable { +func (p GoldilocksVariable) ToQuadraticExtension() QuadraticExtensionVariable { return NewQuadraticExtensionVariable(p, Zero()) } @@ -28,35 +28,35 @@ func OneExtension() QuadraticExtensionVariable { } // Adds two quadratic extension variables in the Goldilocks field. -func (p *Chip) AddExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *GoldilocksApi) AddExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { c0 := p.Add(a[0], b[0]) c1 := p.Add(a[1], b[1]) return NewQuadraticExtensionVariable(c0, c1) } // Adds two quadratic extension variables in the Goldilocks field without reducing. -func (p *Chip) AddExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *GoldilocksApi) AddExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { c0 := p.AddNoReduce(a[0], b[0]) c1 := p.AddNoReduce(a[1], b[1]) return NewQuadraticExtensionVariable(c0, c1) } // Subtracts two quadratic extension variables in the Goldilocks field. -func (p *Chip) SubExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *GoldilocksApi) SubExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { c0 := p.Sub(a[0], b[0]) c1 := p.Sub(a[1], b[1]) return NewQuadraticExtensionVariable(c0, c1) } // Subtracts two quadratic extension variables in the Goldilocks field without reducing. -func (p *Chip) SubExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *GoldilocksApi) SubExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { c0 := p.SubNoReduce(a[0], b[0]) c1 := p.SubNoReduce(a[1], b[1]) return NewQuadraticExtensionVariable(c0, c1) } // Multiplies quadratic extension variable in the Goldilocks field. -func (p *Chip) MulExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *GoldilocksApi) MulExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { product := p.MulExtensionNoReduce(a, b) product[0] = p.Reduce(product[0]) product[1] = p.Reduce(product[1]) @@ -64,7 +64,7 @@ func (p *Chip) MulExtension(a, b QuadraticExtensionVariable) QuadraticExtensionV } // Multiplies quadratic extension variable in the Goldilocks field without reducing. -func (p *Chip) MulExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *GoldilocksApi) MulExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { c0o0 := p.MulNoReduce(a[0], b[0]) c0o1 := p.MulNoReduce(p.MulNoReduce(NewVariable(7), a[1]), b[1]) c0 := p.AddNoReduce(c0o0, c0o1) @@ -74,7 +74,7 @@ func (p *Chip) MulExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticEx // Multiplies two operands a and b and adds to c in the Goldilocks extension field. a * b + c must // be less than RANGE_CHECK_NB_BITS bits. -func (p *Chip) MulAddExtension(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *GoldilocksApi) MulAddExtension(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { product := p.MulExtensionNoReduce(a, b) sum := p.AddExtensionNoReduce(product, c) sum[0] = p.Reduce(sum[0]) @@ -82,7 +82,7 @@ func (p *Chip) MulAddExtension(a, b, c QuadraticExtensionVariable) QuadraticExte return sum } -func (p *Chip) MulAddExtensionNoReduce(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *GoldilocksApi) MulAddExtensionNoReduce(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { product := p.MulExtensionNoReduce(a, b) sum := p.AddExtensionNoReduce(product, c) return sum @@ -90,7 +90,7 @@ func (p *Chip) MulAddExtensionNoReduce(a, b, c QuadraticExtensionVariable) Quadr // Multiplies two operands a and b and subtracts to c in the Goldilocks extension field. a * b - c must // be less than RANGE_CHECK_NB_BITS bits. -func (p *Chip) SubMulExtension(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *GoldilocksApi) SubMulExtension(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { difference := p.SubExtensionNoReduce(a, b) product := p.MulExtensionNoReduce(difference, c) product[0] = p.Reduce(product[0]) @@ -99,9 +99,9 @@ func (p *Chip) SubMulExtension(a, b, c QuadraticExtensionVariable) QuadraticExte } // Multiplies quadratic extension variable in the Goldilocks field by a scalar. -func (p *Chip) ScalarMulExtension( +func (p *GoldilocksApi) ScalarMulExtension( a QuadraticExtensionVariable, - b Variable, + b GoldilocksVariable, ) QuadraticExtensionVariable { return NewQuadraticExtensionVariable( p.Mul(a[0], b), @@ -110,8 +110,8 @@ func (p *Chip) ScalarMulExtension( } // Computes an inner product over quadratic extension variable vectors in the Goldilocks field. -func (p *Chip) InnerProductExtension( - constant Variable, +func (p *GoldilocksApi) InnerProductExtension( + constant GoldilocksVariable, startingAcc QuadraticExtensionVariable, pairs [][2]QuadraticExtensionVariable, ) QuadraticExtensionVariable { @@ -126,7 +126,7 @@ func (p *Chip) InnerProductExtension( } // Computes the inverse of a quadratic extension variable in the Goldilocks field. -func (p *Chip) InverseExtension(a QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *GoldilocksApi) InverseExtension(a QuadraticExtensionVariable) QuadraticExtensionVariable { a0IsZero := p.api.IsZero(a[0].Limb) a1IsZero := p.api.IsZero(a[1].Limb) p.api.AssertIsEqual(p.api.Mul(a0IsZero, a1IsZero), frontend.Variable(0)) @@ -139,12 +139,12 @@ func (p *Chip) InverseExtension(a QuadraticExtensionVariable) QuadraticExtension } // Divides two quadratic extension variables in the Goldilocks field. -func (p *Chip) DivExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *GoldilocksApi) DivExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { return p.MulExtension(a, p.InverseExtension(b)) } // Exponentiates a quadratic extension variable to some exponent in the Golidlocks field. -func (p *Chip) ExpExtension( +func (p *GoldilocksApi) ExpExtension( a QuadraticExtensionVariable, exponent uint64, ) QuadraticExtensionVariable { @@ -173,12 +173,12 @@ func (p *Chip) ExpExtension( return product } -func (p *Chip) ReduceExtension(x QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *GoldilocksApi) ReduceExtension(x QuadraticExtensionVariable) QuadraticExtensionVariable { return NewQuadraticExtensionVariable(p.Reduce(x[0]), p.Reduce(x[1])) } // Reduces a list of extension field terms with a scalar power in the Goldilocks field. -func (p *Chip) ReduceWithPowers( +func (p *GoldilocksApi) ReduceWithPowers( terms []QuadraticExtensionVariable, scalar QuadraticExtensionVariable, ) QuadraticExtensionVariable { @@ -197,14 +197,14 @@ func (p *Chip) ReduceWithPowers( } // Outputs whether the quadratic extension variable is zero. -func (p *Chip) IsZero(x QuadraticExtensionVariable) frontend.Variable { +func (p *GoldilocksApi) IsZero(x QuadraticExtensionVariable) frontend.Variable { x0IsZero := p.api.IsZero(x[0].Limb) x1IsZero := p.api.IsZero(x[1].Limb) return p.api.Mul(x0IsZero, x1IsZero) } // Lookup is similar to select, but returns the first variable if the bit is zero and vice-versa. -func (p *Chip) Lookup( +func (p *GoldilocksApi) Lookup( b frontend.Variable, x, y QuadraticExtensionVariable, ) QuadraticExtensionVariable { @@ -214,7 +214,7 @@ func (p *Chip) Lookup( } // Lookup2 is similar to select2, but returns the first variable if the bit is zero and vice-versa. -func (p *Chip) Lookup2( +func (p *GoldilocksApi) Lookup2( b0 frontend.Variable, b1 frontend.Variable, qe0, qe1, qe2, qe3 QuadraticExtensionVariable, @@ -225,7 +225,7 @@ func (p *Chip) Lookup2( } // Asserts that two quadratic extension variables are equal. -func (p *Chip) AssertIsEqualExtension( +func (p *GoldilocksApi) AssertIsEqualExtension( a QuadraticExtensionVariable, b QuadraticExtensionVariable, ) { @@ -233,7 +233,7 @@ func (p *Chip) AssertIsEqualExtension( p.AssertIsEqual(a[1], b[1]) } -func (p *Chip) RangeCheckQE(a QuadraticExtensionVariable) { +func (p *GoldilocksApi) RangeCheckQE(a QuadraticExtensionVariable) { p.RangeCheck(a[0]) p.RangeCheck(a[1]) } diff --git a/goldilocks/quadratic_extension_algebra.go b/goldilocks/quadratic_extension_algebra.go index 9ce1028..668ed5f 100644 --- a/goldilocks/quadratic_extension_algebra.go +++ b/goldilocks/quadratic_extension_algebra.go @@ -25,7 +25,7 @@ func OneExtensionAlgebra() QuadraticExtensionAlgebraVariable { return OneExtension().ToQuadraticExtensionAlgebra() } -func (p *Chip) AddExtensionAlgebra( +func (p *GoldilocksApi) AddExtensionAlgebra( a QuadraticExtensionAlgebraVariable, b QuadraticExtensionAlgebraVariable, ) QuadraticExtensionAlgebraVariable { @@ -36,7 +36,7 @@ func (p *Chip) AddExtensionAlgebra( return sum } -func (p *Chip) SubExtensionAlgebra( +func (p *GoldilocksApi) SubExtensionAlgebra( a QuadraticExtensionAlgebraVariable, b QuadraticExtensionAlgebraVariable, ) QuadraticExtensionAlgebraVariable { @@ -47,7 +47,7 @@ func (p *Chip) SubExtensionAlgebra( return diff } -func (p Chip) MulExtensionAlgebra( +func (p GoldilocksApi) MulExtensionAlgebra( a QuadraticExtensionAlgebraVariable, b QuadraticExtensionAlgebraVariable, ) QuadraticExtensionAlgebraVariable { @@ -74,7 +74,7 @@ func (p Chip) MulExtensionAlgebra( return product } -func (p *Chip) ScalarMulExtensionAlgebra( +func (p *GoldilocksApi) ScalarMulExtensionAlgebra( a QuadraticExtensionVariable, b QuadraticExtensionAlgebraVariable, ) QuadraticExtensionAlgebraVariable { @@ -85,7 +85,7 @@ func (p *Chip) ScalarMulExtensionAlgebra( return product } -func (p *Chip) PartialInterpolateExtAlgebra( +func (p *GoldilocksApi) PartialInterpolateExtAlgebra( domain []goldilocks.Element, values []QuadraticExtensionAlgebraVariable, barycentricWeights []goldilocks.Element, diff --git a/goldilocks/quadratic_extension_test.go b/goldilocks/quadratic_extension_test.go index 0087ab6..1fbac49 100644 --- a/goldilocks/quadratic_extension_test.go +++ b/goldilocks/quadratic_extension_test.go @@ -15,7 +15,7 @@ type TestQuadraticExtensionMulCircuit struct { } func (c *TestQuadraticExtensionMulCircuit) Define(api frontend.API) error { - glApi := NewChip(api) + glApi := NewGoldilocksApi(api) actualRes := glApi.MulExtension(c.Operand1, c.Operand2) glApi.AssertIsEqual(actualRes[0], c.ExpectedResult[0]) glApi.AssertIsEqual(actualRes[1], c.ExpectedResult[1]) @@ -58,7 +58,7 @@ type TestQuadraticExtensionDivCircuit struct { } func (c *TestQuadraticExtensionDivCircuit) Define(api frontend.API) error { - glAPI := NewChip(api) + glAPI := NewGoldilocksApi(api) actualRes := glAPI.DivExtension(c.Operand1, c.Operand2) glAPI.AssertIsEqual(actualRes[0], c.ExpectedResult[0]) glAPI.AssertIsEqual(actualRes[1], c.ExpectedResult[1]) diff --git a/goldilocks/utils.go b/goldilocks/utils.go index 654230f..0101868 100644 --- a/goldilocks/utils.go +++ b/goldilocks/utils.go @@ -24,8 +24,8 @@ func StrArrayToFrontendVariableArray(input []string) []frontend.Variable { return output } -func Uint64ArrayToVariableArray(input []uint64) []Variable { - var output []Variable +func Uint64ArrayToVariableArray(input []uint64) []GoldilocksVariable { + var output []GoldilocksVariable for i := 0; i < len(input); i++ { output = append(output, NewVariable(input[i])) } diff --git a/plonk/gates/arithmetic_extension_gate.go b/plonk/gates/arithmetic_extension_gate.go index e09ed2a..91d4db1 100644 --- a/plonk/gates/arithmetic_extension_gate.go +++ b/plonk/gates/arithmetic_extension_gate.go @@ -58,7 +58,7 @@ func (g *ArithmeticExtensionGate) wiresIthOutput(i uint64) Range { func (g *ArithmeticExtensionGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { const0 := vars.localConstants[0] diff --git a/plonk/gates/arithmetic_gate.go b/plonk/gates/arithmetic_gate.go index 7867cb0..e7b78a7 100644 --- a/plonk/gates/arithmetic_gate.go +++ b/plonk/gates/arithmetic_gate.go @@ -59,7 +59,7 @@ func (g *ArithmeticGate) WireIthOutput(i uint64) uint64 { func (g *ArithmeticGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { const0 := vars.localConstants[0] diff --git a/plonk/gates/base_sum_gate.go b/plonk/gates/base_sum_gate.go index aff6db6..543953c 100644 --- a/plonk/gates/base_sum_gate.go +++ b/plonk/gates/base_sum_gate.go @@ -65,7 +65,7 @@ func (g *BaseSumGate) limbs() []uint64 { func (g *BaseSumGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { sum := vars.localWires[BASESUM_GATE_WIRE_SUM] diff --git a/plonk/gates/constant_gate.go b/plonk/gates/constant_gate.go index e263139..3771df0 100644 --- a/plonk/gates/constant_gate.go +++ b/plonk/gates/constant_gate.go @@ -56,7 +56,7 @@ func (g *ConstantGate) WireOutput(i uint64) uint64 { func (g *ConstantGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { constraints := []gl.QuadraticExtensionVariable{} diff --git a/plonk/gates/coset_interpolation_gate.go b/plonk/gates/coset_interpolation_gate.go index 58e53da..1e08a13 100644 --- a/plonk/gates/coset_interpolation_gate.go +++ b/plonk/gates/coset_interpolation_gate.go @@ -147,7 +147,7 @@ func (g *CosetInterpolationGate) wiresShiftedEvaluationPoint() Range { func (g *CosetInterpolationGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { constraints := []gl.QuadraticExtensionVariable{} diff --git a/plonk/gates/evaluate_gates.go b/plonk/gates/evaluate_gates.go index 8823cc9..b123765 100644 --- a/plonk/gates/evaluate_gates.go +++ b/plonk/gates/evaluate_gates.go @@ -36,7 +36,7 @@ func (g *EvaluateGatesChip) computeFilter( s gl.QuadraticExtensionVariable, manySelector bool, ) gl.QuadraticExtensionVariable { - glApi := gl.NewChip(g.api) + glApi := gl.NewGoldilocksApi(g.api) product := gl.OneExtension() for i := groupRange.start; i < groupRange.end; i++ { if i == uint64(row) { @@ -62,7 +62,7 @@ func (g *EvaluateGatesChip) evalFiltered( groupRange Range, numSelectors uint64, ) []gl.QuadraticExtensionVariable { - glApi := gl.NewChip(g.api) + glApi := gl.NewGoldilocksApi(g.api) filter := g.computeFilter(row, groupRange, vars.localConstants[selectorIndex], numSelectors > 1) vars.RemovePrefix(numSelectors) @@ -75,7 +75,7 @@ func (g *EvaluateGatesChip) evalFiltered( } func (g *EvaluateGatesChip) EvaluateGateConstraints(vars EvaluationVars) []gl.QuadraticExtensionVariable { - glApi := gl.NewChip(g.api) + glApi := gl.NewGoldilocksApi(g.api) constraints := make([]gl.QuadraticExtensionVariable, g.numGateConstraints) for i := range constraints { constraints[i] = gl.ZeroExtension() diff --git a/plonk/gates/exponentiation_gate.go b/plonk/gates/exponentiation_gate.go index ccf02e6..3d75301 100644 --- a/plonk/gates/exponentiation_gate.go +++ b/plonk/gates/exponentiation_gate.go @@ -65,7 +65,7 @@ func (g *ExponentiationGate) wireIntermediateValue(i uint64) uint64 { func (g *ExponentiationGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { base := vars.localWires[g.wireBase()] diff --git a/plonk/gates/gates.go b/plonk/gates/gates.go index edd98d4..b46e82d 100644 --- a/plonk/gates/gates.go +++ b/plonk/gates/gates.go @@ -12,7 +12,7 @@ type Gate interface { Id() string EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable } diff --git a/plonk/gates/gates_test.go b/plonk/gates/gates_test.go index 8bf99ba..91b4a37 100644 --- a/plonk/gates/gates_test.go +++ b/plonk/gates/gates_test.go @@ -693,7 +693,7 @@ func (circuit *TestGateCircuit) Define(api frontend.API) error { commonCircuitData := verifier.DeserializeCommonCircuitData("../../data/decode_block/common_circuit_data.json") numSelectors := commonCircuitData.SelectorsInfo.NumSelectors() - glApi := gl.NewChip(api) + glApi := gl.NewGoldilocksApi(api) vars := gates.NewEvaluationVars(localConstants[numSelectors:], localWires, publicInputsHash) diff --git a/plonk/gates/multiplication_extension_gate.go b/plonk/gates/multiplication_extension_gate.go index 37cec16..ce17821 100644 --- a/plonk/gates/multiplication_extension_gate.go +++ b/plonk/gates/multiplication_extension_gate.go @@ -54,7 +54,7 @@ func (g *MultiplicationExtensionGate) wiresIthOutput(i uint64) Range { func (g *MultiplicationExtensionGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { const0 := vars.localConstants[0] diff --git a/plonk/gates/noop_gate.go b/plonk/gates/noop_gate.go index f7c67e0..9b24291 100644 --- a/plonk/gates/noop_gate.go +++ b/plonk/gates/noop_gate.go @@ -27,7 +27,7 @@ func (g *NoopGate) Id() string { func (g *NoopGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { return []gl.QuadraticExtensionVariable{} diff --git a/plonk/gates/poseidon_gate.go b/plonk/gates/poseidon_gate.go index 4576b2f..be31caa 100644 --- a/plonk/gates/poseidon_gate.go +++ b/plonk/gates/poseidon_gate.go @@ -91,7 +91,7 @@ func (g *PoseidonGate) WiresEnd() uint64 { func (g *PoseidonGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { constraints := []gl.QuadraticExtensionVariable{} diff --git a/plonk/gates/poseidon_mds_gate.go b/plonk/gates/poseidon_mds_gate.go index 9efb2ef..f59ebb9 100644 --- a/plonk/gates/poseidon_mds_gate.go +++ b/plonk/gates/poseidon_mds_gate.go @@ -45,7 +45,7 @@ func (g *PoseidonMdsGate) mdsRowShfAlgebra( v [poseidon.SPONGE_WIDTH]gl.QuadraticExtensionAlgebraVariable, api frontend.API, ) gl.QuadraticExtensionAlgebraVariable { - glApi := gl.NewChip(api) + glApi := gl.NewGoldilocksApi(api) if r >= poseidon.SPONGE_WIDTH { panic("MDS row index out of range") } @@ -75,7 +75,7 @@ func (g *PoseidonMdsGate) mdsLayerAlgebra( func (g *PoseidonMdsGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { constraints := []gl.QuadraticExtensionVariable{} diff --git a/plonk/gates/public_input_gate.go b/plonk/gates/public_input_gate.go index 9fad5e7..f417217 100644 --- a/plonk/gates/public_input_gate.go +++ b/plonk/gates/public_input_gate.go @@ -31,7 +31,7 @@ func (g *PublicInputGate) WiresPublicInputsHash() []uint64 { func (g *PublicInputGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { constraints := []gl.QuadraticExtensionVariable{} diff --git a/plonk/gates/random_access_gate.go b/plonk/gates/random_access_gate.go index 5d1e0a8..82e30e9 100644 --- a/plonk/gates/random_access_gate.go +++ b/plonk/gates/random_access_gate.go @@ -116,7 +116,7 @@ func (g *RandomAccessGate) WireBit(i uint64, copy uint64) uint64 { func (g *RandomAccessGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { two := gl.NewVariable(2).ToQuadraticExtension() diff --git a/plonk/gates/reducing_extension_gate.go b/plonk/gates/reducing_extension_gate.go index 2d71c07..c75a810 100644 --- a/plonk/gates/reducing_extension_gate.go +++ b/plonk/gates/reducing_extension_gate.go @@ -76,7 +76,7 @@ func (g *ReducingExtensionGate) wiresAccs(i uint64) Range { func (g *ReducingExtensionGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { alpha := vars.GetLocalExtAlgebra(g.wiresAlpha()) diff --git a/plonk/gates/reducing_gate.go b/plonk/gates/reducing_gate.go index 2212f2b..2261c2f 100644 --- a/plonk/gates/reducing_gate.go +++ b/plonk/gates/reducing_gate.go @@ -76,7 +76,7 @@ func (g *ReducingGate) wiresAccs(i uint64) Range { func (g *ReducingGate) EvalUnfiltered( api frontend.API, - glApi gl.Chip, + glApi gl.GoldilocksApi, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { alpha := vars.GetLocalExtAlgebra(g.wiresAlpha()) diff --git a/plonk/plonk.go b/plonk/plonk.go index 47494dd..4baaf8d 100644 --- a/plonk/plonk.go +++ b/plonk/plonk.go @@ -13,8 +13,8 @@ type PlonkChip struct { commonData types.CommonCircuitData `gnark:"-"` - DEGREE gl.Variable `gnark:"-"` - DEGREE_BITS_F gl.Variable `gnark:"-"` + DEGREE gl.GoldilocksVariable `gnark:"-"` + DEGREE_BITS_F gl.GoldilocksVariable `gnark:"-"` DEGREE_QE gl.QuadraticExtensionVariable `gnark:"-"` evaluateGatesChip *gates.EvaluateGatesChip @@ -44,7 +44,7 @@ func NewPlonkChip(api frontend.API, commonData types.CommonCircuitData) *PlonkCh } func (p *PlonkChip) expPowerOf2Extension(x gl.QuadraticExtensionVariable) gl.QuadraticExtensionVariable { - glApi := gl.NewChip(p.api) + glApi := gl.NewGoldilocksApi(p.api) for i := uint64(0); i < p.commonData.DegreeBits; i++ { x = glApi.MulExtension(x, x) } @@ -53,7 +53,7 @@ func (p *PlonkChip) expPowerOf2Extension(x gl.QuadraticExtensionVariable) gl.Qua func (p *PlonkChip) evalL0(x gl.QuadraticExtensionVariable, xPowN gl.QuadraticExtensionVariable) gl.QuadraticExtensionVariable { // L_0(x) = (x^n - 1) / (n * (x - 1)) - glApi := gl.NewChip(p.api) + glApi := gl.NewGoldilocksApi(p.api) evalZeroPoly := glApi.SubExtension( xPowN, gl.OneExtension(), @@ -74,7 +74,7 @@ func (p *PlonkChip) checkPartialProducts( challengeNum uint64, openings types.OpeningSet, ) []gl.QuadraticExtensionVariable { - glApi := gl.NewChip(p.api) + glApi := gl.NewGoldilocksApi(p.api) numPartProds := p.commonData.NumPartialProducts quotDegreeFactor := p.commonData.QuotientDegreeFactor @@ -110,7 +110,7 @@ func (p *PlonkChip) evalVanishingPoly( openings types.OpeningSet, zetaPowN gl.QuadraticExtensionVariable, ) []gl.QuadraticExtensionVariable { - glApi := gl.NewChip(p.api) + glApi := gl.NewGoldilocksApi(p.api) constraintTerms := p.evaluateGatesChip.EvaluateGateConstraints(vars) // Calculate the k[i] * x @@ -197,7 +197,7 @@ func (p *PlonkChip) Verify( openings types.OpeningSet, publicInputsHash poseidon.GoldilocksHashOut, ) { - glApi := gl.NewChip(p.api) + glApi := gl.NewGoldilocksApi(p.api) // Calculate zeta^n zetaPowN := p.expPowerOf2Extension(proofChallenges.PlonkZeta) diff --git a/poseidon/bn254.go b/poseidon/bn254.go index d28b7b6..51afe0f 100644 --- a/poseidon/bn254.go +++ b/poseidon/bn254.go @@ -20,15 +20,15 @@ const BN254_SPONGE_WIDTH int = 4 const BN254_SPONGE_RATE int = 3 type BN254Chip struct { - api frontend.API `gnark:"-"` - gl gl.Chip `gnark:"-"` + api frontend.API `gnark:"-"` + gl gl.GoldilocksApi `gnark:"-"` } type BN254State = [BN254_SPONGE_WIDTH]frontend.Variable type BN254HashOut = frontend.Variable func NewBN254Chip(api frontend.API) *BN254Chip { - return &BN254Chip{api: api, gl: *gl.NewChip(api)} + return &BN254Chip{api: api, gl: *gl.NewGoldilocksApi(api)} } func (c *BN254Chip) Poseidon(state BN254State) BN254State { @@ -39,7 +39,7 @@ func (c *BN254Chip) Poseidon(state BN254State) BN254State { return state } -func (c *BN254Chip) HashNoPad(input []gl.Variable) BN254HashOut { +func (c *BN254Chip) HashNoPad(input []gl.GoldilocksVariable) BN254HashOut { state := BN254State{ frontend.Variable(0), frontend.Variable(0), @@ -69,7 +69,7 @@ func (c *BN254Chip) HashNoPad(input []gl.Variable) BN254HashOut { return BN254HashOut(state[0]) } -func (c *BN254Chip) HashOrNoop(input []gl.Variable) BN254HashOut { +func (c *BN254Chip) HashOrNoop(input []gl.GoldilocksVariable) BN254HashOut { if len(input) <= 3 { returnVal := frontend.Variable(0) @@ -94,10 +94,10 @@ func (c *BN254Chip) TwoToOne(left BN254HashOut, right BN254HashOut) BN254HashOut return state[0] } -func (c *BN254Chip) ToVec(hash BN254HashOut) []gl.Variable { +func (c *BN254Chip) ToVec(hash BN254HashOut) []gl.GoldilocksVariable { bits := c.api.ToBinary(hash) - returnElements := []gl.Variable{} + returnElements := []gl.GoldilocksVariable{} // Split into 7 byte chunks, since 8 byte chunks can result in collisions chunkSize := 56 diff --git a/poseidon/goldilocks.go b/poseidon/goldilocks.go index ee27bcd..509ef55 100644 --- a/poseidon/goldilocks.go +++ b/poseidon/goldilocks.go @@ -11,17 +11,17 @@ const MAX_WIDTH = 12 const SPONGE_WIDTH = 12 const SPONGE_RATE = 8 -type GoldilocksState = [SPONGE_WIDTH]gl.Variable +type GoldilocksState = [SPONGE_WIDTH]gl.GoldilocksVariable type GoldilocksStateExtension = [SPONGE_WIDTH]gl.QuadraticExtensionVariable -type GoldilocksHashOut = [4]gl.Variable +type GoldilocksHashOut = [4]gl.GoldilocksVariable type GoldilocksChip struct { - api frontend.API `gnark:"-"` - gl gl.Chip `gnark:"-"` + api frontend.API `gnark:"-"` + gl gl.GoldilocksApi `gnark:"-"` } func NewGoldilocksChip(api frontend.API) *GoldilocksChip { - return &GoldilocksChip{api: api, gl: *gl.NewChip(api)} + return &GoldilocksChip{api: api, gl: *gl.NewGoldilocksApi(api)} } // The permutation function. @@ -38,7 +38,7 @@ func (c *GoldilocksChip) Poseidon(input GoldilocksState) GoldilocksState { // The input elements MUST have all it's elements be within Goldilocks field. // The returned slice's elements will all be within Goldilocks field. -func (c *GoldilocksChip) HashNToMNoPad(input []gl.Variable, nbOutputs int) []gl.Variable { +func (c *GoldilocksChip) HashNToMNoPad(input []gl.GoldilocksVariable, nbOutputs int) []gl.GoldilocksVariable { var state GoldilocksState for i := 0; i < SPONGE_WIDTH; i++ { @@ -54,7 +54,7 @@ func (c *GoldilocksChip) HashNToMNoPad(input []gl.Variable, nbOutputs int) []gl. state = c.Poseidon(state) } - var outputs []gl.Variable + var outputs []gl.GoldilocksVariable for { for i := 0; i < SPONGE_RATE; i++ { @@ -69,9 +69,9 @@ func (c *GoldilocksChip) HashNToMNoPad(input []gl.Variable, nbOutputs int) []gl. // The input elements can be outside of the Goldilocks field. // The returned slice's elements will all be within Goldilocks field. -func (c *GoldilocksChip) HashNoPad(input []gl.Variable) GoldilocksHashOut { +func (c *GoldilocksChip) HashNoPad(input []gl.GoldilocksVariable) GoldilocksHashOut { var hash GoldilocksHashOut - inputVars := []gl.Variable{} + inputVars := []gl.GoldilocksVariable{} for i := 0; i < len(input); i++ { inputVars = append(inputVars, c.gl.Reduce(input[i])) @@ -85,7 +85,7 @@ func (c *GoldilocksChip) HashNoPad(input []gl.Variable) GoldilocksHashOut { return hash } -func (c *GoldilocksChip) ToVec(hash GoldilocksHashOut) []gl.Variable { +func (c *GoldilocksChip) ToVec(hash GoldilocksHashOut) []gl.GoldilocksVariable { return hash[:] } @@ -135,7 +135,7 @@ func (c *GoldilocksChip) ConstantLayerExtension(state GoldilocksStateExtension, return state } -func (c *GoldilocksChip) sBoxMonomial(x gl.Variable) gl.Variable { +func (c *GoldilocksChip) sBoxMonomial(x gl.GoldilocksVariable) gl.GoldilocksVariable { x2 := c.gl.MulNoReduce(x, x) x3 := c.gl.MulNoReduce(x, x2) x3 = c.gl.ReduceWithMaxBits(x3, 192) @@ -169,7 +169,7 @@ func (c *GoldilocksChip) SBoxLayerExtension(state GoldilocksStateExtension) Gold return state } -func (c *GoldilocksChip) mdsRowShf(r int, v [SPONGE_WIDTH]gl.Variable) gl.Variable { +func (c *GoldilocksChip) mdsRowShf(r int, v [SPONGE_WIDTH]gl.GoldilocksVariable) gl.GoldilocksVariable { res := gl.Zero() for i := 0; i < 12; i++ { diff --git a/poseidon/goldilocks_test.go b/poseidon/goldilocks_test.go index 32be542..981aee3 100644 --- a/poseidon/goldilocks_test.go +++ b/poseidon/goldilocks_test.go @@ -25,7 +25,7 @@ func (circuit *TestPoseidonCircuit) Define(api frontend.API) error { poseidonChip := NewGoldilocksChip(api) output := poseidonChip.Poseidon(input) - glApi := gl.NewChip(api) + glApi := gl.NewGoldilocksApi(api) for i := 0; i < 12; i++ { glApi.AssertIsEqual(output[i], gl.NewVariable(circuit.Out[i])) diff --git a/poseidon/public_inputs_hash_test.go b/poseidon/public_inputs_hash_test.go index e68a3bc..a11d5a1 100644 --- a/poseidon/public_inputs_hash_test.go +++ b/poseidon/public_inputs_hash_test.go @@ -18,10 +18,10 @@ type TestPublicInputsHashCircuit struct { } func (circuit *TestPublicInputsHashCircuit) Define(api frontend.API) error { - glAPI := gl.NewChip(api) + glAPI := gl.NewGoldilocksApi(api) // BN254 -> Binary(64) -> F - var input [3]gl.Variable + var input [3]gl.GoldilocksVariable for i := 0; i < 3; i++ { input[i] = gl.NewVariable(api.FromBinary(api.ToBinary(circuit.In[i], 64)...)) } diff --git a/types/circuit.go b/types/circuit.go index 9e46d30..7b5fb9a 100644 --- a/types/circuit.go +++ b/types/circuit.go @@ -16,7 +16,7 @@ type Proof struct { type ProofWithPublicInputs struct { Proof Proof - PublicInputs []gl.Variable // Length = CommonCircuitData.NumPublicInputs + PublicInputs []gl.GoldilocksVariable // Length = CommonCircuitData.NumPublicInputs } type VerifierOnlyCircuitData struct { @@ -46,6 +46,6 @@ type CommonCircuitData struct { NumGateConstraints uint64 NumConstants uint64 NumPublicInputs uint64 - KIs []gl.Variable + KIs []gl.GoldilocksVariable NumPartialProducts uint64 } diff --git a/types/fri.go b/types/fri.go index aaea0f3..59e6fdc 100644 --- a/types/fri.go +++ b/types/fri.go @@ -47,11 +47,11 @@ func NewFriMerkleProof(merkleProofLen uint64) FriMerkleProof { } type FriEvalProof struct { - Elements []gl.Variable // Length = [CommonCircuitData.Constants + CommonCircuitData.NumRoutedWires, CommonCircuitData.NumWires + CommonCircuitData.FriParams.Hiding ? 4 : 0, CommonCircuitData.NumChallenges * (1 + CommonCircuitData.NumPartialProducts) + salt, CommonCircuitData.NumChallenges * CommonCircuitData.QuotientDegreeFactor + salt] + Elements []gl.GoldilocksVariable // Length = [CommonCircuitData.Constants + CommonCircuitData.NumRoutedWires, CommonCircuitData.NumWires + CommonCircuitData.FriParams.Hiding ? 4 : 0, CommonCircuitData.NumChallenges * (1 + CommonCircuitData.NumPartialProducts) + salt, CommonCircuitData.NumChallenges * CommonCircuitData.QuotientDegreeFactor + salt] MerkleProof FriMerkleProof } -func NewFriEvalProof(elements []gl.Variable, merkleProof FriMerkleProof) FriEvalProof { +func NewFriEvalProof(elements []gl.GoldilocksVariable, merkleProof FriMerkleProof) FriEvalProof { return FriEvalProof{Elements: elements, MerkleProof: merkleProof} } @@ -88,12 +88,12 @@ type FriProof struct { CommitPhaseMerkleCaps []FriMerkleCap // Length = Len(CommonCircuitData.FriParams.ReductionArityBits) QueryRoundProofs []FriQueryRound // Length = CommonCircuitData.FriConfig.FriParams.NumQueryRounds FinalPoly PolynomialCoeffs - PowWitness gl.Variable + PowWitness gl.GoldilocksVariable } type FriChallenges struct { FriAlpha gl.QuadraticExtensionVariable FriBetas []gl.QuadraticExtensionVariable - FriPowResponse gl.Variable - FriQueryIndices []gl.Variable + FriPowResponse gl.GoldilocksVariable + FriQueryIndices []gl.GoldilocksVariable } diff --git a/types/plonk.go b/types/plonk.go index f0b03b9..b9a36d1 100644 --- a/types/plonk.go +++ b/types/plonk.go @@ -25,9 +25,9 @@ func NewOpeningSet(numConstants uint64, numRoutedWires uint64, numWires uint64, } type ProofChallenges struct { - PlonkBetas []gl.Variable - PlonkGammas []gl.Variable - PlonkAlphas []gl.Variable + PlonkBetas []gl.GoldilocksVariable + PlonkGammas []gl.GoldilocksVariable + PlonkAlphas []gl.GoldilocksVariable PlonkZeta gl.QuadraticExtensionVariable FriChallenges FriChallenges } diff --git a/verifier/verifier.go b/verifier/verifier.go index ca0d0f7..68da5c7 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -12,7 +12,7 @@ import ( type VerifierChip struct { api frontend.API `gnark:"-"` - glChip *gl.Chip `gnark:"-"` + glChip *gl.GoldilocksApi `gnark:"-"` poseidonGlChip *poseidon.GoldilocksChip `gnark:"-"` poseidonBN254Chip *poseidon.BN254Chip `gnark:"-"` plonkChip *plonk.PlonkChip `gnark:"-"` @@ -20,7 +20,7 @@ type VerifierChip struct { } func NewVerifierChip(api frontend.API, commonCircuitData types.CommonCircuitData) *VerifierChip { - glChip := gl.NewChip(api) + glChip := gl.NewGoldilocksApi(api) friChip := fri.NewChip(api, &commonCircuitData.FriParams) plonkChip := plonk.NewPlonkChip(api, commonCircuitData) poseidonGlChip := poseidon.NewGoldilocksChip(api) @@ -35,7 +35,7 @@ func NewVerifierChip(api frontend.API, commonCircuitData types.CommonCircuitData } } -func (c *VerifierChip) GetPublicInputsHash(publicInputs []gl.Variable) poseidon.GoldilocksHashOut { +func (c *VerifierChip) GetPublicInputsHash(publicInputs []gl.GoldilocksVariable) poseidon.GoldilocksHashOut { return c.poseidonGlChip.HashNoPad(publicInputs) } @@ -206,7 +206,7 @@ func (c *VerifierChip) rangeCheckProof(proof types.Proof) { func (c *VerifierChip) Verify( proof types.Proof, - publicInputs []gl.Variable, + publicInputs []gl.GoldilocksVariable, verifierData types.VerifierOnlyCircuitData, commonData types.CommonCircuitData, ) { diff --git a/verifier/verifier_test.go b/verifier/verifier_test.go index e9cd2d5..4ca3924 100644 --- a/verifier/verifier_test.go +++ b/verifier/verifier_test.go @@ -15,7 +15,7 @@ import ( type TestVerifierCircuit struct { Proof types.Proof - PublicInputs []gl.Variable `gnark:",public"` + PublicInputs []gl.GoldilocksVariable `gnark:",public"` verifierChip *verifier.VerifierChip `gnark:"-"` plonky2CircuitName string `gnark:"-"` From 90e2f5f1b14c564954fec428ff058abae68c513b Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Tue, 10 Oct 2023 22:54:16 -0700 Subject: [PATCH 03/13] Added benchmark --- goldilocks/.gitignore | 1 + goldilocks/base.go | 11 ++++++----- goldilocks/base_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 goldilocks/.gitignore diff --git a/goldilocks/.gitignore b/goldilocks/.gitignore new file mode 100644 index 0000000..dca82ea --- /dev/null +++ b/goldilocks/.gitignore @@ -0,0 +1 @@ +gnark.pprof \ No newline at end of file diff --git a/goldilocks/base.go b/goldilocks/base.go index f3c4ef5..c4aff35 100644 --- a/goldilocks/base.go +++ b/goldilocks/base.go @@ -77,12 +77,14 @@ func NegOne() GoldilocksVariable { // The chip used for Goldilocks field operations. type GoldilocksApi struct { - api frontend.API + api frontend.API + rangeChecker frontend.Rangechecker } // Creates a new Goldilocks chip. func NewGoldilocksApi(api frontend.API) *GoldilocksApi { - return &GoldilocksApi{api: api} + rangeChecker := rangecheck.New(api) + return &GoldilocksApi{api: api, rangeChecker: rangeChecker} } // Adds two field elements such that x + y = z within the Golidlocks field. @@ -182,8 +184,7 @@ func (p *GoldilocksApi) Reduce(x GoldilocksVariable) GoldilocksVariable { } quotient := result[0] - rangeCheckNbBits := RANGE_CHECK_NB_BITS - p.api.ToBinary(quotient, rangeCheckNbBits) + p.rangeChecker.Check(quotient, RANGE_CHECK_NB_BITS) remainder := NewVariable(result[1]) p.RangeCheck(remainder) @@ -205,7 +206,7 @@ func (p *GoldilocksApi) ReduceWithMaxBits(x GoldilocksVariable, maxNbBits uint64 } quotient := result[0] - p.api.ToBinary(quotient, int(maxNbBits)) + p.rangeChecker.Check(quotient, int(maxNbBits)) remainder := NewVariable(result[1]) p.RangeCheck(remainder) diff --git a/goldilocks/base_test.go b/goldilocks/base_test.go index 44d3ec0..c554f72 100644 --- a/goldilocks/base_test.go +++ b/goldilocks/base_test.go @@ -1,12 +1,16 @@ package goldilocks import ( + "fmt" "math/big" + "os" "testing" "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark/backend" "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/frontend/cs/scs" + "github.com/consensys/gnark/profile" "github.com/consensys/gnark/test" ) @@ -39,6 +43,43 @@ func TestGoldilocksRangeCheck(t *testing.T) { assert.ProverSucceeded(&circuit, &witness, test.WithCurves(ecc.BN254), test.WithBackends(backend.GROTH16)) } +type TestGoldilocksRangeCheckBenchmarkCircuit struct { + X []frontend.Variable +} + +func (c *TestGoldilocksRangeCheckBenchmarkCircuit) Define(api frontend.API) error { + glApi := NewGoldilocksApi(api) + for _, x := range c.X { + glApi.RangeCheck(NewVariable(x)) + } + return nil +} + +func BenchmarkGoldilocksRangeCheck(b *testing.B) { + var sizes = []int{5, 10, 15} + for i := 0; i < len(sizes); i++ { + var circuit, witness TestGoldilocksRangeCheckBenchmarkCircuit + circuit.X = make([]frontend.Variable, 2< Date: Tue, 10 Oct 2023 22:56:44 -0700 Subject: [PATCH 04/13] Added reduce to benchmark --- goldilocks/base_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/goldilocks/base_test.go b/goldilocks/base_test.go index c554f72..1a28dca 100644 --- a/goldilocks/base_test.go +++ b/goldilocks/base_test.go @@ -51,6 +51,8 @@ func (c *TestGoldilocksRangeCheckBenchmarkCircuit) Define(api frontend.API) erro glApi := NewGoldilocksApi(api) for _, x := range c.X { glApi.RangeCheck(NewVariable(x)) + glApi.Reduce(NewVariable(x)) + } return nil } From d8b919a4038033fed6d24b18cbd4153eac0eaa1f Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Wed, 11 Oct 2023 00:28:20 -0700 Subject: [PATCH 05/13] Fixed underconstrained in range check and added dummy mode to benchmark.go --- benchmark.go | 19 ++++++++++++++++--- goldilocks/base.go | 10 ++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/benchmark.go b/benchmark.go index 7ba592f..320ed8e 100644 --- a/benchmark.go +++ b/benchmark.go @@ -40,7 +40,7 @@ func (circuit *BenchmarkPlonky2VerifierCircuit) Define(api frontend.API) error { return nil } -func compileCircuit(plonky2Circuit string, profileCircuit bool, serialize bool, outputSolidity bool) (constraint.ConstraintSystem, groth16.ProvingKey, groth16.VerifyingKey) { +func compileCircuit(plonky2Circuit string, profileCircuit bool, serialize bool, outputSolidity bool, dummy bool) (constraint.ConstraintSystem, groth16.ProvingKey, groth16.VerifyingKey) { circuit := BenchmarkPlonky2VerifierCircuit{ plonky2CircuitName: plonky2Circuit, } @@ -76,9 +76,17 @@ func compileCircuit(plonky2Circuit string, profileCircuit bool, serialize bool, fR1CS.Close() } */ + var pk groth16.ProvingKey + var vk groth16.VerifyingKey fmt.Println("Running circuit setup", time.Now()) - pk, vk, err := groth16.Setup(r1cs) + if dummy { + fmt.Println("Using dummy setup") + pk, err = groth16.DummySetup(r1cs) + } else { + fmt.Println("Using real setup") + pk, vk, err = groth16.Setup(r1cs) + } if err != nil { fmt.Println(err) os.Exit(1) @@ -132,6 +140,11 @@ func createProof(plonky2Circuit string, r1cs constraint.ConstraintSystem, pk gro fProof.Close() } + if vk == nil { + fmt.Println("vk is nil, means you're using dummy setup and we skip verification step") + return proof + } + fmt.Println("Verifying proof", time.Now()) err = groth16.Verify(proof, vk, publicWitness) if err != nil { @@ -187,6 +200,6 @@ func main() { os.Exit(1) } - r1cs, pk, vk := compileCircuit(*plonky2Circuit, *profileCircuit, *serialize, *outputSolidity) + r1cs, pk, vk := compileCircuit(*plonky2Circuit, *profileCircuit, *serialize, *outputSolidity, true) createProof(*plonky2Circuit, r1cs, pk, vk, *serialize) } diff --git a/goldilocks/base.go b/goldilocks/base.go index c4aff35..14f8ed4 100644 --- a/goldilocks/base.go +++ b/goldilocks/base.go @@ -323,8 +323,18 @@ func (p *GoldilocksApi) RangeCheck(x GoldilocksVariable) { panic(err) } + // We check that this is a valid decomposition of the Goldilock's element and range-check each limb. mostSigBits := result[0] leastSigBits := result[1] + p.api.AssertIsEqual( + p.api.Add( + p.api.Mul(mostSigBits, uint64(math.Pow(2, 32))), + leastSigBits, + ), + x.Limb, + ) + rangeChecker.Check(mostSigBits, 32) + rangeChecker.Check(leastSigBits, 32) // If the most significant bits are all 1, then we need to check that the least significant bits are all zero // in order for element to be less than the Goldilock's modulus. From 3b8611c6ac36e7ff3b8221e57f192b25fbb02834 Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Wed, 11 Oct 2023 11:37:45 -0700 Subject: [PATCH 06/13] Rename back --- benchmark.go | 2 +- benchmark_plonk.go | 2 +- challenger/challenger.go | 30 +++++++++++----------- fri/fri.go | 14 +++++----- goldilocks/base.go | 40 ++++++++++++++--------------- goldilocks/quadratic_extension.go | 10 ++++---- goldilocks/utils.go | 4 +-- plonk/plonk.go | 4 +-- poseidon/bn254.go | 8 +++--- poseidon/goldilocks.go | 18 ++++++------- poseidon/public_inputs_hash_test.go | 2 +- types/circuit.go | 4 +-- types/fri.go | 10 ++++---- types/plonk.go | 6 ++--- verifier/verifier.go | 4 +-- verifier/verifier_test.go | 2 +- 16 files changed, 80 insertions(+), 80 deletions(-) diff --git a/benchmark.go b/benchmark.go index 320ed8e..9f341b2 100644 --- a/benchmark.go +++ b/benchmark.go @@ -22,7 +22,7 @@ import ( type BenchmarkPlonky2VerifierCircuit struct { Proof types.Proof - PublicInputs []gl.GoldilocksVariable `gnark:",public"` + PublicInputs []gl.Variable `gnark:",public"` verifierChip *verifier.VerifierChip `gnark:"-"` plonky2CircuitName string `gnark:"-"` diff --git a/benchmark_plonk.go b/benchmark_plonk.go index d4bacfd..6f7df12 100644 --- a/benchmark_plonk.go +++ b/benchmark_plonk.go @@ -23,7 +23,7 @@ import ( type BenchmarkPlonky2VerifierCircuitPlonk struct { Proof types.Proof - PublicInputs []gl.GoldilocksVariable `gnark:",public"` + PublicInputs []gl.Variable `gnark:",public"` verifierChip *verifier.VerifierChip `gnark:"-"` plonky2CircuitName string `gnark:"-"` diff --git a/challenger/challenger.go b/challenger/challenger.go index 85a35e5..a1c07be 100644 --- a/challenger/challenger.go +++ b/challenger/challenger.go @@ -14,15 +14,15 @@ type Chip struct { api frontend.API `gnark:"-"` poseidonChip *poseidon.GoldilocksChip poseidonBN254Chip *poseidon.BN254Chip - spongeState [poseidon.SPONGE_WIDTH]gl.GoldilocksVariable - inputBuffer []gl.GoldilocksVariable - outputBuffer []gl.GoldilocksVariable + spongeState [poseidon.SPONGE_WIDTH]gl.Variable + inputBuffer []gl.Variable + outputBuffer []gl.Variable } func NewChip(api frontend.API) *Chip { - var spongeState [poseidon.SPONGE_WIDTH]gl.GoldilocksVariable - var inputBuffer []gl.GoldilocksVariable - var outputBuffer []gl.GoldilocksVariable + var spongeState [poseidon.SPONGE_WIDTH]gl.Variable + var inputBuffer []gl.Variable + var outputBuffer []gl.Variable for i := 0; i < poseidon.SPONGE_WIDTH; i++ { spongeState[i] = gl.Zero() } @@ -38,7 +38,7 @@ func NewChip(api frontend.API) *Chip { } } -func (c *Chip) ObserveElement(element gl.GoldilocksVariable) { +func (c *Chip) ObserveElement(element gl.Variable) { c.outputBuffer = clearBuffer(c.outputBuffer) c.inputBuffer = append(c.inputBuffer, element) if len(c.inputBuffer) == poseidon.SPONGE_RATE { @@ -46,7 +46,7 @@ func (c *Chip) ObserveElement(element gl.GoldilocksVariable) { } } -func (c *Chip) ObserveElements(elements []gl.GoldilocksVariable) { +func (c *Chip) ObserveElements(elements []gl.Variable) { for i := 0; i < len(elements); i++ { c.ObserveElement(elements[i]) } @@ -84,7 +84,7 @@ func (c *Chip) ObserveOpenings(openings fri.Openings) { } } -func (c *Chip) GetChallenge() gl.GoldilocksVariable { +func (c *Chip) GetChallenge() gl.Variable { if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 { c.duplexing() } @@ -95,8 +95,8 @@ func (c *Chip) GetChallenge() gl.GoldilocksVariable { return challenge } -func (c *Chip) GetNChallenges(n uint64) []gl.GoldilocksVariable { - challenges := make([]gl.GoldilocksVariable, n) +func (c *Chip) GetNChallenges(n uint64) []gl.Variable { + challenges := make([]gl.Variable, n) for i := uint64(0); i < n; i++ { challenges[i] = c.GetChallenge() } @@ -109,13 +109,13 @@ func (c *Chip) GetExtensionChallenge() gl.QuadraticExtensionVariable { } func (c *Chip) GetHash() poseidon.GoldilocksHashOut { - return [4]gl.GoldilocksVariable{c.GetChallenge(), c.GetChallenge(), c.GetChallenge(), c.GetChallenge()} + return [4]gl.Variable{c.GetChallenge(), c.GetChallenge(), c.GetChallenge(), c.GetChallenge()} } func (c *Chip) GetFriChallenges( commitPhaseMerkleCaps []types.FriMerkleCap, finalPoly types.PolynomialCoeffs, - powWitness gl.GoldilocksVariable, + powWitness gl.Variable, degreeBits uint64, config types.FriConfig, ) types.FriChallenges { @@ -142,8 +142,8 @@ func (c *Chip) GetFriChallenges( } } -func clearBuffer(buffer []gl.GoldilocksVariable) []gl.GoldilocksVariable { - return make([]gl.GoldilocksVariable, 0) +func clearBuffer(buffer []gl.Variable) []gl.Variable { + return make([]gl.Variable, 0) } func (c *Chip) duplexing() { diff --git a/fri/fri.go b/fri/fri.go index ab8255f..9610e50 100644 --- a/fri/fri.go +++ b/fri/fri.go @@ -33,7 +33,7 @@ func NewChip( } } -func (f *Chip) assertLeadingZeros(powWitness gl.GoldilocksVariable, friConfig types.FriConfig) { +func (f *Chip) assertLeadingZeros(powWitness gl.Variable, friConfig types.FriConfig) { // Asserts that powWitness'es big-endian bit representation has at least `leading_zeros` leading zeros. // Note that this is assuming that the Goldilocks field is being used. Specfically that the // field is 64 bits long @@ -58,7 +58,7 @@ func (f *Chip) fromOpeningsAndAlpha( } func (f *Chip) verifyMerkleProofToCapWithCapIndex( - leafData []gl.GoldilocksVariable, + leafData []gl.Variable, leafIndexBits []frontend.Variable, capIndexBits []frontend.Variable, merkleCap types.FriMerkleCap, @@ -139,7 +139,7 @@ func (f *Chip) assertNoncanonicalIndicesOK() { func (f *Chip) expFromBitsConstBase( base goldilocks.Element, exponentBits []frontend.Variable, -) gl.GoldilocksVariable { +) gl.Variable { product := gl.One() for i, bit := range exponentBits { // If the bit is on, we multiply product by base^pow. @@ -167,7 +167,7 @@ func (f *Chip) expFromBitsConstBase( func (f *Chip) calculateSubgroupX( xIndexBits []frontend.Variable, nLog uint64, -) gl.GoldilocksVariable { +) gl.Variable { // Compute x from its index // `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain. // TODO - Make these as global values @@ -284,7 +284,7 @@ func (f *Chip) interpolate( } func (f *Chip) computeEvaluation( - x gl.GoldilocksVariable, + x gl.Variable, xIndexWithinCosetBits []frontend.Variable, arityBits uint64, evals []gl.QuadraticExtensionVariable, @@ -359,7 +359,7 @@ func (f *Chip) verifyQueryRound( precomputedReducedEval []gl.QuadraticExtensionVariable, initialMerkleCaps []types.FriMerkleCap, proof *types.FriProof, - xIndex gl.GoldilocksVariable, + xIndex gl.Variable, n uint64, nLog uint64, roundProof *types.FriQueryRound, @@ -437,7 +437,7 @@ func (f *Chip) verifyQueryRound( ) // Convert evals (array of QE) to fields by taking their 0th degree coefficients - fieldEvals := make([]gl.GoldilocksVariable, 0, 2*len(evals)) + fieldEvals := make([]gl.Variable, 0, 2*len(evals)) for j := 0; j < len(evals); j++ { fieldEvals = append(fieldEvals, evals[j][0]) fieldEvals = append(fieldEvals, evals[j][1]) diff --git a/goldilocks/base.go b/goldilocks/base.go index 14f8ed4..c6a5cca 100644 --- a/goldilocks/base.go +++ b/goldilocks/base.go @@ -50,28 +50,28 @@ func init() { } // A type alias used to represent Goldilocks field elements. -type GoldilocksVariable struct { +type Variable struct { Limb frontend.Variable } // Creates a new Goldilocks field element from an existing variable. Assumes that the element is // already reduced. -func NewVariable(x frontend.Variable) GoldilocksVariable { - return GoldilocksVariable{Limb: x} +func NewVariable(x frontend.Variable) Variable { + return Variable{Limb: x} } // The zero element in the Golidlocks field. -func Zero() GoldilocksVariable { +func Zero() Variable { return NewVariable(0) } // The one element in the Goldilocks field. -func One() GoldilocksVariable { +func One() Variable { return NewVariable(1) } // The negative one element in the Goldilocks field. -func NegOne() GoldilocksVariable { +func NegOne() Variable { return NewVariable(MODULUS.Uint64() - 1) } @@ -88,38 +88,38 @@ func NewGoldilocksApi(api frontend.API) *GoldilocksApi { } // Adds two field elements such that x + y = z within the Golidlocks field. -func (p *GoldilocksApi) Add(a GoldilocksVariable, b GoldilocksVariable) GoldilocksVariable { +func (p *GoldilocksApi) Add(a Variable, b Variable) Variable { return p.MulAdd(a, NewVariable(1), b) } // Adds two field elements such that x + y = z within the Golidlocks field without reducing. -func (p *GoldilocksApi) AddNoReduce(a GoldilocksVariable, b GoldilocksVariable) GoldilocksVariable { +func (p *GoldilocksApi) AddNoReduce(a Variable, b Variable) Variable { return NewVariable(p.api.Add(a.Limb, b.Limb)) } // Subtracts two field elements such that x + y = z within the Golidlocks field. -func (p *GoldilocksApi) Sub(a GoldilocksVariable, b GoldilocksVariable) GoldilocksVariable { +func (p *GoldilocksApi) Sub(a Variable, b Variable) Variable { return p.MulAdd(b, NewVariable(MODULUS.Uint64()-1), a) } // Subtracts two field elements such that x + y = z within the Golidlocks field without reducing. -func (p *GoldilocksApi) SubNoReduce(a GoldilocksVariable, b GoldilocksVariable) GoldilocksVariable { +func (p *GoldilocksApi) SubNoReduce(a Variable, b Variable) Variable { return NewVariable(p.api.Add(a.Limb, p.api.Mul(b.Limb, MODULUS.Uint64()-1))) } // Multiplies two field elements such that x * y = z within the Golidlocks field. -func (p *GoldilocksApi) Mul(a GoldilocksVariable, b GoldilocksVariable) GoldilocksVariable { +func (p *GoldilocksApi) Mul(a Variable, b Variable) Variable { return p.MulAdd(a, b, Zero()) } // Multiplies two field elements such that x * y = z within the Golidlocks field without reducing. -func (p *GoldilocksApi) MulNoReduce(a GoldilocksVariable, b GoldilocksVariable) GoldilocksVariable { +func (p *GoldilocksApi) MulNoReduce(a Variable, b Variable) Variable { return NewVariable(p.api.Mul(a.Limb, b.Limb)) } // Multiplies two field elements and adds a field element such that x * y + z = c within the // Golidlocks field. -func (p *GoldilocksApi) MulAdd(a GoldilocksVariable, b GoldilocksVariable, c GoldilocksVariable) GoldilocksVariable { +func (p *GoldilocksApi) MulAdd(a Variable, b Variable, c Variable) Variable { result, err := p.api.Compiler().NewHint(MulAddHint, 2, a.Limb, b.Limb, c.Limb) if err != nil { panic(err) @@ -140,7 +140,7 @@ func (p *GoldilocksApi) MulAdd(a GoldilocksVariable, b GoldilocksVariable, c Gol // Multiplies two field elements and adds a field element such that x * y + z = c within the // Golidlocks field without reducing. -func (p *GoldilocksApi) MulAddNoReduce(a GoldilocksVariable, b GoldilocksVariable, c GoldilocksVariable) GoldilocksVariable { +func (p *GoldilocksApi) MulAddNoReduce(a Variable, b Variable, c Variable) Variable { return p.AddNoReduce(p.MulNoReduce(a, b), c) } @@ -168,7 +168,7 @@ func MulAddHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { } // Reduces a field element x such that x % MODULUS = y. -func (p *GoldilocksApi) Reduce(x GoldilocksVariable) GoldilocksVariable { +func (p *GoldilocksApi) Reduce(x Variable) Variable { // Witness a `quotient` and `remainder` such that: // // MODULUS * quotient + remainder = x @@ -192,7 +192,7 @@ func (p *GoldilocksApi) Reduce(x GoldilocksVariable) GoldilocksVariable { } // Reduces a field element x such that x % MODULUS = y. -func (p *GoldilocksApi) ReduceWithMaxBits(x GoldilocksVariable, maxNbBits uint64) GoldilocksVariable { +func (p *GoldilocksApi) ReduceWithMaxBits(x Variable, maxNbBits uint64) Variable { // Witness a `quotient` and `remainder` such that: // // MODULUS * quotient + remainder = x @@ -227,7 +227,7 @@ func ReduceHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { } // Computes the inverse of a field element x such that x * x^-1 = 1. -func (p *GoldilocksApi) Inverse(x GoldilocksVariable) GoldilocksVariable { +func (p *GoldilocksApi) Inverse(x Variable) Variable { result, err := p.api.Compiler().NewHint(InverseHint, 1, x.Limb) if err != nil { panic(err) @@ -261,7 +261,7 @@ func InverseHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { } // Computes a field element raised to some power. -func (p *GoldilocksApi) Exp(x GoldilocksVariable, k *big.Int) GoldilocksVariable { +func (p *GoldilocksApi) Exp(x Variable, k *big.Int) Variable { if k.IsUint64() && k.Uint64() == 0 { return One() } @@ -306,7 +306,7 @@ func SplitLimbsHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { } // Range checks a field element x to be less than the Golidlocks modulus 2 ^ 64 - 2 ^ 32 + 1. -func (p *GoldilocksApi) RangeCheck(x GoldilocksVariable) { +func (p *GoldilocksApi) RangeCheck(x Variable) { // The Goldilocks' modulus is 2^64 - 2^32 + 1, which is: // // 1111111111111111111111111111111100000000000000000000000000000001 @@ -350,7 +350,7 @@ func (p *GoldilocksApi) RangeCheck(x GoldilocksVariable) { ) } -func (p *GoldilocksApi) AssertIsEqual(x, y GoldilocksVariable) { +func (p *GoldilocksApi) AssertIsEqual(x, y Variable) { p.api.AssertIsEqual(x.Limb, y.Limb) } diff --git a/goldilocks/quadratic_extension.go b/goldilocks/quadratic_extension.go index 3a4c80d..62f5f65 100644 --- a/goldilocks/quadratic_extension.go +++ b/goldilocks/quadratic_extension.go @@ -9,13 +9,13 @@ import ( const W uint64 = 7 const DTH_ROOT uint64 = 18446744069414584320 -type QuadraticExtensionVariable [2]GoldilocksVariable +type QuadraticExtensionVariable [2]Variable -func NewQuadraticExtensionVariable(x GoldilocksVariable, y GoldilocksVariable) QuadraticExtensionVariable { +func NewQuadraticExtensionVariable(x Variable, y Variable) QuadraticExtensionVariable { return QuadraticExtensionVariable{x, y} } -func (p GoldilocksVariable) ToQuadraticExtension() QuadraticExtensionVariable { +func (p Variable) ToQuadraticExtension() QuadraticExtensionVariable { return NewQuadraticExtensionVariable(p, Zero()) } @@ -101,7 +101,7 @@ func (p *GoldilocksApi) SubMulExtension(a, b, c QuadraticExtensionVariable) Quad // Multiplies quadratic extension variable in the Goldilocks field by a scalar. func (p *GoldilocksApi) ScalarMulExtension( a QuadraticExtensionVariable, - b GoldilocksVariable, + b Variable, ) QuadraticExtensionVariable { return NewQuadraticExtensionVariable( p.Mul(a[0], b), @@ -111,7 +111,7 @@ func (p *GoldilocksApi) ScalarMulExtension( // Computes an inner product over quadratic extension variable vectors in the Goldilocks field. func (p *GoldilocksApi) InnerProductExtension( - constant GoldilocksVariable, + constant Variable, startingAcc QuadraticExtensionVariable, pairs [][2]QuadraticExtensionVariable, ) QuadraticExtensionVariable { diff --git a/goldilocks/utils.go b/goldilocks/utils.go index 0101868..654230f 100644 --- a/goldilocks/utils.go +++ b/goldilocks/utils.go @@ -24,8 +24,8 @@ func StrArrayToFrontendVariableArray(input []string) []frontend.Variable { return output } -func Uint64ArrayToVariableArray(input []uint64) []GoldilocksVariable { - var output []GoldilocksVariable +func Uint64ArrayToVariableArray(input []uint64) []Variable { + var output []Variable for i := 0; i < len(input); i++ { output = append(output, NewVariable(input[i])) } diff --git a/plonk/plonk.go b/plonk/plonk.go index 4baaf8d..26e7b97 100644 --- a/plonk/plonk.go +++ b/plonk/plonk.go @@ -13,8 +13,8 @@ type PlonkChip struct { commonData types.CommonCircuitData `gnark:"-"` - DEGREE gl.GoldilocksVariable `gnark:"-"` - DEGREE_BITS_F gl.GoldilocksVariable `gnark:"-"` + DEGREE gl.Variable `gnark:"-"` + DEGREE_BITS_F gl.Variable `gnark:"-"` DEGREE_QE gl.QuadraticExtensionVariable `gnark:"-"` evaluateGatesChip *gates.EvaluateGatesChip diff --git a/poseidon/bn254.go b/poseidon/bn254.go index 51afe0f..ff54d3d 100644 --- a/poseidon/bn254.go +++ b/poseidon/bn254.go @@ -39,7 +39,7 @@ func (c *BN254Chip) Poseidon(state BN254State) BN254State { return state } -func (c *BN254Chip) HashNoPad(input []gl.GoldilocksVariable) BN254HashOut { +func (c *BN254Chip) HashNoPad(input []gl.Variable) BN254HashOut { state := BN254State{ frontend.Variable(0), frontend.Variable(0), @@ -69,7 +69,7 @@ func (c *BN254Chip) HashNoPad(input []gl.GoldilocksVariable) BN254HashOut { return BN254HashOut(state[0]) } -func (c *BN254Chip) HashOrNoop(input []gl.GoldilocksVariable) BN254HashOut { +func (c *BN254Chip) HashOrNoop(input []gl.Variable) BN254HashOut { if len(input) <= 3 { returnVal := frontend.Variable(0) @@ -94,10 +94,10 @@ func (c *BN254Chip) TwoToOne(left BN254HashOut, right BN254HashOut) BN254HashOut return state[0] } -func (c *BN254Chip) ToVec(hash BN254HashOut) []gl.GoldilocksVariable { +func (c *BN254Chip) ToVec(hash BN254HashOut) []gl.Variable { bits := c.api.ToBinary(hash) - returnElements := []gl.GoldilocksVariable{} + returnElements := []gl.Variable{} // Split into 7 byte chunks, since 8 byte chunks can result in collisions chunkSize := 56 diff --git a/poseidon/goldilocks.go b/poseidon/goldilocks.go index 509ef55..1764deb 100644 --- a/poseidon/goldilocks.go +++ b/poseidon/goldilocks.go @@ -11,9 +11,9 @@ const MAX_WIDTH = 12 const SPONGE_WIDTH = 12 const SPONGE_RATE = 8 -type GoldilocksState = [SPONGE_WIDTH]gl.GoldilocksVariable +type GoldilocksState = [SPONGE_WIDTH]gl.Variable type GoldilocksStateExtension = [SPONGE_WIDTH]gl.QuadraticExtensionVariable -type GoldilocksHashOut = [4]gl.GoldilocksVariable +type GoldilocksHashOut = [4]gl.Variable type GoldilocksChip struct { api frontend.API `gnark:"-"` @@ -38,7 +38,7 @@ func (c *GoldilocksChip) Poseidon(input GoldilocksState) GoldilocksState { // The input elements MUST have all it's elements be within Goldilocks field. // The returned slice's elements will all be within Goldilocks field. -func (c *GoldilocksChip) HashNToMNoPad(input []gl.GoldilocksVariable, nbOutputs int) []gl.GoldilocksVariable { +func (c *GoldilocksChip) HashNToMNoPad(input []gl.Variable, nbOutputs int) []gl.Variable { var state GoldilocksState for i := 0; i < SPONGE_WIDTH; i++ { @@ -54,7 +54,7 @@ func (c *GoldilocksChip) HashNToMNoPad(input []gl.GoldilocksVariable, nbOutputs state = c.Poseidon(state) } - var outputs []gl.GoldilocksVariable + var outputs []gl.Variable for { for i := 0; i < SPONGE_RATE; i++ { @@ -69,9 +69,9 @@ func (c *GoldilocksChip) HashNToMNoPad(input []gl.GoldilocksVariable, nbOutputs // The input elements can be outside of the Goldilocks field. // The returned slice's elements will all be within Goldilocks field. -func (c *GoldilocksChip) HashNoPad(input []gl.GoldilocksVariable) GoldilocksHashOut { +func (c *GoldilocksChip) HashNoPad(input []gl.Variable) GoldilocksHashOut { var hash GoldilocksHashOut - inputVars := []gl.GoldilocksVariable{} + inputVars := []gl.Variable{} for i := 0; i < len(input); i++ { inputVars = append(inputVars, c.gl.Reduce(input[i])) @@ -85,7 +85,7 @@ func (c *GoldilocksChip) HashNoPad(input []gl.GoldilocksVariable) GoldilocksHash return hash } -func (c *GoldilocksChip) ToVec(hash GoldilocksHashOut) []gl.GoldilocksVariable { +func (c *GoldilocksChip) ToVec(hash GoldilocksHashOut) []gl.Variable { return hash[:] } @@ -135,7 +135,7 @@ func (c *GoldilocksChip) ConstantLayerExtension(state GoldilocksStateExtension, return state } -func (c *GoldilocksChip) sBoxMonomial(x gl.GoldilocksVariable) gl.GoldilocksVariable { +func (c *GoldilocksChip) sBoxMonomial(x gl.Variable) gl.Variable { x2 := c.gl.MulNoReduce(x, x) x3 := c.gl.MulNoReduce(x, x2) x3 = c.gl.ReduceWithMaxBits(x3, 192) @@ -169,7 +169,7 @@ func (c *GoldilocksChip) SBoxLayerExtension(state GoldilocksStateExtension) Gold return state } -func (c *GoldilocksChip) mdsRowShf(r int, v [SPONGE_WIDTH]gl.GoldilocksVariable) gl.GoldilocksVariable { +func (c *GoldilocksChip) mdsRowShf(r int, v [SPONGE_WIDTH]gl.Variable) gl.Variable { res := gl.Zero() for i := 0; i < 12; i++ { diff --git a/poseidon/public_inputs_hash_test.go b/poseidon/public_inputs_hash_test.go index a11d5a1..bd510bb 100644 --- a/poseidon/public_inputs_hash_test.go +++ b/poseidon/public_inputs_hash_test.go @@ -21,7 +21,7 @@ func (circuit *TestPublicInputsHashCircuit) Define(api frontend.API) error { glAPI := gl.NewGoldilocksApi(api) // BN254 -> Binary(64) -> F - var input [3]gl.GoldilocksVariable + var input [3]gl.Variable for i := 0; i < 3; i++ { input[i] = gl.NewVariable(api.FromBinary(api.ToBinary(circuit.In[i], 64)...)) } diff --git a/types/circuit.go b/types/circuit.go index 7b5fb9a..9e46d30 100644 --- a/types/circuit.go +++ b/types/circuit.go @@ -16,7 +16,7 @@ type Proof struct { type ProofWithPublicInputs struct { Proof Proof - PublicInputs []gl.GoldilocksVariable // Length = CommonCircuitData.NumPublicInputs + PublicInputs []gl.Variable // Length = CommonCircuitData.NumPublicInputs } type VerifierOnlyCircuitData struct { @@ -46,6 +46,6 @@ type CommonCircuitData struct { NumGateConstraints uint64 NumConstants uint64 NumPublicInputs uint64 - KIs []gl.GoldilocksVariable + KIs []gl.Variable NumPartialProducts uint64 } diff --git a/types/fri.go b/types/fri.go index 59e6fdc..aaea0f3 100644 --- a/types/fri.go +++ b/types/fri.go @@ -47,11 +47,11 @@ func NewFriMerkleProof(merkleProofLen uint64) FriMerkleProof { } type FriEvalProof struct { - Elements []gl.GoldilocksVariable // Length = [CommonCircuitData.Constants + CommonCircuitData.NumRoutedWires, CommonCircuitData.NumWires + CommonCircuitData.FriParams.Hiding ? 4 : 0, CommonCircuitData.NumChallenges * (1 + CommonCircuitData.NumPartialProducts) + salt, CommonCircuitData.NumChallenges * CommonCircuitData.QuotientDegreeFactor + salt] + Elements []gl.Variable // Length = [CommonCircuitData.Constants + CommonCircuitData.NumRoutedWires, CommonCircuitData.NumWires + CommonCircuitData.FriParams.Hiding ? 4 : 0, CommonCircuitData.NumChallenges * (1 + CommonCircuitData.NumPartialProducts) + salt, CommonCircuitData.NumChallenges * CommonCircuitData.QuotientDegreeFactor + salt] MerkleProof FriMerkleProof } -func NewFriEvalProof(elements []gl.GoldilocksVariable, merkleProof FriMerkleProof) FriEvalProof { +func NewFriEvalProof(elements []gl.Variable, merkleProof FriMerkleProof) FriEvalProof { return FriEvalProof{Elements: elements, MerkleProof: merkleProof} } @@ -88,12 +88,12 @@ type FriProof struct { CommitPhaseMerkleCaps []FriMerkleCap // Length = Len(CommonCircuitData.FriParams.ReductionArityBits) QueryRoundProofs []FriQueryRound // Length = CommonCircuitData.FriConfig.FriParams.NumQueryRounds FinalPoly PolynomialCoeffs - PowWitness gl.GoldilocksVariable + PowWitness gl.Variable } type FriChallenges struct { FriAlpha gl.QuadraticExtensionVariable FriBetas []gl.QuadraticExtensionVariable - FriPowResponse gl.GoldilocksVariable - FriQueryIndices []gl.GoldilocksVariable + FriPowResponse gl.Variable + FriQueryIndices []gl.Variable } diff --git a/types/plonk.go b/types/plonk.go index b9a36d1..f0b03b9 100644 --- a/types/plonk.go +++ b/types/plonk.go @@ -25,9 +25,9 @@ func NewOpeningSet(numConstants uint64, numRoutedWires uint64, numWires uint64, } type ProofChallenges struct { - PlonkBetas []gl.GoldilocksVariable - PlonkGammas []gl.GoldilocksVariable - PlonkAlphas []gl.GoldilocksVariable + PlonkBetas []gl.Variable + PlonkGammas []gl.Variable + PlonkAlphas []gl.Variable PlonkZeta gl.QuadraticExtensionVariable FriChallenges FriChallenges } diff --git a/verifier/verifier.go b/verifier/verifier.go index 68da5c7..a5bd262 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -35,7 +35,7 @@ func NewVerifierChip(api frontend.API, commonCircuitData types.CommonCircuitData } } -func (c *VerifierChip) GetPublicInputsHash(publicInputs []gl.GoldilocksVariable) poseidon.GoldilocksHashOut { +func (c *VerifierChip) GetPublicInputsHash(publicInputs []gl.Variable) poseidon.GoldilocksHashOut { return c.poseidonGlChip.HashNoPad(publicInputs) } @@ -206,7 +206,7 @@ func (c *VerifierChip) rangeCheckProof(proof types.Proof) { func (c *VerifierChip) Verify( proof types.Proof, - publicInputs []gl.GoldilocksVariable, + publicInputs []gl.Variable, verifierData types.VerifierOnlyCircuitData, commonData types.CommonCircuitData, ) { diff --git a/verifier/verifier_test.go b/verifier/verifier_test.go index 4ca3924..e9cd2d5 100644 --- a/verifier/verifier_test.go +++ b/verifier/verifier_test.go @@ -15,7 +15,7 @@ import ( type TestVerifierCircuit struct { Proof types.Proof - PublicInputs []gl.GoldilocksVariable `gnark:",public"` + PublicInputs []gl.Variable `gnark:",public"` verifierChip *verifier.VerifierChip `gnark:"-"` plonky2CircuitName string `gnark:"-"` From 5d53737841e4ae980df732d8851fe298f5d4a06f Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Wed, 11 Oct 2023 12:01:26 -0700 Subject: [PATCH 07/13] Moved to variables --- benchmark.go | 4 +- benchmark_plonk.go | 4 +- challenger/challenger.go | 14 +++---- fri/fri.go | 38 +++++++++--------- fri/fri_test.go | 6 +-- fri/fri_utils.go | 30 +++++++------- goldilocks/base.go | 39 +++++++++--------- goldilocks/base_test.go | 6 +-- goldilocks/quadratic_extension.go | 42 ++++++++++---------- goldilocks/quadratic_extension_algebra.go | 10 ++--- goldilocks/quadratic_extension_test.go | 4 +- plonk/gates/arithmetic_extension_gate.go | 2 +- plonk/gates/arithmetic_gate.go | 2 +- plonk/gates/base_sum_gate.go | 2 +- plonk/gates/constant_gate.go | 2 +- plonk/gates/coset_interpolation_gate.go | 2 +- plonk/gates/evaluate_gates.go | 6 +-- plonk/gates/exponentiation_gate.go | 2 +- plonk/gates/gates.go | 2 +- plonk/gates/gates_test.go | 2 +- plonk/gates/multiplication_extension_gate.go | 2 +- plonk/gates/noop_gate.go | 2 +- plonk/gates/poseidon_gate.go | 2 +- plonk/gates/poseidon_mds_gate.go | 4 +- plonk/gates/public_input_gate.go | 2 +- plonk/gates/random_access_gate.go | 2 +- plonk/gates/reducing_extension_gate.go | 2 +- plonk/gates/reducing_gate.go | 2 +- plonk/plonk.go | 26 ++++++------ poseidon/bn254.go | 6 +-- poseidon/goldilocks.go | 6 +-- poseidon/goldilocks_test.go | 2 +- poseidon/public_inputs_hash_test.go | 2 +- {types => variables}/circuit.go | 2 +- {types => variables}/fri.go | 2 +- {types => variables}/plonk.go | 2 +- verifier/deserialize.go | 40 +++++++++---------- verifier/verifier.go | 28 ++++++------- verifier/verifier_test.go | 4 +- 39 files changed, 180 insertions(+), 177 deletions(-) rename {types => variables}/circuit.go (98%) rename {types => variables}/fri.go (99%) rename {types => variables}/plonk.go (98%) diff --git a/benchmark.go b/benchmark.go index 9f341b2..ad468fd 100644 --- a/benchmark.go +++ b/benchmark.go @@ -9,7 +9,7 @@ import ( "time" gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" - "github.com/succinctlabs/gnark-plonky2-verifier/types" + "github.com/succinctlabs/gnark-plonky2-verifier/variables" "github.com/succinctlabs/gnark-plonky2-verifier/verifier" "github.com/consensys/gnark-crypto/ecc" @@ -21,7 +21,7 @@ import ( ) type BenchmarkPlonky2VerifierCircuit struct { - Proof types.Proof + Proof variables.Proof PublicInputs []gl.Variable `gnark:",public"` verifierChip *verifier.VerifierChip `gnark:"-"` diff --git a/benchmark_plonk.go b/benchmark_plonk.go index 6f7df12..9089d17 100644 --- a/benchmark_plonk.go +++ b/benchmark_plonk.go @@ -9,7 +9,7 @@ import ( "time" gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" - "github.com/succinctlabs/gnark-plonky2-verifier/types" + "github.com/succinctlabs/gnark-plonky2-verifier/variables" "github.com/succinctlabs/gnark-plonky2-verifier/verifier" "github.com/consensys/gnark-crypto/ecc" @@ -22,7 +22,7 @@ import ( ) type BenchmarkPlonky2VerifierCircuitPlonk struct { - Proof types.Proof + Proof variables.Proof PublicInputs []gl.Variable `gnark:",public"` verifierChip *verifier.VerifierChip `gnark:"-"` diff --git a/challenger/challenger.go b/challenger/challenger.go index a1c07be..91e656d 100644 --- a/challenger/challenger.go +++ b/challenger/challenger.go @@ -7,7 +7,7 @@ import ( "github.com/succinctlabs/gnark-plonky2-verifier/fri" gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" - "github.com/succinctlabs/gnark-plonky2-verifier/types" + "github.com/succinctlabs/gnark-plonky2-verifier/variables" ) type Chip struct { @@ -113,12 +113,12 @@ func (c *Chip) GetHash() poseidon.GoldilocksHashOut { } func (c *Chip) GetFriChallenges( - commitPhaseMerkleCaps []types.FriMerkleCap, - finalPoly types.PolynomialCoeffs, + commitPhaseMerkleCaps []variables.FriMerkleCap, + finalPoly variables.PolynomialCoeffs, powWitness gl.Variable, degreeBits uint64, - config types.FriConfig, -) types.FriChallenges { + config variables.FriConfig, +) variables.FriChallenges { numFriQueries := config.NumQueryRounds friAlpha := c.GetExtensionChallenge() @@ -134,7 +134,7 @@ func (c *Chip) GetFriChallenges( friPowResponse := c.GetChallenge() friQueryIndices := c.GetNChallenges(numFriQueries) - return types.FriChallenges{ + return variables.FriChallenges{ FriAlpha: friAlpha, FriBetas: friBetas, FriPowResponse: friPowResponse, @@ -152,7 +152,7 @@ func (c *Chip) duplexing() { panic("something went wrong") } - glApi := gl.NewGoldilocksApi(c.api) + glApi := gl.New(c.api) for i := 0; i < len(c.inputBuffer); i++ { c.spongeState[i] = glApi.Reduce(c.inputBuffer[i]) diff --git a/fri/fri.go b/fri/fri.go index 9610e50..86aedfa 100644 --- a/fri/fri.go +++ b/fri/fri.go @@ -10,30 +10,30 @@ import ( "github.com/consensys/gnark/frontend" gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" - "github.com/succinctlabs/gnark-plonky2-verifier/types" + "github.com/succinctlabs/gnark-plonky2-verifier/variables" ) type Chip struct { - api frontend.API `gnark:"-"` - gl gl.GoldilocksApi `gnark:"-"` + api frontend.API `gnark:"-"` + gl gl.Chip `gnark:"-"` poseidonBN254Chip *poseidon.BN254Chip - friParams *types.FriParams `gnark:"-"` + friParams *variables.FriParams `gnark:"-"` } func NewChip( api frontend.API, - friParams *types.FriParams, + friParams *variables.FriParams, ) *Chip { poseidonBN254Chip := poseidon.NewBN254Chip(api) return &Chip{ api: api, poseidonBN254Chip: poseidonBN254Chip, friParams: friParams, - gl: *gl.NewGoldilocksApi(api), + gl: *gl.New(api), } } -func (f *Chip) assertLeadingZeros(powWitness gl.Variable, friConfig types.FriConfig) { +func (f *Chip) assertLeadingZeros(powWitness gl.Variable, friConfig variables.FriConfig) { // Asserts that powWitness'es big-endian bit representation has at least `leading_zeros` leading zeros. // Note that this is assuming that the Goldilocks field is being used. Specfically that the // field is 64 bits long @@ -61,8 +61,8 @@ func (f *Chip) verifyMerkleProofToCapWithCapIndex( leafData []gl.Variable, leafIndexBits []frontend.Variable, capIndexBits []frontend.Variable, - merkleCap types.FriMerkleCap, - proof *types.FriMerkleProof, + merkleCap variables.FriMerkleCap, + proof *variables.FriMerkleProof, ) { currentDigest := f.poseidonBN254Chip.HashOrNoop(leafData) for i, sibling := range proof.Siblings { @@ -100,7 +100,7 @@ func (f *Chip) verifyMerkleProofToCapWithCapIndex( f.api.AssertIsEqual(currentDigest, merkleCapEntry) } -func (f *Chip) verifyInitialProof(xIndexBits []frontend.Variable, proof *types.FriInitialTreeProof, initialMerkleCaps []types.FriMerkleCap, capIndexBits []frontend.Variable) { +func (f *Chip) verifyInitialProof(xIndexBits []frontend.Variable, proof *variables.FriInitialTreeProof, initialMerkleCaps []variables.FriMerkleCap, capIndexBits []frontend.Variable) { if len(proof.EvalsProofs) != len(initialMerkleCaps) { panic("length of eval proofs in fri proof should equal length of initial merkle caps") } @@ -187,7 +187,7 @@ func (f *Chip) calculateSubgroupX( func (f *Chip) friCombineInitial( instance InstanceInfo, - proof types.FriInitialTreeProof, + proof variables.FriInitialTreeProof, friAlpha gl.QuadraticExtensionVariable, subgroupX_QE gl.QuadraticExtensionVariable, precomputedReducedEval []gl.QuadraticExtensionVariable, @@ -228,7 +228,7 @@ func (f *Chip) friCombineInitial( return sum } -func (f *Chip) finalPolyEval(finalPoly types.PolynomialCoeffs, point gl.QuadraticExtensionVariable) gl.QuadraticExtensionVariable { +func (f *Chip) finalPolyEval(finalPoly variables.PolynomialCoeffs, point gl.QuadraticExtensionVariable) gl.QuadraticExtensionVariable { ret := gl.ZeroExtension() for i := len(finalPoly.Coeffs) - 1; i >= 0; i-- { ret = f.gl.MulAddExtension(ret, point, finalPoly.Coeffs[i]) @@ -355,14 +355,14 @@ func (f *Chip) computeEvaluation( func (f *Chip) verifyQueryRound( instance InstanceInfo, - challenges *types.FriChallenges, + challenges *variables.FriChallenges, precomputedReducedEval []gl.QuadraticExtensionVariable, - initialMerkleCaps []types.FriMerkleCap, - proof *types.FriProof, + initialMerkleCaps []variables.FriMerkleCap, + proof *variables.FriProof, xIndex gl.Variable, n uint64, nLog uint64, - roundProof *types.FriQueryRound, + roundProof *variables.FriQueryRound, ) { f.assertNoncanonicalIndicesOK() xIndex = f.gl.Reduce(xIndex) @@ -468,9 +468,9 @@ func (f *Chip) verifyQueryRound( func (f *Chip) VerifyFriProof( instance InstanceInfo, openings Openings, - friChallenges *types.FriChallenges, - initialMerkleCaps []types.FriMerkleCap, - friProof *types.FriProof, + friChallenges *variables.FriChallenges, + initialMerkleCaps []variables.FriMerkleCap, + friProof *variables.FriProof, ) { // TODO: Check fri config /* if let Some(max_arity_bits) = params.max_arity_bits() { diff --git a/fri/fri_test.go b/fri/fri_test.go index 2faf638..4a8e507 100644 --- a/fri/fri_test.go +++ b/fri/fri_test.go @@ -10,7 +10,7 @@ import ( "github.com/succinctlabs/gnark-plonky2-verifier/fri" gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" - "github.com/succinctlabs/gnark-plonky2-verifier/types" + "github.com/succinctlabs/gnark-plonky2-verifier/variables" "github.com/succinctlabs/gnark-plonky2-verifier/verifier" ) @@ -25,7 +25,7 @@ func (circuit *TestFriCircuit) Define(api frontend.API) error { commonCircuitData := verifier.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename) verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuit.verifierOnlyCircuitDataFilename) - glApi := gl.NewGoldilocksApi(api) + glApi := gl.New(api) poseidonChip := poseidon.NewGoldilocksChip(api) friChip := fri.NewChip(api, &commonCircuitData.FriParams) challengerChip := challenger.NewChip(api) @@ -67,7 +67,7 @@ func (circuit *TestFriCircuit) Define(api frontend.API) error { x = 11890500485816111017 api.AssertIsEqual(friChallenges.FriQueryIndices[0].Limb, x) - initialMerkleCaps := []types.FriMerkleCap{ + initialMerkleCaps := []variables.FriMerkleCap{ verifierOnlyCircuitData.ConstantSigmasCap, proofWithPis.Proof.WiresCap, proofWithPis.Proof.PlonkZsPartialProductsCap, diff --git a/fri/fri_utils.go b/fri/fri_utils.go index 4f5cdc8..aacd5e1 100644 --- a/fri/fri_utils.go +++ b/fri/fri_utils.go @@ -2,7 +2,7 @@ package fri import ( gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" - "github.com/succinctlabs/gnark-plonky2-verifier/types" + "github.com/succinctlabs/gnark-plonky2-verifier/variables" ) type OpeningBatch struct { @@ -13,7 +13,7 @@ type Openings struct { Batches []OpeningBatch } -func ToOpenings(c types.OpeningSet) Openings { +func ToOpenings(c variables.OpeningSet) Openings { values := c.Constants // num_constants + 1 values = append(values, c.PlonkSigmas...) // num_routed_wires values = append(values, c.Wires...) // num_wires @@ -70,7 +70,7 @@ var QUOTIENT = PlonkOracle{ blinding: true, } -func polynomialInfoFromRange(c *types.CommonCircuitData, oracleIdx uint64, startPolyIdx uint64, endPolyIdx uint64) []PolynomialInfo { +func polynomialInfoFromRange(c *variables.CommonCircuitData, oracleIdx uint64, startPolyIdx uint64, endPolyIdx uint64) []PolynomialInfo { returnArr := make([]PolynomialInfo, 0) for i := startPolyIdx; i < endPolyIdx; i++ { returnArr = append(returnArr, @@ -84,7 +84,7 @@ func polynomialInfoFromRange(c *types.CommonCircuitData, oracleIdx uint64, start } // Range of the sigma polynomials in the `constants_sigmas_commitment`. -func sigmasRange(c *types.CommonCircuitData) []uint64 { +func sigmasRange(c *variables.CommonCircuitData) []uint64 { returnArr := make([]uint64, 0) for i := c.NumConstants; i <= c.NumConstants+c.Config.NumRoutedWires; i++ { returnArr = append(returnArr, i) @@ -93,20 +93,20 @@ func sigmasRange(c *types.CommonCircuitData) []uint64 { return returnArr } -func numPreprocessedPolys(c *types.CommonCircuitData) uint64 { +func numPreprocessedPolys(c *variables.CommonCircuitData) uint64 { sigmasRange := sigmasRange(c) return sigmasRange[len(sigmasRange)-1] } -func numZSPartialProductsPolys(c *types.CommonCircuitData) uint64 { +func numZSPartialProductsPolys(c *variables.CommonCircuitData) uint64 { return c.Config.NumChallenges * (1 + c.NumPartialProducts) } -func numQuotientPolys(c *types.CommonCircuitData) uint64 { +func numQuotientPolys(c *variables.CommonCircuitData) uint64 { return c.Config.NumChallenges * c.QuotientDegreeFactor } -func friPreprocessedPolys(c *types.CommonCircuitData) []PolynomialInfo { +func friPreprocessedPolys(c *variables.CommonCircuitData) []PolynomialInfo { return polynomialInfoFromRange( c, CONSTANTS_SIGMAS.index, @@ -115,12 +115,12 @@ func friPreprocessedPolys(c *types.CommonCircuitData) []PolynomialInfo { ) } -func friWirePolys(c *types.CommonCircuitData) []PolynomialInfo { +func friWirePolys(c *variables.CommonCircuitData) []PolynomialInfo { numWirePolys := c.Config.NumWires return polynomialInfoFromRange(c, WIRES.index, 0, numWirePolys) } -func friZSPartialProductsPolys(c *types.CommonCircuitData) []PolynomialInfo { +func friZSPartialProductsPolys(c *variables.CommonCircuitData) []PolynomialInfo { return polynomialInfoFromRange( c, ZS_PARTIAL_PRODUCTS.index, @@ -129,7 +129,7 @@ func friZSPartialProductsPolys(c *types.CommonCircuitData) []PolynomialInfo { ) } -func friQuotientPolys(c *types.CommonCircuitData) []PolynomialInfo { +func friQuotientPolys(c *variables.CommonCircuitData) []PolynomialInfo { return polynomialInfoFromRange( c, QUOTIENT.index, @@ -138,7 +138,7 @@ func friQuotientPolys(c *types.CommonCircuitData) []PolynomialInfo { ) } -func friZSPolys(c *types.CommonCircuitData) []PolynomialInfo { +func friZSPolys(c *variables.CommonCircuitData) []PolynomialInfo { return polynomialInfoFromRange( c, ZS_PARTIAL_PRODUCTS.index, @@ -147,7 +147,7 @@ func friZSPolys(c *types.CommonCircuitData) []PolynomialInfo { ) } -func friOracles(c *types.CommonCircuitData) []OracleInfo { +func friOracles(c *variables.CommonCircuitData) []OracleInfo { return []OracleInfo{ { NumPolys: numPreprocessedPolys(c), @@ -168,7 +168,7 @@ func friOracles(c *types.CommonCircuitData) []OracleInfo { } } -func friAllPolys(c *types.CommonCircuitData) []PolynomialInfo { +func friAllPolys(c *variables.CommonCircuitData) []PolynomialInfo { returnArr := make([]PolynomialInfo, 0) returnArr = append(returnArr, friPreprocessedPolys(c)...) returnArr = append(returnArr, friWirePolys(c)...) @@ -178,7 +178,7 @@ func friAllPolys(c *types.CommonCircuitData) []PolynomialInfo { return returnArr } -func GetInstance(c *types.CommonCircuitData, glApi *gl.GoldilocksApi, zeta gl.QuadraticExtensionVariable, degreeBits uint64) InstanceInfo { +func GetInstance(c *variables.CommonCircuitData, glApi *gl.Chip, zeta gl.QuadraticExtensionVariable, degreeBits uint64) InstanceInfo { zetaBatch := BatchInfo{ Point: zeta, Polynomials: friAllPolys(c), diff --git a/goldilocks/base.go b/goldilocks/base.go index c6a5cca..d51a978 100644 --- a/goldilocks/base.go +++ b/goldilocks/base.go @@ -11,6 +11,9 @@ package goldilocks // be very beneficial to use the no reduction methods and keep track of the maximum number of bits // your computation uses. +// This implementation is based on the following plonky2 implementation of Goldilocks +// Available here: https://github.com/0xPolygonZero/plonky2/blob/main/field/src/goldilocks_field.rs#L70 + import ( "fmt" "math" @@ -76,50 +79,50 @@ func NegOne() Variable { } // The chip used for Goldilocks field operations. -type GoldilocksApi struct { +type Chip struct { api frontend.API rangeChecker frontend.Rangechecker } -// Creates a new Goldilocks chip. -func NewGoldilocksApi(api frontend.API) *GoldilocksApi { +// Creates a new Goldilocks Chip. +func New(api frontend.API) *Chip { rangeChecker := rangecheck.New(api) - return &GoldilocksApi{api: api, rangeChecker: rangeChecker} + return &Chip{api: api, rangeChecker: rangeChecker} } // Adds two field elements such that x + y = z within the Golidlocks field. -func (p *GoldilocksApi) Add(a Variable, b Variable) Variable { +func (p *Chip) Add(a Variable, b Variable) Variable { return p.MulAdd(a, NewVariable(1), b) } // Adds two field elements such that x + y = z within the Golidlocks field without reducing. -func (p *GoldilocksApi) AddNoReduce(a Variable, b Variable) Variable { +func (p *Chip) AddNoReduce(a Variable, b Variable) Variable { return NewVariable(p.api.Add(a.Limb, b.Limb)) } // Subtracts two field elements such that x + y = z within the Golidlocks field. -func (p *GoldilocksApi) Sub(a Variable, b Variable) Variable { +func (p *Chip) Sub(a Variable, b Variable) Variable { return p.MulAdd(b, NewVariable(MODULUS.Uint64()-1), a) } // Subtracts two field elements such that x + y = z within the Golidlocks field without reducing. -func (p *GoldilocksApi) SubNoReduce(a Variable, b Variable) Variable { +func (p *Chip) SubNoReduce(a Variable, b Variable) Variable { return NewVariable(p.api.Add(a.Limb, p.api.Mul(b.Limb, MODULUS.Uint64()-1))) } // Multiplies two field elements such that x * y = z within the Golidlocks field. -func (p *GoldilocksApi) Mul(a Variable, b Variable) Variable { +func (p *Chip) Mul(a Variable, b Variable) Variable { return p.MulAdd(a, b, Zero()) } // Multiplies two field elements such that x * y = z within the Golidlocks field without reducing. -func (p *GoldilocksApi) MulNoReduce(a Variable, b Variable) Variable { +func (p *Chip) MulNoReduce(a Variable, b Variable) Variable { return NewVariable(p.api.Mul(a.Limb, b.Limb)) } // Multiplies two field elements and adds a field element such that x * y + z = c within the // Golidlocks field. -func (p *GoldilocksApi) MulAdd(a Variable, b Variable, c Variable) Variable { +func (p *Chip) MulAdd(a Variable, b Variable, c Variable) Variable { result, err := p.api.Compiler().NewHint(MulAddHint, 2, a.Limb, b.Limb, c.Limb) if err != nil { panic(err) @@ -140,7 +143,7 @@ func (p *GoldilocksApi) MulAdd(a Variable, b Variable, c Variable) Variable { // Multiplies two field elements and adds a field element such that x * y + z = c within the // Golidlocks field without reducing. -func (p *GoldilocksApi) MulAddNoReduce(a Variable, b Variable, c Variable) Variable { +func (p *Chip) MulAddNoReduce(a Variable, b Variable, c Variable) Variable { return p.AddNoReduce(p.MulNoReduce(a, b), c) } @@ -168,7 +171,7 @@ func MulAddHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { } // Reduces a field element x such that x % MODULUS = y. -func (p *GoldilocksApi) Reduce(x Variable) Variable { +func (p *Chip) Reduce(x Variable) Variable { // Witness a `quotient` and `remainder` such that: // // MODULUS * quotient + remainder = x @@ -192,7 +195,7 @@ func (p *GoldilocksApi) Reduce(x Variable) Variable { } // Reduces a field element x such that x % MODULUS = y. -func (p *GoldilocksApi) ReduceWithMaxBits(x Variable, maxNbBits uint64) Variable { +func (p *Chip) ReduceWithMaxBits(x Variable, maxNbBits uint64) Variable { // Witness a `quotient` and `remainder` such that: // // MODULUS * quotient + remainder = x @@ -227,7 +230,7 @@ func ReduceHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { } // Computes the inverse of a field element x such that x * x^-1 = 1. -func (p *GoldilocksApi) Inverse(x Variable) Variable { +func (p *Chip) Inverse(x Variable) Variable { result, err := p.api.Compiler().NewHint(InverseHint, 1, x.Limb) if err != nil { panic(err) @@ -261,7 +264,7 @@ func InverseHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { } // Computes a field element raised to some power. -func (p *GoldilocksApi) Exp(x Variable, k *big.Int) Variable { +func (p *Chip) Exp(x Variable, k *big.Int) Variable { if k.IsUint64() && k.Uint64() == 0 { return One() } @@ -306,7 +309,7 @@ func SplitLimbsHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error { } // Range checks a field element x to be less than the Golidlocks modulus 2 ^ 64 - 2 ^ 32 + 1. -func (p *GoldilocksApi) RangeCheck(x Variable) { +func (p *Chip) RangeCheck(x Variable) { // The Goldilocks' modulus is 2^64 - 2^32 + 1, which is: // // 1111111111111111111111111111111100000000000000000000000000000001 @@ -350,7 +353,7 @@ func (p *GoldilocksApi) RangeCheck(x Variable) { ) } -func (p *GoldilocksApi) AssertIsEqual(x, y Variable) { +func (p *Chip) AssertIsEqual(x, y Variable) { p.api.AssertIsEqual(x.Limb, y.Limb) } diff --git a/goldilocks/base_test.go b/goldilocks/base_test.go index 1a28dca..d2f6f51 100644 --- a/goldilocks/base_test.go +++ b/goldilocks/base_test.go @@ -19,7 +19,7 @@ type TestGoldilocksRangeCheckCircuit struct { } func (c *TestGoldilocksRangeCheckCircuit) Define(api frontend.API) error { - glApi := NewGoldilocksApi(api) + glApi := New(api) glApi.RangeCheck(NewVariable(c.X)) return nil } @@ -48,7 +48,7 @@ type TestGoldilocksRangeCheckBenchmarkCircuit struct { } func (c *TestGoldilocksRangeCheckBenchmarkCircuit) Define(api frontend.API) error { - glApi := NewGoldilocksApi(api) + glApi := New(api) for _, x := range c.X { glApi.RangeCheck(NewVariable(x)) glApi.Reduce(NewVariable(x)) @@ -88,7 +88,7 @@ type TestGoldilocksMulAddCircuit struct { } func (c *TestGoldilocksMulAddCircuit) Define(api frontend.API) error { - glApi := NewGoldilocksApi(api) + glApi := New(api) calculateValue := glApi.MulAdd(NewVariable(c.X), NewVariable(c.Y), NewVariable(c.Z)) api.AssertIsEqual(calculateValue.Limb, c.ExpectedResult) return nil diff --git a/goldilocks/quadratic_extension.go b/goldilocks/quadratic_extension.go index 62f5f65..d384300 100644 --- a/goldilocks/quadratic_extension.go +++ b/goldilocks/quadratic_extension.go @@ -28,35 +28,35 @@ func OneExtension() QuadraticExtensionVariable { } // Adds two quadratic extension variables in the Goldilocks field. -func (p *GoldilocksApi) AddExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *Chip) AddExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { c0 := p.Add(a[0], b[0]) c1 := p.Add(a[1], b[1]) return NewQuadraticExtensionVariable(c0, c1) } // Adds two quadratic extension variables in the Goldilocks field without reducing. -func (p *GoldilocksApi) AddExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *Chip) AddExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { c0 := p.AddNoReduce(a[0], b[0]) c1 := p.AddNoReduce(a[1], b[1]) return NewQuadraticExtensionVariable(c0, c1) } // Subtracts two quadratic extension variables in the Goldilocks field. -func (p *GoldilocksApi) SubExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *Chip) SubExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { c0 := p.Sub(a[0], b[0]) c1 := p.Sub(a[1], b[1]) return NewQuadraticExtensionVariable(c0, c1) } // Subtracts two quadratic extension variables in the Goldilocks field without reducing. -func (p *GoldilocksApi) SubExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *Chip) SubExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { c0 := p.SubNoReduce(a[0], b[0]) c1 := p.SubNoReduce(a[1], b[1]) return NewQuadraticExtensionVariable(c0, c1) } // Multiplies quadratic extension variable in the Goldilocks field. -func (p *GoldilocksApi) MulExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *Chip) MulExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { product := p.MulExtensionNoReduce(a, b) product[0] = p.Reduce(product[0]) product[1] = p.Reduce(product[1]) @@ -64,7 +64,7 @@ func (p *GoldilocksApi) MulExtension(a, b QuadraticExtensionVariable) QuadraticE } // Multiplies quadratic extension variable in the Goldilocks field without reducing. -func (p *GoldilocksApi) MulExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *Chip) MulExtensionNoReduce(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { c0o0 := p.MulNoReduce(a[0], b[0]) c0o1 := p.MulNoReduce(p.MulNoReduce(NewVariable(7), a[1]), b[1]) c0 := p.AddNoReduce(c0o0, c0o1) @@ -74,7 +74,7 @@ func (p *GoldilocksApi) MulExtensionNoReduce(a, b QuadraticExtensionVariable) Qu // Multiplies two operands a and b and adds to c in the Goldilocks extension field. a * b + c must // be less than RANGE_CHECK_NB_BITS bits. -func (p *GoldilocksApi) MulAddExtension(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *Chip) MulAddExtension(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { product := p.MulExtensionNoReduce(a, b) sum := p.AddExtensionNoReduce(product, c) sum[0] = p.Reduce(sum[0]) @@ -82,7 +82,7 @@ func (p *GoldilocksApi) MulAddExtension(a, b, c QuadraticExtensionVariable) Quad return sum } -func (p *GoldilocksApi) MulAddExtensionNoReduce(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *Chip) MulAddExtensionNoReduce(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { product := p.MulExtensionNoReduce(a, b) sum := p.AddExtensionNoReduce(product, c) return sum @@ -90,7 +90,7 @@ func (p *GoldilocksApi) MulAddExtensionNoReduce(a, b, c QuadraticExtensionVariab // Multiplies two operands a and b and subtracts to c in the Goldilocks extension field. a * b - c must // be less than RANGE_CHECK_NB_BITS bits. -func (p *GoldilocksApi) SubMulExtension(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *Chip) SubMulExtension(a, b, c QuadraticExtensionVariable) QuadraticExtensionVariable { difference := p.SubExtensionNoReduce(a, b) product := p.MulExtensionNoReduce(difference, c) product[0] = p.Reduce(product[0]) @@ -99,7 +99,7 @@ func (p *GoldilocksApi) SubMulExtension(a, b, c QuadraticExtensionVariable) Quad } // Multiplies quadratic extension variable in the Goldilocks field by a scalar. -func (p *GoldilocksApi) ScalarMulExtension( +func (p *Chip) ScalarMulExtension( a QuadraticExtensionVariable, b Variable, ) QuadraticExtensionVariable { @@ -110,7 +110,7 @@ func (p *GoldilocksApi) ScalarMulExtension( } // Computes an inner product over quadratic extension variable vectors in the Goldilocks field. -func (p *GoldilocksApi) InnerProductExtension( +func (p *Chip) InnerProductExtension( constant Variable, startingAcc QuadraticExtensionVariable, pairs [][2]QuadraticExtensionVariable, @@ -126,7 +126,7 @@ func (p *GoldilocksApi) InnerProductExtension( } // Computes the inverse of a quadratic extension variable in the Goldilocks field. -func (p *GoldilocksApi) InverseExtension(a QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *Chip) InverseExtension(a QuadraticExtensionVariable) QuadraticExtensionVariable { a0IsZero := p.api.IsZero(a[0].Limb) a1IsZero := p.api.IsZero(a[1].Limb) p.api.AssertIsEqual(p.api.Mul(a0IsZero, a1IsZero), frontend.Variable(0)) @@ -139,12 +139,12 @@ func (p *GoldilocksApi) InverseExtension(a QuadraticExtensionVariable) Quadratic } // Divides two quadratic extension variables in the Goldilocks field. -func (p *GoldilocksApi) DivExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *Chip) DivExtension(a, b QuadraticExtensionVariable) QuadraticExtensionVariable { return p.MulExtension(a, p.InverseExtension(b)) } // Exponentiates a quadratic extension variable to some exponent in the Golidlocks field. -func (p *GoldilocksApi) ExpExtension( +func (p *Chip) ExpExtension( a QuadraticExtensionVariable, exponent uint64, ) QuadraticExtensionVariable { @@ -173,12 +173,12 @@ func (p *GoldilocksApi) ExpExtension( return product } -func (p *GoldilocksApi) ReduceExtension(x QuadraticExtensionVariable) QuadraticExtensionVariable { +func (p *Chip) ReduceExtension(x QuadraticExtensionVariable) QuadraticExtensionVariable { return NewQuadraticExtensionVariable(p.Reduce(x[0]), p.Reduce(x[1])) } // Reduces a list of extension field terms with a scalar power in the Goldilocks field. -func (p *GoldilocksApi) ReduceWithPowers( +func (p *Chip) ReduceWithPowers( terms []QuadraticExtensionVariable, scalar QuadraticExtensionVariable, ) QuadraticExtensionVariable { @@ -197,14 +197,14 @@ func (p *GoldilocksApi) ReduceWithPowers( } // Outputs whether the quadratic extension variable is zero. -func (p *GoldilocksApi) IsZero(x QuadraticExtensionVariable) frontend.Variable { +func (p *Chip) IsZero(x QuadraticExtensionVariable) frontend.Variable { x0IsZero := p.api.IsZero(x[0].Limb) x1IsZero := p.api.IsZero(x[1].Limb) return p.api.Mul(x0IsZero, x1IsZero) } // Lookup is similar to select, but returns the first variable if the bit is zero and vice-versa. -func (p *GoldilocksApi) Lookup( +func (p *Chip) Lookup( b frontend.Variable, x, y QuadraticExtensionVariable, ) QuadraticExtensionVariable { @@ -214,7 +214,7 @@ func (p *GoldilocksApi) Lookup( } // Lookup2 is similar to select2, but returns the first variable if the bit is zero and vice-versa. -func (p *GoldilocksApi) Lookup2( +func (p *Chip) Lookup2( b0 frontend.Variable, b1 frontend.Variable, qe0, qe1, qe2, qe3 QuadraticExtensionVariable, @@ -225,7 +225,7 @@ func (p *GoldilocksApi) Lookup2( } // Asserts that two quadratic extension variables are equal. -func (p *GoldilocksApi) AssertIsEqualExtension( +func (p *Chip) AssertIsEqualExtension( a QuadraticExtensionVariable, b QuadraticExtensionVariable, ) { @@ -233,7 +233,7 @@ func (p *GoldilocksApi) AssertIsEqualExtension( p.AssertIsEqual(a[1], b[1]) } -func (p *GoldilocksApi) RangeCheckQE(a QuadraticExtensionVariable) { +func (p *Chip) RangeCheckQE(a QuadraticExtensionVariable) { p.RangeCheck(a[0]) p.RangeCheck(a[1]) } diff --git a/goldilocks/quadratic_extension_algebra.go b/goldilocks/quadratic_extension_algebra.go index 668ed5f..9ce1028 100644 --- a/goldilocks/quadratic_extension_algebra.go +++ b/goldilocks/quadratic_extension_algebra.go @@ -25,7 +25,7 @@ func OneExtensionAlgebra() QuadraticExtensionAlgebraVariable { return OneExtension().ToQuadraticExtensionAlgebra() } -func (p *GoldilocksApi) AddExtensionAlgebra( +func (p *Chip) AddExtensionAlgebra( a QuadraticExtensionAlgebraVariable, b QuadraticExtensionAlgebraVariable, ) QuadraticExtensionAlgebraVariable { @@ -36,7 +36,7 @@ func (p *GoldilocksApi) AddExtensionAlgebra( return sum } -func (p *GoldilocksApi) SubExtensionAlgebra( +func (p *Chip) SubExtensionAlgebra( a QuadraticExtensionAlgebraVariable, b QuadraticExtensionAlgebraVariable, ) QuadraticExtensionAlgebraVariable { @@ -47,7 +47,7 @@ func (p *GoldilocksApi) SubExtensionAlgebra( return diff } -func (p GoldilocksApi) MulExtensionAlgebra( +func (p Chip) MulExtensionAlgebra( a QuadraticExtensionAlgebraVariable, b QuadraticExtensionAlgebraVariable, ) QuadraticExtensionAlgebraVariable { @@ -74,7 +74,7 @@ func (p GoldilocksApi) MulExtensionAlgebra( return product } -func (p *GoldilocksApi) ScalarMulExtensionAlgebra( +func (p *Chip) ScalarMulExtensionAlgebra( a QuadraticExtensionVariable, b QuadraticExtensionAlgebraVariable, ) QuadraticExtensionAlgebraVariable { @@ -85,7 +85,7 @@ func (p *GoldilocksApi) ScalarMulExtensionAlgebra( return product } -func (p *GoldilocksApi) PartialInterpolateExtAlgebra( +func (p *Chip) PartialInterpolateExtAlgebra( domain []goldilocks.Element, values []QuadraticExtensionAlgebraVariable, barycentricWeights []goldilocks.Element, diff --git a/goldilocks/quadratic_extension_test.go b/goldilocks/quadratic_extension_test.go index 1fbac49..9521daf 100644 --- a/goldilocks/quadratic_extension_test.go +++ b/goldilocks/quadratic_extension_test.go @@ -15,7 +15,7 @@ type TestQuadraticExtensionMulCircuit struct { } func (c *TestQuadraticExtensionMulCircuit) Define(api frontend.API) error { - glApi := NewGoldilocksApi(api) + glApi := New(api) actualRes := glApi.MulExtension(c.Operand1, c.Operand2) glApi.AssertIsEqual(actualRes[0], c.ExpectedResult[0]) glApi.AssertIsEqual(actualRes[1], c.ExpectedResult[1]) @@ -58,7 +58,7 @@ type TestQuadraticExtensionDivCircuit struct { } func (c *TestQuadraticExtensionDivCircuit) Define(api frontend.API) error { - glAPI := NewGoldilocksApi(api) + glAPI := New(api) actualRes := glAPI.DivExtension(c.Operand1, c.Operand2) glAPI.AssertIsEqual(actualRes[0], c.ExpectedResult[0]) glAPI.AssertIsEqual(actualRes[1], c.ExpectedResult[1]) diff --git a/plonk/gates/arithmetic_extension_gate.go b/plonk/gates/arithmetic_extension_gate.go index 91d4db1..e09ed2a 100644 --- a/plonk/gates/arithmetic_extension_gate.go +++ b/plonk/gates/arithmetic_extension_gate.go @@ -58,7 +58,7 @@ func (g *ArithmeticExtensionGate) wiresIthOutput(i uint64) Range { func (g *ArithmeticExtensionGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { const0 := vars.localConstants[0] diff --git a/plonk/gates/arithmetic_gate.go b/plonk/gates/arithmetic_gate.go index e7b78a7..7867cb0 100644 --- a/plonk/gates/arithmetic_gate.go +++ b/plonk/gates/arithmetic_gate.go @@ -59,7 +59,7 @@ func (g *ArithmeticGate) WireIthOutput(i uint64) uint64 { func (g *ArithmeticGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { const0 := vars.localConstants[0] diff --git a/plonk/gates/base_sum_gate.go b/plonk/gates/base_sum_gate.go index 543953c..aff6db6 100644 --- a/plonk/gates/base_sum_gate.go +++ b/plonk/gates/base_sum_gate.go @@ -65,7 +65,7 @@ func (g *BaseSumGate) limbs() []uint64 { func (g *BaseSumGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { sum := vars.localWires[BASESUM_GATE_WIRE_SUM] diff --git a/plonk/gates/constant_gate.go b/plonk/gates/constant_gate.go index 3771df0..e263139 100644 --- a/plonk/gates/constant_gate.go +++ b/plonk/gates/constant_gate.go @@ -56,7 +56,7 @@ func (g *ConstantGate) WireOutput(i uint64) uint64 { func (g *ConstantGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { constraints := []gl.QuadraticExtensionVariable{} diff --git a/plonk/gates/coset_interpolation_gate.go b/plonk/gates/coset_interpolation_gate.go index 1e08a13..58e53da 100644 --- a/plonk/gates/coset_interpolation_gate.go +++ b/plonk/gates/coset_interpolation_gate.go @@ -147,7 +147,7 @@ func (g *CosetInterpolationGate) wiresShiftedEvaluationPoint() Range { func (g *CosetInterpolationGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { constraints := []gl.QuadraticExtensionVariable{} diff --git a/plonk/gates/evaluate_gates.go b/plonk/gates/evaluate_gates.go index b123765..835eb6e 100644 --- a/plonk/gates/evaluate_gates.go +++ b/plonk/gates/evaluate_gates.go @@ -36,7 +36,7 @@ func (g *EvaluateGatesChip) computeFilter( s gl.QuadraticExtensionVariable, manySelector bool, ) gl.QuadraticExtensionVariable { - glApi := gl.NewGoldilocksApi(g.api) + glApi := gl.New(g.api) product := gl.OneExtension() for i := groupRange.start; i < groupRange.end; i++ { if i == uint64(row) { @@ -62,7 +62,7 @@ func (g *EvaluateGatesChip) evalFiltered( groupRange Range, numSelectors uint64, ) []gl.QuadraticExtensionVariable { - glApi := gl.NewGoldilocksApi(g.api) + glApi := gl.New(g.api) filter := g.computeFilter(row, groupRange, vars.localConstants[selectorIndex], numSelectors > 1) vars.RemovePrefix(numSelectors) @@ -75,7 +75,7 @@ func (g *EvaluateGatesChip) evalFiltered( } func (g *EvaluateGatesChip) EvaluateGateConstraints(vars EvaluationVars) []gl.QuadraticExtensionVariable { - glApi := gl.NewGoldilocksApi(g.api) + glApi := gl.New(g.api) constraints := make([]gl.QuadraticExtensionVariable, g.numGateConstraints) for i := range constraints { constraints[i] = gl.ZeroExtension() diff --git a/plonk/gates/exponentiation_gate.go b/plonk/gates/exponentiation_gate.go index 3d75301..ccf02e6 100644 --- a/plonk/gates/exponentiation_gate.go +++ b/plonk/gates/exponentiation_gate.go @@ -65,7 +65,7 @@ func (g *ExponentiationGate) wireIntermediateValue(i uint64) uint64 { func (g *ExponentiationGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { base := vars.localWires[g.wireBase()] diff --git a/plonk/gates/gates.go b/plonk/gates/gates.go index b46e82d..edd98d4 100644 --- a/plonk/gates/gates.go +++ b/plonk/gates/gates.go @@ -12,7 +12,7 @@ type Gate interface { Id() string EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable } diff --git a/plonk/gates/gates_test.go b/plonk/gates/gates_test.go index 91b4a37..3409e46 100644 --- a/plonk/gates/gates_test.go +++ b/plonk/gates/gates_test.go @@ -693,7 +693,7 @@ func (circuit *TestGateCircuit) Define(api frontend.API) error { commonCircuitData := verifier.DeserializeCommonCircuitData("../../data/decode_block/common_circuit_data.json") numSelectors := commonCircuitData.SelectorsInfo.NumSelectors() - glApi := gl.NewGoldilocksApi(api) + glApi := gl.New(api) vars := gates.NewEvaluationVars(localConstants[numSelectors:], localWires, publicInputsHash) diff --git a/plonk/gates/multiplication_extension_gate.go b/plonk/gates/multiplication_extension_gate.go index ce17821..37cec16 100644 --- a/plonk/gates/multiplication_extension_gate.go +++ b/plonk/gates/multiplication_extension_gate.go @@ -54,7 +54,7 @@ func (g *MultiplicationExtensionGate) wiresIthOutput(i uint64) Range { func (g *MultiplicationExtensionGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { const0 := vars.localConstants[0] diff --git a/plonk/gates/noop_gate.go b/plonk/gates/noop_gate.go index 9b24291..f7c67e0 100644 --- a/plonk/gates/noop_gate.go +++ b/plonk/gates/noop_gate.go @@ -27,7 +27,7 @@ func (g *NoopGate) Id() string { func (g *NoopGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { return []gl.QuadraticExtensionVariable{} diff --git a/plonk/gates/poseidon_gate.go b/plonk/gates/poseidon_gate.go index be31caa..4576b2f 100644 --- a/plonk/gates/poseidon_gate.go +++ b/plonk/gates/poseidon_gate.go @@ -91,7 +91,7 @@ func (g *PoseidonGate) WiresEnd() uint64 { func (g *PoseidonGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { constraints := []gl.QuadraticExtensionVariable{} diff --git a/plonk/gates/poseidon_mds_gate.go b/plonk/gates/poseidon_mds_gate.go index f59ebb9..f03319d 100644 --- a/plonk/gates/poseidon_mds_gate.go +++ b/plonk/gates/poseidon_mds_gate.go @@ -45,7 +45,7 @@ func (g *PoseidonMdsGate) mdsRowShfAlgebra( v [poseidon.SPONGE_WIDTH]gl.QuadraticExtensionAlgebraVariable, api frontend.API, ) gl.QuadraticExtensionAlgebraVariable { - glApi := gl.NewGoldilocksApi(api) + glApi := gl.New(api) if r >= poseidon.SPONGE_WIDTH { panic("MDS row index out of range") } @@ -75,7 +75,7 @@ func (g *PoseidonMdsGate) mdsLayerAlgebra( func (g *PoseidonMdsGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { constraints := []gl.QuadraticExtensionVariable{} diff --git a/plonk/gates/public_input_gate.go b/plonk/gates/public_input_gate.go index f417217..9fad5e7 100644 --- a/plonk/gates/public_input_gate.go +++ b/plonk/gates/public_input_gate.go @@ -31,7 +31,7 @@ func (g *PublicInputGate) WiresPublicInputsHash() []uint64 { func (g *PublicInputGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { constraints := []gl.QuadraticExtensionVariable{} diff --git a/plonk/gates/random_access_gate.go b/plonk/gates/random_access_gate.go index 82e30e9..5d1e0a8 100644 --- a/plonk/gates/random_access_gate.go +++ b/plonk/gates/random_access_gate.go @@ -116,7 +116,7 @@ func (g *RandomAccessGate) WireBit(i uint64, copy uint64) uint64 { func (g *RandomAccessGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { two := gl.NewVariable(2).ToQuadraticExtension() diff --git a/plonk/gates/reducing_extension_gate.go b/plonk/gates/reducing_extension_gate.go index c75a810..2d71c07 100644 --- a/plonk/gates/reducing_extension_gate.go +++ b/plonk/gates/reducing_extension_gate.go @@ -76,7 +76,7 @@ func (g *ReducingExtensionGate) wiresAccs(i uint64) Range { func (g *ReducingExtensionGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { alpha := vars.GetLocalExtAlgebra(g.wiresAlpha()) diff --git a/plonk/gates/reducing_gate.go b/plonk/gates/reducing_gate.go index 2261c2f..2212f2b 100644 --- a/plonk/gates/reducing_gate.go +++ b/plonk/gates/reducing_gate.go @@ -76,7 +76,7 @@ func (g *ReducingGate) wiresAccs(i uint64) Range { func (g *ReducingGate) EvalUnfiltered( api frontend.API, - glApi gl.GoldilocksApi, + glApi gl.Chip, vars EvaluationVars, ) []gl.QuadraticExtensionVariable { alpha := vars.GetLocalExtAlgebra(g.wiresAlpha()) diff --git a/plonk/plonk.go b/plonk/plonk.go index 26e7b97..b94a3d4 100644 --- a/plonk/plonk.go +++ b/plonk/plonk.go @@ -5,13 +5,13 @@ import ( gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" - "github.com/succinctlabs/gnark-plonky2-verifier/types" + "github.com/succinctlabs/gnark-plonky2-verifier/variables" ) type PlonkChip struct { api frontend.API `gnark:"-"` - commonData types.CommonCircuitData `gnark:"-"` + commonData variables.CommonCircuitData `gnark:"-"` DEGREE gl.Variable `gnark:"-"` DEGREE_BITS_F gl.Variable `gnark:"-"` @@ -20,7 +20,7 @@ type PlonkChip struct { evaluateGatesChip *gates.EvaluateGatesChip } -func NewPlonkChip(api frontend.API, commonData types.CommonCircuitData) *PlonkChip { +func NewPlonkChip(api frontend.API, commonData variables.CommonCircuitData) *PlonkChip { // TODO: Should degreeBits be verified that it fits within the field and that degree is within uint64? evaluateGatesChip := gates.NewEvaluateGatesChip( @@ -44,7 +44,7 @@ func NewPlonkChip(api frontend.API, commonData types.CommonCircuitData) *PlonkCh } func (p *PlonkChip) expPowerOf2Extension(x gl.QuadraticExtensionVariable) gl.QuadraticExtensionVariable { - glApi := gl.NewGoldilocksApi(p.api) + glApi := gl.New(p.api) for i := uint64(0); i < p.commonData.DegreeBits; i++ { x = glApi.MulExtension(x, x) } @@ -53,7 +53,7 @@ func (p *PlonkChip) expPowerOf2Extension(x gl.QuadraticExtensionVariable) gl.Qua func (p *PlonkChip) evalL0(x gl.QuadraticExtensionVariable, xPowN gl.QuadraticExtensionVariable) gl.QuadraticExtensionVariable { // L_0(x) = (x^n - 1) / (n * (x - 1)) - glApi := gl.NewGoldilocksApi(p.api) + glApi := gl.New(p.api) evalZeroPoly := glApi.SubExtension( xPowN, gl.OneExtension(), @@ -72,9 +72,9 @@ func (p *PlonkChip) checkPartialProducts( numerators []gl.QuadraticExtensionVariable, denominators []gl.QuadraticExtensionVariable, challengeNum uint64, - openings types.OpeningSet, + openings variables.OpeningSet, ) []gl.QuadraticExtensionVariable { - glApi := gl.NewGoldilocksApi(p.api) + glApi := gl.New(p.api) numPartProds := p.commonData.NumPartialProducts quotDegreeFactor := p.commonData.QuotientDegreeFactor @@ -106,11 +106,11 @@ func (p *PlonkChip) checkPartialProducts( func (p *PlonkChip) evalVanishingPoly( vars gates.EvaluationVars, - proofChallenges types.ProofChallenges, - openings types.OpeningSet, + proofChallenges variables.ProofChallenges, + openings variables.OpeningSet, zetaPowN gl.QuadraticExtensionVariable, ) []gl.QuadraticExtensionVariable { - glApi := gl.NewGoldilocksApi(p.api) + glApi := gl.New(p.api) constraintTerms := p.evaluateGatesChip.EvaluateGateConstraints(vars) // Calculate the k[i] * x @@ -193,11 +193,11 @@ func (p *PlonkChip) evalVanishingPoly( } func (p *PlonkChip) Verify( - proofChallenges types.ProofChallenges, - openings types.OpeningSet, + proofChallenges variables.ProofChallenges, + openings variables.OpeningSet, publicInputsHash poseidon.GoldilocksHashOut, ) { - glApi := gl.NewGoldilocksApi(p.api) + glApi := gl.New(p.api) // Calculate zeta^n zetaPowN := p.expPowerOf2Extension(proofChallenges.PlonkZeta) diff --git a/poseidon/bn254.go b/poseidon/bn254.go index ff54d3d..48e4a21 100644 --- a/poseidon/bn254.go +++ b/poseidon/bn254.go @@ -20,15 +20,15 @@ const BN254_SPONGE_WIDTH int = 4 const BN254_SPONGE_RATE int = 3 type BN254Chip struct { - api frontend.API `gnark:"-"` - gl gl.GoldilocksApi `gnark:"-"` + api frontend.API `gnark:"-"` + gl gl.Chip `gnark:"-"` } type BN254State = [BN254_SPONGE_WIDTH]frontend.Variable type BN254HashOut = frontend.Variable func NewBN254Chip(api frontend.API) *BN254Chip { - return &BN254Chip{api: api, gl: *gl.NewGoldilocksApi(api)} + return &BN254Chip{api: api, gl: *gl.New(api)} } func (c *BN254Chip) Poseidon(state BN254State) BN254State { diff --git a/poseidon/goldilocks.go b/poseidon/goldilocks.go index 1764deb..7fd6c34 100644 --- a/poseidon/goldilocks.go +++ b/poseidon/goldilocks.go @@ -16,12 +16,12 @@ type GoldilocksStateExtension = [SPONGE_WIDTH]gl.QuadraticExtensionVariable type GoldilocksHashOut = [4]gl.Variable type GoldilocksChip struct { - api frontend.API `gnark:"-"` - gl gl.GoldilocksApi `gnark:"-"` + api frontend.API `gnark:"-"` + gl gl.Chip `gnark:"-"` } func NewGoldilocksChip(api frontend.API) *GoldilocksChip { - return &GoldilocksChip{api: api, gl: *gl.NewGoldilocksApi(api)} + return &GoldilocksChip{api: api, gl: *gl.New(api)} } // The permutation function. diff --git a/poseidon/goldilocks_test.go b/poseidon/goldilocks_test.go index 981aee3..bad7aa4 100644 --- a/poseidon/goldilocks_test.go +++ b/poseidon/goldilocks_test.go @@ -25,7 +25,7 @@ func (circuit *TestPoseidonCircuit) Define(api frontend.API) error { poseidonChip := NewGoldilocksChip(api) output := poseidonChip.Poseidon(input) - glApi := gl.NewGoldilocksApi(api) + glApi := gl.New(api) for i := 0; i < 12; i++ { glApi.AssertIsEqual(output[i], gl.NewVariable(circuit.Out[i])) diff --git a/poseidon/public_inputs_hash_test.go b/poseidon/public_inputs_hash_test.go index bd510bb..2939c6d 100644 --- a/poseidon/public_inputs_hash_test.go +++ b/poseidon/public_inputs_hash_test.go @@ -18,7 +18,7 @@ type TestPublicInputsHashCircuit struct { } func (circuit *TestPublicInputsHashCircuit) Define(api frontend.API) error { - glAPI := gl.NewGoldilocksApi(api) + glAPI := gl.New(api) // BN254 -> Binary(64) -> F var input [3]gl.Variable diff --git a/types/circuit.go b/variables/circuit.go similarity index 98% rename from types/circuit.go rename to variables/circuit.go index 9e46d30..81ee9bd 100644 --- a/types/circuit.go +++ b/variables/circuit.go @@ -1,4 +1,4 @@ -package types +package variables import ( gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" diff --git a/types/fri.go b/variables/fri.go similarity index 99% rename from types/fri.go rename to variables/fri.go index aaea0f3..fdcecfc 100644 --- a/types/fri.go +++ b/variables/fri.go @@ -1,4 +1,4 @@ -package types +package variables import ( gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" diff --git a/types/plonk.go b/variables/plonk.go similarity index 98% rename from types/plonk.go rename to variables/plonk.go index f0b03b9..1fc30f7 100644 --- a/types/plonk.go +++ b/variables/plonk.go @@ -1,4 +1,4 @@ -package types +package variables import gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" diff --git a/verifier/deserialize.go b/verifier/deserialize.go index ac52565..3498ad5 100644 --- a/verifier/deserialize.go +++ b/verifier/deserialize.go @@ -10,7 +10,7 @@ import ( gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" - "github.com/succinctlabs/gnark-plonky2-verifier/types" + "github.com/succinctlabs/gnark-plonky2-verifier/variables" ) type ProofWithPublicInputsRaw struct { @@ -146,7 +146,7 @@ type VerifierOnlyCircuitDataRaw struct { CircuitDigest string `json:"circuit_digest"` } -func DeserializeMerkleCap(merkleCapRaw []string) types.FriMerkleCap { +func DeserializeMerkleCap(merkleCapRaw []string) variables.FriMerkleCap { n := len(merkleCapRaw) merkleCap := make([]poseidon.BN254HashOut, n) for i := 0; i < n; i++ { @@ -156,9 +156,9 @@ func DeserializeMerkleCap(merkleCapRaw []string) types.FriMerkleCap { return merkleCap } -func DeserializeMerkleProof(merkleProofRaw struct{ Siblings []interface{} }) types.FriMerkleProof { +func DeserializeMerkleProof(merkleProofRaw struct{ Siblings []interface{} }) variables.FriMerkleProof { n := len(merkleProofRaw.Siblings) - var mp types.FriMerkleProof + var mp variables.FriMerkleProof mp.Siblings = make([]poseidon.BN254HashOut, n) for i := 0; i < n; i++ { element := merkleProofRaw.Siblings[i].(struct{ Elements []uint64 }) @@ -175,8 +175,8 @@ func DeserializeOpeningSet(openingSetRaw struct { PlonkZsNext [][]uint64 PartialProducts [][]uint64 QuotientPolys [][]uint64 -}) types.OpeningSet { - return types.OpeningSet{ +}) variables.OpeningSet { + return variables.OpeningSet{ Constants: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Constants), PlonkSigmas: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkSigmas), Wires: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Wires), @@ -216,29 +216,29 @@ func DeserializeFriProof(openingProofRaw struct { Coeffs [][]uint64 } PowWitness uint64 -}) types.FriProof { - var openingProof types.FriProof +}) variables.FriProof { + var openingProof variables.FriProof openingProof.PowWitness = gl.NewVariable(openingProofRaw.PowWitness) openingProof.FinalPoly.Coeffs = gl.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs) - openingProof.CommitPhaseMerkleCaps = make([]types.FriMerkleCap, len(openingProofRaw.CommitPhaseMerkleCaps)) + openingProof.CommitPhaseMerkleCaps = make([]variables.FriMerkleCap, len(openingProofRaw.CommitPhaseMerkleCaps)) for i := 0; i < len(openingProofRaw.CommitPhaseMerkleCaps); i++ { openingProof.CommitPhaseMerkleCaps[i] = StringArrayToHashBN254Array(openingProofRaw.CommitPhaseMerkleCaps[i]) } numQueryRoundProofs := len(openingProofRaw.QueryRoundProofs) - openingProof.QueryRoundProofs = make([]types.FriQueryRound, numQueryRoundProofs) + openingProof.QueryRoundProofs = make([]variables.FriQueryRound, numQueryRoundProofs) for i := 0; i < numQueryRoundProofs; i++ { numEvalProofs := len(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs) - openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs = make([]types.FriEvalProof, numEvalProofs) + openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs = make([]variables.FriEvalProof, numEvalProofs) for j := 0; j < numEvalProofs; j++ { openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].Elements = gl.Uint64ArrayToVariableArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].LeafElements) openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Siblings = StringArrayToHashBN254Array(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Hash) } numSteps := len(openingProofRaw.QueryRoundProofs[i].Steps) - openingProof.QueryRoundProofs[i].Steps = make([]types.FriQueryStep, numSteps) + openingProof.QueryRoundProofs[i].Steps = make([]variables.FriQueryStep, numSteps) for j := 0; j < numSteps; j++ { openingProof.QueryRoundProofs[i].Steps[j].Evals = gl.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.QueryRoundProofs[i].Steps[j].Evals) openingProof.QueryRoundProofs[i].Steps[j].MerkleProof.Siblings = StringArrayToHashBN254Array(openingProofRaw.QueryRoundProofs[i].Steps[j].MerkleProof.Siblings) @@ -248,7 +248,7 @@ func DeserializeFriProof(openingProofRaw struct { return openingProof } -func DeserializeProofWithPublicInputs(path string) types.ProofWithPublicInputs { +func DeserializeProofWithPublicInputs(path string) variables.ProofWithPublicInputs { jsonFile, err := os.Open(path) if err != nil { panic(err) @@ -263,7 +263,7 @@ func DeserializeProofWithPublicInputs(path string) types.ProofWithPublicInputs { panic(err) } - var proofWithPis types.ProofWithPublicInputs + var proofWithPis variables.ProofWithPublicInputs proofWithPis.Proof.WiresCap = DeserializeMerkleCap(raw.Proof.WiresCap) proofWithPis.Proof.PlonkZsPartialProductsCap = DeserializeMerkleCap(raw.Proof.PlonkZsPartialProductsCap) proofWithPis.Proof.QuotientPolysCap = DeserializeMerkleCap(raw.Proof.QuotientPolysCap) @@ -297,7 +297,7 @@ func DeserializeProofWithPublicInputs(path string) types.ProofWithPublicInputs { return proofWithPis } -func DeserializeProofChallenges(path string) types.ProofChallenges { +func DeserializeProofChallenges(path string) variables.ProofChallenges { jsonFile, err := os.Open(path) if err != nil { panic(err) @@ -312,7 +312,7 @@ func DeserializeProofChallenges(path string) types.ProofChallenges { panic(err) } - var proofChallenges types.ProofChallenges + var proofChallenges variables.ProofChallenges proofChallenges.PlonkBetas = gl.Uint64ArrayToVariableArray(raw.PlonkBetas) proofChallenges.PlonkGammas = gl.Uint64ArrayToVariableArray(raw.PlonkGammas) proofChallenges.PlonkAlphas = gl.Uint64ArrayToVariableArray(raw.PlonkAlphas) @@ -345,7 +345,7 @@ func ReductionArityBits( return returnArr } -func DeserializeCommonCircuitData(path string) types.CommonCircuitData { +func DeserializeCommonCircuitData(path string) variables.CommonCircuitData { jsonFile, err := os.Open(path) if err != nil { panic(err) @@ -360,7 +360,7 @@ func DeserializeCommonCircuitData(path string) types.CommonCircuitData { panic(err) } - var commonCircuitData types.CommonCircuitData + var commonCircuitData variables.CommonCircuitData commonCircuitData.Config.NumWires = raw.Config.NumWires commonCircuitData.Config.NumRoutedWires = raw.Config.NumRoutedWires commonCircuitData.Config.NumConstants = raw.Config.NumConstants @@ -411,7 +411,7 @@ func DeserializeCommonCircuitData(path string) types.CommonCircuitData { return commonCircuitData } -func DeserializeVerifierOnlyCircuitData(path string) types.VerifierOnlyCircuitData { +func DeserializeVerifierOnlyCircuitData(path string) variables.VerifierOnlyCircuitData { jsonFile, err := os.Open(path) if err != nil { panic(err) @@ -426,7 +426,7 @@ func DeserializeVerifierOnlyCircuitData(path string) types.VerifierOnlyCircuitDa panic(err) } - var verifierOnlyCircuitData types.VerifierOnlyCircuitData + var verifierOnlyCircuitData variables.VerifierOnlyCircuitData verifierOnlyCircuitData.ConstantSigmasCap = DeserializeMerkleCap(raw.ConstantsSigmasCap) circuitDigestBigInt, _ := new(big.Int).SetString(raw.CircuitDigest, 10) circuitDigestVar := frontend.Variable(circuitDigestBigInt) diff --git a/verifier/verifier.go b/verifier/verifier.go index a5bd262..bfa69d9 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -7,20 +7,20 @@ import ( gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/plonk" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" - "github.com/succinctlabs/gnark-plonky2-verifier/types" + "github.com/succinctlabs/gnark-plonky2-verifier/variables" ) type VerifierChip struct { api frontend.API `gnark:"-"` - glChip *gl.GoldilocksApi `gnark:"-"` + glChip *gl.Chip `gnark:"-"` poseidonGlChip *poseidon.GoldilocksChip `gnark:"-"` poseidonBN254Chip *poseidon.BN254Chip `gnark:"-"` plonkChip *plonk.PlonkChip `gnark:"-"` friChip *fri.Chip `gnark:"-"` } -func NewVerifierChip(api frontend.API, commonCircuitData types.CommonCircuitData) *VerifierChip { - glChip := gl.NewGoldilocksApi(api) +func NewVerifierChip(api frontend.API, commonCircuitData variables.CommonCircuitData) *VerifierChip { + glChip := gl.New(api) friChip := fri.NewChip(api, &commonCircuitData.FriParams) plonkChip := plonk.NewPlonkChip(api, commonCircuitData) poseidonGlChip := poseidon.NewGoldilocksChip(api) @@ -40,11 +40,11 @@ func (c *VerifierChip) GetPublicInputsHash(publicInputs []gl.Variable) poseidon. } func (c *VerifierChip) GetChallenges( - proof types.Proof, + proof variables.Proof, publicInputsHash poseidon.GoldilocksHashOut, - commonData types.CommonCircuitData, - verifierData types.VerifierOnlyCircuitData, -) types.ProofChallenges { + commonData variables.CommonCircuitData, + verifierData variables.VerifierOnlyCircuitData, +) variables.ProofChallenges { config := commonData.Config numChallenges := config.NumChallenges challenger := challenger.NewChip(c.api) @@ -65,7 +65,7 @@ func (c *VerifierChip) GetChallenges( challenger.ObserveOpenings(fri.ToOpenings(proof.Openings)) - return types.ProofChallenges{ + return variables.ProofChallenges{ PlonkBetas: plonkBetas, PlonkGammas: plonkGammas, PlonkAlphas: plonkAlphas, @@ -147,7 +147,7 @@ func (c *VerifierChip) generateProofInput(commonData common.CommonCircuitData) c } */ -func (c *VerifierChip) rangeCheckProof(proof types.Proof) { +func (c *VerifierChip) rangeCheckProof(proof variables.Proof) { // Need to verify the plonky2 proof's openings, openings proof (other than the sibling elements), fri's final poly, pow witness. // Note that this is NOT range checking the public inputs (first 32 elements should be no more than 8 bits and the last 4 elements should be no more than 64 bits). Since this is currently being inputted via the smart contract, @@ -205,10 +205,10 @@ func (c *VerifierChip) rangeCheckProof(proof types.Proof) { } func (c *VerifierChip) Verify( - proof types.Proof, + proof variables.Proof, publicInputs []gl.Variable, - verifierData types.VerifierOnlyCircuitData, - commonData types.CommonCircuitData, + verifierData variables.VerifierOnlyCircuitData, + commonData variables.CommonCircuitData, ) { c.rangeCheckProof(proof) @@ -218,7 +218,7 @@ func (c *VerifierChip) Verify( c.plonkChip.Verify(proofChallenges, proof.Openings, publicInputsHash) - initialMerkleCaps := []types.FriMerkleCap{ + initialMerkleCaps := []variables.FriMerkleCap{ verifierData.ConstantSigmasCap, proof.WiresCap, proof.PlonkZsPartialProductsCap, diff --git a/verifier/verifier_test.go b/verifier/verifier_test.go index e9cd2d5..aa3ac11 100644 --- a/verifier/verifier_test.go +++ b/verifier/verifier_test.go @@ -9,12 +9,12 @@ import ( "github.com/consensys/gnark/std/math/emulated" "github.com/consensys/gnark/test" gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" - "github.com/succinctlabs/gnark-plonky2-verifier/types" + "github.com/succinctlabs/gnark-plonky2-verifier/variables" "github.com/succinctlabs/gnark-plonky2-verifier/verifier" ) type TestVerifierCircuit struct { - Proof types.Proof + Proof variables.Proof PublicInputs []gl.Variable `gnark:",public"` verifierChip *verifier.VerifierChip `gnark:"-"` From b173b28649a5bb7d026246f6005b23dc66fd68b6 Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Wed, 11 Oct 2023 12:20:48 -0700 Subject: [PATCH 08/13] checkpoint --- challenger/challenger.go | 3 +- fri/fri.go | 7 +-- plonk/gates/{selectors.go => types.go} | 0 types/types.go | 20 ++++++++ variables/circuit.go | 5 +- variables/fri.go | 19 -------- verifier/deserialize.go | 55 ++++++++++----------- verifier/verifier.go | 67 -------------------------- 8 files changed, 57 insertions(+), 119 deletions(-) rename plonk/gates/{selectors.go => types.go} (100%) create mode 100644 types/types.go diff --git a/challenger/challenger.go b/challenger/challenger.go index 91e656d..b61f2a5 100644 --- a/challenger/challenger.go +++ b/challenger/challenger.go @@ -7,6 +7,7 @@ import ( "github.com/succinctlabs/gnark-plonky2-verifier/fri" gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" + "github.com/succinctlabs/gnark-plonky2-verifier/types" "github.com/succinctlabs/gnark-plonky2-verifier/variables" ) @@ -117,7 +118,7 @@ func (c *Chip) GetFriChallenges( finalPoly variables.PolynomialCoeffs, powWitness gl.Variable, degreeBits uint64, - config variables.FriConfig, + config types.FriConfig, ) variables.FriChallenges { numFriQueries := config.NumQueryRounds friAlpha := c.GetExtensionChallenge() diff --git a/fri/fri.go b/fri/fri.go index 86aedfa..9483ace 100644 --- a/fri/fri.go +++ b/fri/fri.go @@ -10,6 +10,7 @@ import ( "github.com/consensys/gnark/frontend" gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" + "github.com/succinctlabs/gnark-plonky2-verifier/types" "github.com/succinctlabs/gnark-plonky2-verifier/variables" ) @@ -17,12 +18,12 @@ type Chip struct { api frontend.API `gnark:"-"` gl gl.Chip `gnark:"-"` poseidonBN254Chip *poseidon.BN254Chip - friParams *variables.FriParams `gnark:"-"` + friParams *types.FriParams `gnark:"-"` } func NewChip( api frontend.API, - friParams *variables.FriParams, + friParams *types.FriParams, ) *Chip { poseidonBN254Chip := poseidon.NewBN254Chip(api) return &Chip{ @@ -33,7 +34,7 @@ func NewChip( } } -func (f *Chip) assertLeadingZeros(powWitness gl.Variable, friConfig variables.FriConfig) { +func (f *Chip) assertLeadingZeros(powWitness gl.Variable, friConfig types.FriConfig) { // Asserts that powWitness'es big-endian bit representation has at least `leading_zeros` leading zeros. // Note that this is assuming that the Goldilocks field is being used. Specfically that the // field is 64 bits long diff --git a/plonk/gates/selectors.go b/plonk/gates/types.go similarity index 100% rename from plonk/gates/selectors.go rename to plonk/gates/types.go diff --git a/types/types.go b/types/types.go new file mode 100644 index 0000000..c9b744f --- /dev/null +++ b/types/types.go @@ -0,0 +1,20 @@ +package types + +type FriConfig struct { + RateBits uint64 + CapHeight uint64 + ProofOfWorkBits uint64 + NumQueryRounds uint64 + // TODO: add FriReductionStrategy +} + +func (fc *FriConfig) Rate() float64 { + return 1.0 / float64((uint64(1) << fc.RateBits)) +} + +type FriParams struct { + Config FriConfig + Hiding bool + DegreeBits uint64 + ReductionArityBits []uint64 +} diff --git a/variables/circuit.go b/variables/circuit.go index 81ee9bd..fe73b22 100644 --- a/variables/circuit.go +++ b/variables/circuit.go @@ -4,6 +4,7 @@ import ( gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" + "github.com/succinctlabs/gnark-plonky2-verifier/types" ) type Proof struct { @@ -33,12 +34,12 @@ type CircuitConfig struct { NumChallenges uint64 ZeroKnowledge bool MaxQuotientDegreeFactor uint64 - FriConfig FriConfig + FriConfig types.FriConfig } type CommonCircuitData struct { Config CircuitConfig - FriParams FriParams + FriParams types.FriParams Gates []gates.Gate SelectorsInfo gates.SelectorsInfo DegreeBits uint64 diff --git a/variables/fri.go b/variables/fri.go index fdcecfc..3042a87 100644 --- a/variables/fri.go +++ b/variables/fri.go @@ -13,25 +13,6 @@ func NewPolynomialCoeffs(numCoeffs uint64) PolynomialCoeffs { return PolynomialCoeffs{Coeffs: make([]gl.QuadraticExtensionVariable, numCoeffs)} } -type FriConfig struct { - RateBits uint64 - CapHeight uint64 - ProofOfWorkBits uint64 - NumQueryRounds uint64 - // TODO: add FriReductionStrategy -} - -func (fc *FriConfig) Rate() float64 { - return 1.0 / float64((uint64(1) << fc.RateBits)) -} - -type FriParams struct { - Config FriConfig - Hiding bool - DegreeBits uint64 - ReductionArityBits []uint64 -} - type FriMerkleCap = []poseidon.BN254HashOut func NewFriMerkleCap(capHeight uint64) FriMerkleCap { diff --git a/verifier/deserialize.go b/verifier/deserialize.go index 3498ad5..7bdd8d2 100644 --- a/verifier/deserialize.go +++ b/verifier/deserialize.go @@ -297,33 +297,34 @@ func DeserializeProofWithPublicInputs(path string) variables.ProofWithPublicInpu return proofWithPis } -func DeserializeProofChallenges(path string) variables.ProofChallenges { - jsonFile, err := os.Open(path) - if err != nil { - panic(err) - } - - defer jsonFile.Close() - rawBytes, _ := io.ReadAll(jsonFile) - - var raw ProofChallengesRaw - err = json.Unmarshal(rawBytes, &raw) - if err != nil { - panic(err) - } - - var proofChallenges variables.ProofChallenges - proofChallenges.PlonkBetas = gl.Uint64ArrayToVariableArray(raw.PlonkBetas) - proofChallenges.PlonkGammas = gl.Uint64ArrayToVariableArray(raw.PlonkGammas) - proofChallenges.PlonkAlphas = gl.Uint64ArrayToVariableArray(raw.PlonkAlphas) - proofChallenges.PlonkZeta = gl.Uint64ArrayToQuadraticExtension(raw.PlonkZeta) - proofChallenges.FriChallenges.FriAlpha = gl.Uint64ArrayToQuadraticExtension(raw.FriChallenges.FriAlpha) - proofChallenges.FriChallenges.FriBetas = gl.Uint64ArrayToQuadraticExtensionArray(raw.FriChallenges.FriBetas) - proofChallenges.FriChallenges.FriPowResponse = gl.NewVariable(raw.FriChallenges.FriPowResponse) - proofChallenges.FriChallenges.FriQueryIndices = gl.Uint64ArrayToVariableArray(raw.FriChallenges.FriQueryIndices) - - return proofChallenges -} +// TODO: this seemed unused? +// func DeserializeProofChallenges(path string) variables.ProofChallenges { +// jsonFile, err := os.Open(path) +// if err != nil { +// panic(err) +// } + +// defer jsonFile.Close() +// rawBytes, _ := io.ReadAll(jsonFile) + +// var raw ProofChallengesRaw +// err = json.Unmarshal(rawBytes, &raw) +// if err != nil { +// panic(err) +// } + +// var proofChallenges variables.ProofChallenges +// proofChallenges.PlonkBetas = gl.Uint64ArrayToVariableArray(raw.PlonkBetas) +// proofChallenges.PlonkGammas = gl.Uint64ArrayToVariableArray(raw.PlonkGammas) +// proofChallenges.PlonkAlphas = gl.Uint64ArrayToVariableArray(raw.PlonkAlphas) +// proofChallenges.PlonkZeta = gl.Uint64ArrayToQuadraticExtension(raw.PlonkZeta) +// proofChallenges.FriChallenges.FriAlpha = gl.Uint64ArrayToQuadraticExtension(raw.FriChallenges.FriAlpha) +// proofChallenges.FriChallenges.FriBetas = gl.Uint64ArrayToQuadraticExtensionArray(raw.FriChallenges.FriBetas) +// proofChallenges.FriChallenges.FriPowResponse = gl.NewVariable(raw.FriChallenges.FriPowResponse) +// proofChallenges.FriChallenges.FriQueryIndices = gl.Uint64ArrayToVariableArray(raw.FriChallenges.FriQueryIndices) + +// return proofChallenges +// } func ReductionArityBits( arityBits uint64, diff --git a/verifier/verifier.go b/verifier/verifier.go index bfa69d9..0ff36ba 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -80,73 +80,6 @@ func (c *VerifierChip) GetChallenges( } } -/* -func (c *VerifierChip) generateProofInput(commonData common.CommonCircuitData) common.ProofWithPublicInputs { - // Generate the parts of the witness that is for the plonky2 proof input - - capHeight := commonData.Config.FriConfig.CapHeight - - friCommitPhaseMerkleCaps := []common.MerkleCap{} - for i := 0; i < len(commonData.FriParams.ReductionArityBits); i++ { - friCommitPhaseMerkleCaps = append(friCommitPhaseMerkleCaps, common.NewMerkleCap(capHeight)) - } - - salt := commonData.SaltSize() - numLeavesPerOracle := []uint{ - commonData.NumPreprocessedPolys(), - commonData.Config.NumWires + salt, - commonData.NumZsPartialProductsPolys() + salt, - commonData.NumQuotientPolys() + salt, - } - friQueryRoundProofs := []common.FriQueryRound{} - for i := uint64(0); i < commonData.FriParams.Config.NumQueryRounds; i++ { - evalProofs := []common.EvalProof{} - merkleProofLen := commonData.FriParams.LDEBits() - capHeight - for _, numLeaves := range numLeavesPerOracle { - leaves := make([]field.F, numLeaves) - merkleProof := common.NewMerkleProof(merkleProofLen) - evalProofs = append(evalProofs, common.NewEvalProof(leaves, merkleProof)) - } - - initialTreesProof := common.NewFriInitialTreeProof(evalProofs) - steps := []common.FriQueryStep{} - for _, arityBit := range commonData.FriParams.ReductionArityBits { - if merkleProofLen < arityBit { - panic("merkleProofLen < arityBits") - } - - steps = append(steps, common.NewFriQueryStep(arityBit, merkleProofLen)) - } - - friQueryRoundProofs = append(friQueryRoundProofs, common.NewFriQueryRound(steps, initialTreesProof)) - } - - proofInput := common.ProofWithPublicInputs{ - Proof: common.Proof{ - WiresCap: common.NewMerkleCap(capHeight), - PlonkZsPartialProductsCap: common.NewMerkleCap(capHeight), - QuotientPolysCap: common.NewMerkleCap(capHeight), - Openings: common.NewOpeningSet( - commonData.Config.NumConstants, - commonData.Config.NumRoutedWires, - commonData.Config.NumWires, - commonData.Config.NumChallenges, - commonData.NumPartialProducts, - commonData.QuotientDegreeFactor, - ), - OpeningProof: common.FriProof{ - CommitPhaseMerkleCaps: friCommitPhaseMerkleCaps, - QueryRoundProofs: friQueryRoundProofs, - FinalPoly: common.NewPolynomialCoeffs(commonData.FriParams.FinalPolyLen()), - }, - }, - PublicInputs: make([]field.F, commonData.NumPublicInputs), - } - - return proofInput -} -*/ - func (c *VerifierChip) rangeCheckProof(proof variables.Proof) { // Need to verify the plonky2 proof's openings, openings proof (other than the sibling elements), fri's final poly, pow witness. From 3aef7954ed2bbe2edf245bb5988fa308a906e4c9 Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Wed, 11 Oct 2023 14:53:34 -0700 Subject: [PATCH 09/13] All tests pass --- .gitignore | 1 + README.md | 4 +- benchmark.go | 215 ++++++--- benchmark_plonk.go | 187 -------- fri/fri.go | 38 ++ fri/fri_test.go | 42 +- fri/fri_utils.go | 80 +--- fri/vars.go | 21 + plonk/gates/gates_test.go | 4 +- plonk/plonk.go | 19 +- plonk/plonk_test.go | 36 +- {verifier/data => testdata}/.DS_Store | Bin .../decode_block/common_circuit_data.json | 0 .../proof_with_public_inputs.json | 0 .../verifier_only_circuit_data.json | 0 .../step/common_circuit_data.json | 0 .../step/proof_with_public_inputs.json | 0 .../step/verifier_only_circuit_data.json | 0 types/common_data.go | 122 +++++ types/common_data_test.go | 9 + types/deserialize.go | 126 +++++ types/deserialize_test.go | 13 + types/types.go | 28 ++ types/utils.go | 21 + variables/circuit.go | 28 -- variables/deserialize.go | 156 +++++++ variables/deserialize_test.go | 17 + verifier/deserialize.go | 436 ------------------ verifier/deserialize_test.go | 24 - verifier/util.go | 24 + verifier/verifier.go | 21 +- verifier/verifier_test.go | 113 +---- 32 files changed, 839 insertions(+), 946 deletions(-) delete mode 100644 benchmark_plonk.go create mode 100644 fri/vars.go rename {verifier/data => testdata}/.DS_Store (100%) rename {verifier/data => testdata}/decode_block/common_circuit_data.json (100%) rename {verifier/data => testdata}/decode_block/proof_with_public_inputs.json (100%) rename {verifier/data => testdata}/decode_block/verifier_only_circuit_data.json (100%) rename {verifier/data => testdata}/step/common_circuit_data.json (100%) rename {verifier/data => testdata}/step/proof_with_public_inputs.json (100%) rename {verifier/data => testdata}/step/verifier_only_circuit_data.json (100%) create mode 100644 types/common_data.go create mode 100644 types/common_data_test.go create mode 100644 types/deserialize.go create mode 100644 types/deserialize_test.go create mode 100644 types/utils.go create mode 100644 variables/deserialize.go create mode 100644 variables/deserialize_test.go delete mode 100644 verifier/deserialize.go delete mode 100644 verifier/deserialize_test.go create mode 100644 verifier/util.go diff --git a/.gitignore b/.gitignore index fd45dc0..8045102 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ # vendor/ gnark-ed25519 +gnark.pprof \ No newline at end of file diff --git a/README.md b/README.md index 1bd048b..874f1d2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# gnark-plonky2-verifier +# Gnark Plonky2 Verifier -This is an in-progress implementation of a [Plonky2](https://github.com/mir-protocol/plonky2) verifier in Gnark (supports Groth16 and PLONK). It currently is able to verify some dummy circuits, but not much more as many of the custom gates used in Plonky2 are currently not implemented. +This is an implementation of a [Plonky2](https://github.com/mir-protocol/plonky2) verifier in Gnark (supports Groth16 and PLONK). Besides the verifier, there are some Gnark implementation of circuits in this repo that may be useful for other projects: diff --git a/benchmark.go b/benchmark.go index ad468fd..3fbf46f 100644 --- a/benchmark.go +++ b/benchmark.go @@ -8,51 +8,50 @@ import ( "os" "time" - gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" + "github.com/succinctlabs/gnark-plonky2-verifier/types" "github.com/succinctlabs/gnark-plonky2-verifier/variables" "github.com/succinctlabs/gnark-plonky2-verifier/verifier" "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark/backend/groth16" + "github.com/consensys/gnark/backend/plonk" "github.com/consensys/gnark/constraint" "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/frontend/cs/r1cs" + "github.com/consensys/gnark/frontend/cs/scs" "github.com/consensys/gnark/profile" + "github.com/consensys/gnark/test" ) -type BenchmarkPlonky2VerifierCircuit struct { - Proof variables.Proof - PublicInputs []gl.Variable `gnark:",public"` +func runBenchmark(plonky2Circuit string, proofSystem string, profileCircuit bool, dummy bool, saveArtifacts bool) { + commonCircuitData := types.DeserializeCommonCircuitData("testdata/" + plonky2Circuit + "/common_circuit_data.json") - verifierChip *verifier.VerifierChip `gnark:"-"` - plonky2CircuitName string `gnark:"-"` -} - -func (circuit *BenchmarkPlonky2VerifierCircuit) Define(api frontend.API) error { - circuitDirname := "./verifier/data/" + circuit.plonky2CircuitName + "/" - commonCircuitData := verifier.DeserializeCommonCircuitData(circuitDirname + "common_circuit_data.json") - verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuitDirname + "verifier_only_circuit_data.json") - - circuit.verifierChip = verifier.NewVerifierChip(api, commonCircuitData) - - circuit.verifierChip.Verify(circuit.Proof, circuit.PublicInputs, verifierOnlyCircuitData, commonCircuitData) - - return nil -} + proofWithPis := variables.DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs("testdata/" + plonky2Circuit + "/proof_with_public_inputs.json")) + verifierOnlyCircuitData := variables.DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData("testdata/" + plonky2Circuit + "/verifier_only_circuit_data.json")) -func compileCircuit(plonky2Circuit string, profileCircuit bool, serialize bool, outputSolidity bool, dummy bool) (constraint.ConstraintSystem, groth16.ProvingKey, groth16.VerifyingKey) { - circuit := BenchmarkPlonky2VerifierCircuit{ - plonky2CircuitName: plonky2Circuit, + circuit := verifier.ExampleVerifierCircuit{ + Proof: proofWithPis.Proof, + PublicInputs: proofWithPis.PublicInputs, + VerifierOnlyCircuitData: verifierOnlyCircuitData, + CommonCircuitData: commonCircuitData, } - proofWithPis := verifier.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json") - circuit.Proof = proofWithPis.Proof - circuit.PublicInputs = proofWithPis.PublicInputs var p *profile.Profile if profileCircuit { p = profile.Start() } - r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) + + var builder frontend.NewBuilder + if proofSystem == "plonk" { + builder = scs.NewBuilder + } else if proofSystem == "groth16" { + builder = r1cs.NewBuilder + } else { + fmt.Println("Please provide a valid proof system to benchmark, we only support plonk and groth16") + os.Exit(1) + } + + r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), builder, &circuit) if err != nil { fmt.Println("error in building circuit", err) os.Exit(1) @@ -68,16 +67,116 @@ func compileCircuit(plonky2Circuit string, profileCircuit bool, serialize bool, println("r1cs.GetNbInternalVariables(): ", r1cs.GetNbInternalVariables()) } + witness := verifier.ExampleVerifierCircuit{ + Proof: proofWithPis.Proof, + PublicInputs: proofWithPis.PublicInputs, + VerifierOnlyCircuitData: verifierOnlyCircuitData, + CommonCircuitData: commonCircuitData, + } + + if proofSystem == "plonk" { + plonkProof(r1cs, witness, dummy, saveArtifacts) + } else if proofSystem == "groth16" { + groth16Proof(r1cs, witness, dummy, saveArtifacts) + } else { + panic("Please provide a valid proof system to benchmark, we only support plonk and groth16") + } +} + +func plonkProof(r1cs constraint.ConstraintSystem, assignment verifier.ExampleVerifierCircuit, dummy bool, saveArtifacts bool) { + var pk plonk.ProvingKey + var vk plonk.VerifyingKey + var err error + // Don't serialize the circuit for now, since it takes up too much memory - /* - if serialize { - fR1CS, _ := os.Create("circuit") - r1cs.WriteTo(fR1CS) - fR1CS.Close() + // if saveArtifacts { + // fR1CS, _ := os.Create("circuit") + // r1cs.WriteTo(fR1CS) + // fR1CS.Close() + // } + + fmt.Println("Running circuit setup", time.Now()) + if dummy { + panic("dummy setup not supported for plonk") + } else { + fmt.Println("Using real setup") + srs, err := test.NewKZGSRS(r1cs) + if err != nil { + panic(err) } - */ + pk, vk, err = plonk.Setup(r1cs, srs) + } + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + if saveArtifacts { + fPK, _ := os.Create("proving.key") + pk.WriteTo(fPK) + fPK.Close() + + if vk != nil { + fVK, _ := os.Create("verifying.key") + vk.WriteTo(fVK) + fVK.Close() + } + + fSolidity, _ := os.Create("proof.sol") + err = vk.ExportSolidity(fSolidity) + } + + fmt.Println("Generating witness", time.Now()) + witness, _ := frontend.NewWitness(&assignment, ecc.BN254.ScalarField()) + publicWitness, _ := witness.Public() + if saveArtifacts { + fWitness, _ := os.Create("witness") + witness.WriteTo(fWitness) + fWitness.Close() + } + + fmt.Println("Creating proof", time.Now()) + proof, err := plonk.Prove(r1cs, pk, witness) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + if saveArtifacts { + fProof, _ := os.Create("proof.proof") + proof.WriteTo(fProof) + fProof.Close() + } + + if vk == nil { + fmt.Println("vk is nil, means you're using dummy setup and we skip verification of proof") + return + } + + fmt.Println("Verifying proof", time.Now()) + err = plonk.Verify(proof, vk, publicWitness) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + const fpSize = 4 * 8 + var buf bytes.Buffer + proof.WriteRawTo(&buf) + proofBytes := buf.Bytes() + fmt.Printf("proofBytes: %v\n", proofBytes) +} + +func groth16Proof(r1cs constraint.ConstraintSystem, assignment verifier.ExampleVerifierCircuit, dummy bool, saveArtifacts bool) { var pk groth16.ProvingKey var vk groth16.VerifyingKey + var err error + + // Don't serialize the circuit for now, since it takes up too much memory + // if saveArtifacts { + // fR1CS, _ := os.Create("circuit") + // r1cs.WriteTo(fR1CS) + // fR1CS.Close() + // } fmt.Println("Running circuit setup", time.Now()) if dummy { @@ -92,37 +191,25 @@ func compileCircuit(plonky2Circuit string, profileCircuit bool, serialize bool, os.Exit(1) } - if serialize { + if saveArtifacts { fPK, _ := os.Create("proving.key") pk.WriteTo(fPK) fPK.Close() - fVK, _ := os.Create("verifying.key") - vk.WriteTo(fVK) - fVK.Close() - } + if vk != nil { + fVK, _ := os.Create("verifying.key") + vk.WriteTo(fVK) + fVK.Close() + } - if outputSolidity { fSolidity, _ := os.Create("proof.sol") err = vk.ExportSolidity(fSolidity) } - return r1cs, pk, vk -} - -func createProof(plonky2Circuit string, r1cs constraint.ConstraintSystem, pk groth16.ProvingKey, vk groth16.VerifyingKey, serialize bool) groth16.Proof { - proofWithPis := verifier.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json") - - // Witness - assignment := &BenchmarkPlonky2VerifierCircuit{ - Proof: proofWithPis.Proof, - PublicInputs: proofWithPis.PublicInputs, - } - fmt.Println("Generating witness", time.Now()) - witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) + witness, _ := frontend.NewWitness(&assignment, ecc.BN254.ScalarField()) publicWitness, _ := witness.Public() - if serialize { + if saveArtifacts { fWitness, _ := os.Create("witness") witness.WriteTo(fWitness) fWitness.Close() @@ -134,15 +221,15 @@ func createProof(plonky2Circuit string, r1cs constraint.ConstraintSystem, pk gro fmt.Println(err) os.Exit(1) } - if serialize { + if saveArtifacts { fProof, _ := os.Create("proof.proof") proof.WriteTo(fProof) fProof.Close() } if vk == nil { - fmt.Println("vk is nil, means you're using dummy setup and we skip verification step") - return proof + fmt.Println("vk is nil, means you're using dummy setup and we skip verification of proof") + return } fmt.Println("Verifying proof", time.Now()) @@ -184,14 +271,14 @@ func createProof(plonky2Circuit string, r1cs constraint.ConstraintSystem, pk gro println("c[0] is ", c[0].String()) println("c[1] is ", c[1].String()) - return proof } func main() { plonky2Circuit := flag.String("plonky2-circuit", "", "plonky2 circuit to benchmark") - profileCircuit := flag.Bool("profile", false, "profile the circuit") - serialize := flag.Bool("serialize", false, "serialize the circuit") - outputSolidity := flag.Bool("solidity", false, "output solidity code for the circuit") + proofSystem := flag.String("proof-system", "groth16", "proof system to benchmark") + profileCircuit := flag.Bool("profile", true, "profile the circuit") + dummySetup := flag.Bool("dummy", true, "use dummy setup") + saveArtifacts := flag.Bool("save", false, "save circuit artifacts") flag.Parse() @@ -200,6 +287,12 @@ func main() { os.Exit(1) } - r1cs, pk, vk := compileCircuit(*plonky2Circuit, *profileCircuit, *serialize, *outputSolidity, true) - createProof(*plonky2Circuit, r1cs, pk, vk, *serialize) + if *proofSystem == "plonk" { + *dummySetup = false + } + + fmt.Printf("Running benchmark for %s circuit with proof system %s\n", *plonky2Circuit, *proofSystem) + fmt.Printf("Profiling: %t, DummySetup: %t, SaveArtifacts: %t\n", *profileCircuit, *dummySetup, *saveArtifacts) + + runBenchmark(*plonky2Circuit, *proofSystem, *profileCircuit, *dummySetup, *saveArtifacts) } diff --git a/benchmark_plonk.go b/benchmark_plonk.go deleted file mode 100644 index 9089d17..0000000 --- a/benchmark_plonk.go +++ /dev/null @@ -1,187 +0,0 @@ -package main - -import ( - "bytes" - "flag" - "fmt" - "math/big" - "os" - "time" - - gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" - "github.com/succinctlabs/gnark-plonky2-verifier/variables" - "github.com/succinctlabs/gnark-plonky2-verifier/verifier" - - "github.com/consensys/gnark-crypto/ecc" - "github.com/consensys/gnark/backend/plonk" - "github.com/consensys/gnark/constraint" - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/frontend/cs/scs" - "github.com/consensys/gnark/profile" - "github.com/consensys/gnark/test" -) - -type BenchmarkPlonky2VerifierCircuitPlonk struct { - Proof variables.Proof - PublicInputs []gl.Variable `gnark:",public"` - - verifierChip *verifier.VerifierChip `gnark:"-"` - plonky2CircuitName string `gnark:"-"` -} - -func (circuit *BenchmarkPlonky2VerifierCircuitPlonk) Define(api frontend.API) error { - circuitDirname := "./verifier/data/" + circuit.plonky2CircuitName + "/" - commonCircuitData := verifier.DeserializeCommonCircuitData(circuitDirname + "common_circuit_data.json") - verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuitDirname + "verifier_only_circuit_data.json") - - circuit.verifierChip = verifier.NewVerifierChip(api, commonCircuitData) - - circuit.verifierChip.Verify(circuit.Proof, circuit.PublicInputs, verifierOnlyCircuitData, commonCircuitData) - - return nil -} - -func compileCircuitPlonk(plonky2Circuit string, profileCircuit bool, serialize bool, outputSolidity bool) (constraint.ConstraintSystem, plonk.ProvingKey, plonk.VerifyingKey) { - circuit := BenchmarkPlonky2VerifierCircuitPlonk{ - plonky2CircuitName: plonky2Circuit, - } - proofWithPis := verifier.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json") - circuit.Proof = proofWithPis.Proof - circuit.PublicInputs = proofWithPis.PublicInputs - - var p *profile.Profile - if profileCircuit { - p = profile.Start() - } - r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), scs.NewBuilder, &circuit) - if err != nil { - fmt.Println("error in building circuit", err) - os.Exit(1) - } - - if profileCircuit { - p.Stop() - p.Top() - println("r1cs.GetNbCoefficients(): ", r1cs.GetNbCoefficients()) - println("r1cs.GetNbConstraints(): ", r1cs.GetNbConstraints()) - println("r1cs.GetNbSecretVariables(): ", r1cs.GetNbSecretVariables()) - println("r1cs.GetNbPublicVariables(): ", r1cs.GetNbPublicVariables()) - println("r1cs.GetNbInternalVariables(): ", r1cs.GetNbInternalVariables()) - } - - // Don't serialize the circuit for now, since it takes up too much memory - /* - if serialize { - fR1CS, _ := os.Create("circuit") - r1cs.WriteTo(fR1CS) - fR1CS.Close() - } - */ - - srs, err := test.NewKZGSRS(r1cs) - if err != nil { - panic(err) - } - - fmt.Println("Running circuit setup", time.Now()) - pk, vk, err := plonk.Setup(r1cs, srs) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - if serialize { - fPK, _ := os.Create("proving.key") - pk.WriteTo(fPK) - fPK.Close() - - fVK, _ := os.Create("verifying.key") - vk.WriteTo(fVK) - fVK.Close() - } - - if outputSolidity { - fSolidity, _ := os.Create("proof.sol") - err = vk.ExportSolidity(fSolidity) - } - - return r1cs, pk, vk -} - -func createProofPlonk(plonky2Circuit string, r1cs constraint.ConstraintSystem, pk plonk.ProvingKey, vk plonk.VerifyingKey, serialize bool) plonk.Proof { - proofWithPis := verifier.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json") - - // Witness - assignment := &BenchmarkPlonky2VerifierCircuitPlonk{ - Proof: proofWithPis.Proof, - PublicInputs: proofWithPis.PublicInputs, - } - - fmt.Println("Generating witness", time.Now()) - witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) - publicWitness, _ := witness.Public() - - fmt.Println("Creating proof", time.Now()) - proof, err := plonk.Prove(r1cs, pk, witness) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - fmt.Println("Verifying proof", time.Now()) - err = plonk.Verify(proof, vk, publicWitness) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - const fpSize = 4 * 8 - var buf bytes.Buffer - proof.WriteRawTo(&buf) - proofBytes := buf.Bytes() - - var ( - a [2]*big.Int - b [2][2]*big.Int - c [2]*big.Int - ) - - // proof.Ar, proof.Bs, proof.Krs - a[0] = new(big.Int).SetBytes(proofBytes[fpSize*0 : fpSize*1]) - a[1] = new(big.Int).SetBytes(proofBytes[fpSize*1 : fpSize*2]) - b[0][0] = new(big.Int).SetBytes(proofBytes[fpSize*2 : fpSize*3]) - b[0][1] = new(big.Int).SetBytes(proofBytes[fpSize*3 : fpSize*4]) - b[1][0] = new(big.Int).SetBytes(proofBytes[fpSize*4 : fpSize*5]) - b[1][1] = new(big.Int).SetBytes(proofBytes[fpSize*5 : fpSize*6]) - c[0] = new(big.Int).SetBytes(proofBytes[fpSize*6 : fpSize*7]) - c[1] = new(big.Int).SetBytes(proofBytes[fpSize*7 : fpSize*8]) - - println("a[0] is ", a[0].String()) - println("a[1] is ", a[1].String()) - - println("b[0][0] is ", b[0][0].String()) - println("b[0][1] is ", b[0][1].String()) - println("b[1][0] is ", b[1][0].String()) - println("b[1][1] is ", b[1][1].String()) - - println("c[0] is ", c[0].String()) - println("c[1] is ", c[1].String()) - - return proof -} - -func main() { - plonky2Circuit := flag.String("plonky2-circuit", "", "plonky2 circuit to benchmark") - profileCircuit := flag.Bool("profile", false, "profile the circuit") - serialize := flag.Bool("serialize", false, "serialize the circuit") - outputSolidity := flag.Bool("solidity", false, "output solidity code for the circuit") - - flag.Parse() - - if plonky2Circuit == nil || *plonky2Circuit == "" { - fmt.Println("Please provide a plonky2 circuit to benchmark") - os.Exit(1) - } - - r1cs, pk, vk := compileCircuitPlonk(*plonky2Circuit, *profileCircuit, *serialize, *outputSolidity) - createProofPlonk(*plonky2Circuit, r1cs, pk, vk, *serialize) -} diff --git a/fri/fri.go b/fri/fri.go index 9483ace..cd13cf1 100644 --- a/fri/fri.go +++ b/fri/fri.go @@ -18,22 +18,60 @@ type Chip struct { api frontend.API `gnark:"-"` gl gl.Chip `gnark:"-"` poseidonBN254Chip *poseidon.BN254Chip + commonData *types.CommonCircuitData friParams *types.FriParams `gnark:"-"` } func NewChip( api frontend.API, + commonData *types.CommonCircuitData, friParams *types.FriParams, ) *Chip { poseidonBN254Chip := poseidon.NewBN254Chip(api) return &Chip{ api: api, poseidonBN254Chip: poseidonBN254Chip, + commonData: commonData, friParams: friParams, gl: *gl.New(api), } } +func (f *Chip) GetInstance(zeta gl.QuadraticExtensionVariable) InstanceInfo { + zetaBatch := BatchInfo{ + Point: zeta, + Polynomials: friAllPolys(f.commonData), + } + + g := gl.PrimitiveRootOfUnity(f.commonData.DegreeBits) + zetaNext := f.gl.MulExtension( + gl.NewVariable(g.Uint64()).ToQuadraticExtension(), + zeta, + ) + + zetaNextBath := BatchInfo{ + Point: zetaNext, + Polynomials: friZSPolys(f.commonData), + } + + return InstanceInfo{ + Oracles: friOracles(f.commonData), + Batches: []BatchInfo{zetaBatch, zetaNextBath}, + } +} + +func (f *Chip) ToOpenings(c variables.OpeningSet) Openings { + values := c.Constants // num_constants + 1 + values = append(values, c.PlonkSigmas...) // num_routed_wires + values = append(values, c.Wires...) // num_wires + values = append(values, c.PlonkZs...) // num_challenges + values = append(values, c.PartialProducts...) // num_challenges * num_partial_products + values = append(values, c.QuotientPolys...) // num_challenges * quotient_degree_factor + zetaBatch := OpeningBatch{Values: values} + zetaNextBatch := OpeningBatch{Values: c.PlonkZsNext} + return Openings{Batches: []OpeningBatch{zetaBatch, zetaNextBatch}} +} + func (f *Chip) assertLeadingZeros(powWitness gl.Variable, friConfig types.FriConfig) { // Asserts that powWitness'es big-endian bit representation has at least `leading_zeros` leading zeros. // Note that this is assuming that the Goldilocks field is being used. Specfically that the diff --git a/fri/fri_test.go b/fri/fri_test.go index 4a8e507..19fb51d 100644 --- a/fri/fri_test.go +++ b/fri/fri_test.go @@ -10,24 +10,24 @@ import ( "github.com/succinctlabs/gnark-plonky2-verifier/fri" gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" + "github.com/succinctlabs/gnark-plonky2-verifier/types" "github.com/succinctlabs/gnark-plonky2-verifier/variables" - "github.com/succinctlabs/gnark-plonky2-verifier/verifier" ) type TestFriCircuit struct { - proofWithPIsFilename string `gnark:"-"` - commonCircuitDataFilename string `gnark:"-"` - verifierOnlyCircuitDataFilename string `gnark:"-"` + ProofWithPis variables.ProofWithPublicInputs + VerifierOnlyCircuitData variables.VerifierOnlyCircuitData + CommonCircuitData types.CommonCircuitData } func (circuit *TestFriCircuit) Define(api frontend.API) error { - proofWithPis := verifier.DeserializeProofWithPublicInputs(circuit.proofWithPIsFilename) - commonCircuitData := verifier.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename) - verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuit.verifierOnlyCircuitDataFilename) + commonCircuitData := circuit.CommonCircuitData + verifierOnlyCircuitData := circuit.VerifierOnlyCircuitData + proofWithPis := circuit.ProofWithPis glApi := gl.New(api) poseidonChip := poseidon.NewGoldilocksChip(api) - friChip := fri.NewChip(api, &commonCircuitData.FriParams) + friChip := fri.NewChip(api, &commonCircuitData, &commonCircuitData.FriParams) challengerChip := challenger.NewChip(api) challengerChip.ObserveBN254Hash(verifierOnlyCircuitData.CircuitDigest) @@ -46,7 +46,7 @@ func (circuit *TestFriCircuit) Define(api frontend.API) error { plonkZeta := challengerChip.GetExtensionChallenge() glApi.AssertIsEqual(plonkZeta[0], gl.NewVariable("3892795992421241388")) - challengerChip.ObserveOpenings(fri.ToOpenings(proofWithPis.Proof.Openings)) + challengerChip.ObserveOpenings(friChip.ToOpenings(proofWithPis.Proof.Openings)) friChallenges := challengerChip.GetFriChallenges( proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps, @@ -94,8 +94,8 @@ func (circuit *TestFriCircuit) Define(api frontend.API) error { } friChip.VerifyFriProof( - fri.GetInstance(&commonCircuitData, glApi, plonkZeta, commonCircuitData.DegreeBits), - fri.ToOpenings(proofWithPis.Proof.Openings), + friChip.GetInstance(plonkZeta), + friChip.ToOpenings(proofWithPis.Proof.Openings), &friChallenges, initialMerkleCaps, &proofWithPis.Proof.OpeningProof, @@ -107,16 +107,24 @@ func (circuit *TestFriCircuit) Define(api frontend.API) error { func TestDecodeBlockFriVerification(t *testing.T) { assert := test.NewAssert(t) + proofWithPIsFilename := "../testdata/decode_block/proof_with_public_inputs.json" + commonCircuitDataFilename := "../testdata/decode_block/common_circuit_data.json" + verifierOnlyCircuitDataFilename := "../testdata/decode_block/verifier_only_circuit_data.json" + + proofWithPis := variables.DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs(proofWithPIsFilename)) + commonCircuitData := types.DeserializeCommonCircuitData(commonCircuitDataFilename) + verifierOnlyCircuitData := variables.DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData(verifierOnlyCircuitDataFilename)) + testCase := func() { circuit := TestFriCircuit{ - proofWithPIsFilename: "../../data/decode_block/proof_with_public_inputs.json", - commonCircuitDataFilename: "../../data/decode_block//common_circuit_data.json", - verifierOnlyCircuitDataFilename: "../../data/decode_block//verifier_only_circuit_data.json", + proofWithPis, + verifierOnlyCircuitData, + commonCircuitData, } witness := TestFriCircuit{ - proofWithPIsFilename: "../../data/dummy_2^14_gates/proof_with_public_inputs.json", - commonCircuitDataFilename: "../../data/dummy_2^14_gates/common_circuit_data.json", - verifierOnlyCircuitDataFilename: ".../../data/dummy_2^14_gates/verifier_only_circuit_data.json", + proofWithPis, + verifierOnlyCircuitData, + commonCircuitData, } err := test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField()) assert.NoError(err) diff --git a/fri/fri_utils.go b/fri/fri_utils.go index aacd5e1..dccee7e 100644 --- a/fri/fri_utils.go +++ b/fri/fri_utils.go @@ -1,30 +1,9 @@ package fri import ( - gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" - "github.com/succinctlabs/gnark-plonky2-verifier/variables" + "github.com/succinctlabs/gnark-plonky2-verifier/types" ) -type OpeningBatch struct { - Values []gl.QuadraticExtensionVariable -} - -type Openings struct { - Batches []OpeningBatch -} - -func ToOpenings(c variables.OpeningSet) Openings { - values := c.Constants // num_constants + 1 - values = append(values, c.PlonkSigmas...) // num_routed_wires - values = append(values, c.Wires...) // num_wires - values = append(values, c.PlonkZs...) // num_challenges - values = append(values, c.PartialProducts...) // num_challenges * num_partial_products - values = append(values, c.QuotientPolys...) // num_challenges * quotient_degree_factor - zetaBatch := OpeningBatch{Values: values} - zetaNextBatch := OpeningBatch{Values: c.PlonkZsNext} - return Openings{Batches: []OpeningBatch{zetaBatch, zetaNextBatch}} -} - type PolynomialInfo struct { OracleIndex uint64 PolynomialInfo uint64 @@ -35,16 +14,6 @@ type OracleInfo struct { Blinding bool } -type BatchInfo struct { - Point gl.QuadraticExtensionVariable - Polynomials []PolynomialInfo -} - -type InstanceInfo struct { - Oracles []OracleInfo - Batches []BatchInfo -} - type PlonkOracle struct { index uint64 blinding bool @@ -70,7 +39,7 @@ var QUOTIENT = PlonkOracle{ blinding: true, } -func polynomialInfoFromRange(c *variables.CommonCircuitData, oracleIdx uint64, startPolyIdx uint64, endPolyIdx uint64) []PolynomialInfo { +func polynomialInfoFromRange(c *types.CommonCircuitData, oracleIdx uint64, startPolyIdx uint64, endPolyIdx uint64) []PolynomialInfo { returnArr := make([]PolynomialInfo, 0) for i := startPolyIdx; i < endPolyIdx; i++ { returnArr = append(returnArr, @@ -84,7 +53,7 @@ func polynomialInfoFromRange(c *variables.CommonCircuitData, oracleIdx uint64, s } // Range of the sigma polynomials in the `constants_sigmas_commitment`. -func sigmasRange(c *variables.CommonCircuitData) []uint64 { +func sigmasRange(c *types.CommonCircuitData) []uint64 { returnArr := make([]uint64, 0) for i := c.NumConstants; i <= c.NumConstants+c.Config.NumRoutedWires; i++ { returnArr = append(returnArr, i) @@ -93,20 +62,20 @@ func sigmasRange(c *variables.CommonCircuitData) []uint64 { return returnArr } -func numPreprocessedPolys(c *variables.CommonCircuitData) uint64 { +func numPreprocessedPolys(c *types.CommonCircuitData) uint64 { sigmasRange := sigmasRange(c) return sigmasRange[len(sigmasRange)-1] } -func numZSPartialProductsPolys(c *variables.CommonCircuitData) uint64 { +func numZSPartialProductsPolys(c *types.CommonCircuitData) uint64 { return c.Config.NumChallenges * (1 + c.NumPartialProducts) } -func numQuotientPolys(c *variables.CommonCircuitData) uint64 { +func numQuotientPolys(c *types.CommonCircuitData) uint64 { return c.Config.NumChallenges * c.QuotientDegreeFactor } -func friPreprocessedPolys(c *variables.CommonCircuitData) []PolynomialInfo { +func friPreprocessedPolys(c *types.CommonCircuitData) []PolynomialInfo { return polynomialInfoFromRange( c, CONSTANTS_SIGMAS.index, @@ -115,12 +84,12 @@ func friPreprocessedPolys(c *variables.CommonCircuitData) []PolynomialInfo { ) } -func friWirePolys(c *variables.CommonCircuitData) []PolynomialInfo { +func friWirePolys(c *types.CommonCircuitData) []PolynomialInfo { numWirePolys := c.Config.NumWires return polynomialInfoFromRange(c, WIRES.index, 0, numWirePolys) } -func friZSPartialProductsPolys(c *variables.CommonCircuitData) []PolynomialInfo { +func friZSPartialProductsPolys(c *types.CommonCircuitData) []PolynomialInfo { return polynomialInfoFromRange( c, ZS_PARTIAL_PRODUCTS.index, @@ -129,7 +98,7 @@ func friZSPartialProductsPolys(c *variables.CommonCircuitData) []PolynomialInfo ) } -func friQuotientPolys(c *variables.CommonCircuitData) []PolynomialInfo { +func friQuotientPolys(c *types.CommonCircuitData) []PolynomialInfo { return polynomialInfoFromRange( c, QUOTIENT.index, @@ -138,7 +107,7 @@ func friQuotientPolys(c *variables.CommonCircuitData) []PolynomialInfo { ) } -func friZSPolys(c *variables.CommonCircuitData) []PolynomialInfo { +func friZSPolys(c *types.CommonCircuitData) []PolynomialInfo { return polynomialInfoFromRange( c, ZS_PARTIAL_PRODUCTS.index, @@ -147,7 +116,7 @@ func friZSPolys(c *variables.CommonCircuitData) []PolynomialInfo { ) } -func friOracles(c *variables.CommonCircuitData) []OracleInfo { +func friOracles(c *types.CommonCircuitData) []OracleInfo { return []OracleInfo{ { NumPolys: numPreprocessedPolys(c), @@ -168,7 +137,7 @@ func friOracles(c *variables.CommonCircuitData) []OracleInfo { } } -func friAllPolys(c *variables.CommonCircuitData) []PolynomialInfo { +func friAllPolys(c *types.CommonCircuitData) []PolynomialInfo { returnArr := make([]PolynomialInfo, 0) returnArr = append(returnArr, friPreprocessedPolys(c)...) returnArr = append(returnArr, friWirePolys(c)...) @@ -177,26 +146,3 @@ func friAllPolys(c *variables.CommonCircuitData) []PolynomialInfo { return returnArr } - -func GetInstance(c *variables.CommonCircuitData, glApi *gl.Chip, zeta gl.QuadraticExtensionVariable, degreeBits uint64) InstanceInfo { - zetaBatch := BatchInfo{ - Point: zeta, - Polynomials: friAllPolys(c), - } - - g := gl.PrimitiveRootOfUnity(degreeBits) - zetaNext := glApi.MulExtension( - gl.NewVariable(g.Uint64()).ToQuadraticExtension(), - zeta, - ) - - zetaNextBath := BatchInfo{ - Point: zetaNext, - Polynomials: friZSPolys(c), - } - - return InstanceInfo{ - Oracles: friOracles(c), - Batches: []BatchInfo{zetaBatch, zetaNextBath}, - } -} diff --git a/fri/vars.go b/fri/vars.go new file mode 100644 index 0000000..e3ef63b --- /dev/null +++ b/fri/vars.go @@ -0,0 +1,21 @@ +package fri + +import gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" + +type BatchInfo struct { + Point gl.QuadraticExtensionVariable + Polynomials []PolynomialInfo +} + +type InstanceInfo struct { + Oracles []OracleInfo + Batches []BatchInfo +} + +type OpeningBatch struct { + Values []gl.QuadraticExtensionVariable +} + +type Openings struct { + Batches []OpeningBatch +} diff --git a/plonk/gates/gates_test.go b/plonk/gates/gates_test.go index 3409e46..0f64769 100644 --- a/plonk/gates/gates_test.go +++ b/plonk/gates/gates_test.go @@ -11,7 +11,7 @@ import ( gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" - "github.com/succinctlabs/gnark-plonky2-verifier/verifier" + "github.com/succinctlabs/gnark-plonky2-verifier/types" ) // From recursive_step circuit @@ -690,7 +690,7 @@ type TestGateCircuit struct { } func (circuit *TestGateCircuit) Define(api frontend.API) error { - commonCircuitData := verifier.DeserializeCommonCircuitData("../../data/decode_block/common_circuit_data.json") + commonCircuitData := types.DeserializeCommonCircuitData("../../testdata/decode_block/common_circuit_data.json") numSelectors := commonCircuitData.SelectorsInfo.NumSelectors() glApi := gl.New(api) diff --git a/plonk/plonk.go b/plonk/plonk.go index b94a3d4..945611f 100644 --- a/plonk/plonk.go +++ b/plonk/plonk.go @@ -5,27 +5,37 @@ import ( gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" + "github.com/succinctlabs/gnark-plonky2-verifier/types" "github.com/succinctlabs/gnark-plonky2-verifier/variables" ) type PlonkChip struct { api frontend.API `gnark:"-"` - commonData variables.CommonCircuitData `gnark:"-"` + commonData types.CommonCircuitData `gnark:"-"` + // These are global constant variables that we use in this Chip that we save here. + // This avoids having to recreate them every time we use them. DEGREE gl.Variable `gnark:"-"` DEGREE_BITS_F gl.Variable `gnark:"-"` DEGREE_QE gl.QuadraticExtensionVariable `gnark:"-"` + commonDataKIs []gl.Variable `gnark:"-"` evaluateGatesChip *gates.EvaluateGatesChip } -func NewPlonkChip(api frontend.API, commonData variables.CommonCircuitData) *PlonkChip { +func NewPlonkChip(api frontend.API, commonData types.CommonCircuitData) *PlonkChip { // TODO: Should degreeBits be verified that it fits within the field and that degree is within uint64? + // Create the gates based on commonData GateIds + createdGates := []gates.Gate{} + for _, gateId := range commonData.GateIds { + createdGates = append(createdGates, gates.GateInstanceFromId(gateId)) + } + evaluateGatesChip := gates.NewEvaluateGatesChip( api, - commonData.Gates, + createdGates, commonData.NumGateConstraints, commonData.SelectorsInfo, ) @@ -38,6 +48,7 @@ func NewPlonkChip(api frontend.API, commonData variables.CommonCircuitData) *Plo DEGREE: gl.NewVariable(1 << commonData.DegreeBits), DEGREE_BITS_F: gl.NewVariable(commonData.DegreeBits), DEGREE_QE: gl.NewVariable(1 << commonData.DegreeBits).ToQuadraticExtension(), + commonDataKIs: gl.Uint64ArrayToVariableArray(commonData.KIs), evaluateGatesChip: evaluateGatesChip, } @@ -117,7 +128,7 @@ func (p *PlonkChip) evalVanishingPoly( sIDs := make([]gl.QuadraticExtensionVariable, p.commonData.Config.NumRoutedWires) for i := uint64(0); i < p.commonData.Config.NumRoutedWires; i++ { - sIDs[i] = glApi.ScalarMulExtension(proofChallenges.PlonkZeta, p.commonData.KIs[i]) + sIDs[i] = glApi.ScalarMulExtension(proofChallenges.PlonkZeta, p.commonDataKIs[i]) } // Calculate L_0(zeta) diff --git a/plonk/plonk_test.go b/plonk/plonk_test.go index 5cb00dc..5a7b898 100644 --- a/plonk/plonk_test.go +++ b/plonk/plonk_test.go @@ -7,23 +7,25 @@ import ( "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/test" "github.com/succinctlabs/gnark-plonky2-verifier/plonk" + "github.com/succinctlabs/gnark-plonky2-verifier/types" + "github.com/succinctlabs/gnark-plonky2-verifier/variables" "github.com/succinctlabs/gnark-plonky2-verifier/verifier" ) type TestPlonkCircuit struct { - proofWithPIsFilename string `gnark:"-"` - commonCircuitDataFilename string `gnark:"-"` - verifierOnlyCircuitDataFilename string `gnark:"-"` + ProofWithPis variables.ProofWithPublicInputs `gnark:",public"` + VerifierOnlyCircuitData variables.VerifierOnlyCircuitData `gnark:",public"` + CommonCircuitData types.CommonCircuitData } func (circuit *TestPlonkCircuit) Define(api frontend.API) error { - proofWithPis := verifier.DeserializeProofWithPublicInputs(circuit.proofWithPIsFilename) - commonCircuitData := verifier.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename) - verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuit.verifierOnlyCircuitDataFilename) + commonCircuitData := circuit.CommonCircuitData + verifierOnlyCircuitData := circuit.VerifierOnlyCircuitData + proofWithPis := circuit.ProofWithPis verifierChip := verifier.NewVerifierChip(api, commonCircuitData) publicInputsHash := verifierChip.GetPublicInputsHash(proofWithPis.PublicInputs) - proofChallenges := verifierChip.GetChallenges(proofWithPis.Proof, publicInputsHash, commonCircuitData, verifierOnlyCircuitData) + proofChallenges := verifierChip.GetChallenges(proofWithPis.Proof, publicInputsHash, verifierOnlyCircuitData) plonkChip := plonk.NewPlonkChip( api, @@ -37,13 +39,25 @@ func (circuit *TestPlonkCircuit) Define(api frontend.API) error { func TestPlonkDecodeBlock(t *testing.T) { assert := test.NewAssert(t) + proofWithPIsFilename := "../testdata/decode_block/proof_with_public_inputs.json" + commonCircuitDataFilename := "../testdata/decode_block/common_circuit_data.json" + verifierOnlyCircuitDataFilename := "../testdata/decode_block/verifier_only_circuit_data.json" + + proofWithPis := variables.DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs(proofWithPIsFilename)) + commonCircuitData := types.DeserializeCommonCircuitData(commonCircuitDataFilename) + verifierOnlyCircuitData := variables.DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData(verifierOnlyCircuitDataFilename)) + testCase := func() { circuit := TestPlonkCircuit{ - proofWithPIsFilename: "../../data/decode_block/proof_with_public_inputs.json", - commonCircuitDataFilename: "../../data/decode_block/common_circuit_data.json", - verifierOnlyCircuitDataFilename: "../../data/decode_block/verifier_only_circuit_data.json", + proofWithPis, + verifierOnlyCircuitData, + commonCircuitData, + } + witness := TestPlonkCircuit{ + proofWithPis, + verifierOnlyCircuitData, + commonCircuitData, } - witness := TestPlonkCircuit{} err := test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField()) assert.NoError(err) } diff --git a/verifier/data/.DS_Store b/testdata/.DS_Store similarity index 100% rename from verifier/data/.DS_Store rename to testdata/.DS_Store diff --git a/verifier/data/decode_block/common_circuit_data.json b/testdata/decode_block/common_circuit_data.json similarity index 100% rename from verifier/data/decode_block/common_circuit_data.json rename to testdata/decode_block/common_circuit_data.json diff --git a/verifier/data/decode_block/proof_with_public_inputs.json b/testdata/decode_block/proof_with_public_inputs.json similarity index 100% rename from verifier/data/decode_block/proof_with_public_inputs.json rename to testdata/decode_block/proof_with_public_inputs.json diff --git a/verifier/data/decode_block/verifier_only_circuit_data.json b/testdata/decode_block/verifier_only_circuit_data.json similarity index 100% rename from verifier/data/decode_block/verifier_only_circuit_data.json rename to testdata/decode_block/verifier_only_circuit_data.json diff --git a/verifier/data/step/common_circuit_data.json b/testdata/step/common_circuit_data.json similarity index 100% rename from verifier/data/step/common_circuit_data.json rename to testdata/step/common_circuit_data.json diff --git a/verifier/data/step/proof_with_public_inputs.json b/testdata/step/proof_with_public_inputs.json similarity index 100% rename from verifier/data/step/proof_with_public_inputs.json rename to testdata/step/proof_with_public_inputs.json diff --git a/verifier/data/step/verifier_only_circuit_data.json b/testdata/step/verifier_only_circuit_data.json similarity index 100% rename from verifier/data/step/verifier_only_circuit_data.json rename to testdata/step/verifier_only_circuit_data.json diff --git a/types/common_data.go b/types/common_data.go new file mode 100644 index 0000000..3c386f3 --- /dev/null +++ b/types/common_data.go @@ -0,0 +1,122 @@ +package types + +import ( + "encoding/json" + "io" + "os" + + "github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" +) + +type CommonCircuitDataRaw struct { + Config struct { + NumWires uint64 `json:"num_wires"` + NumRoutedWires uint64 `json:"num_routed_wires"` + NumConstants uint64 `json:"num_constants"` + UseBaseArithmeticGate bool `json:"use_base_arithmetic_gate"` + SecurityBits uint64 `json:"security_bits"` + NumChallenges uint64 `json:"num_challenges"` + ZeroKnowledge bool `json:"zero_knowledge"` + MaxQuotientDegreeFactor uint64 `json:"max_quotient_degree_factor"` + FriConfig struct { + RateBits uint64 `json:"rate_bits"` + CapHeight uint64 `json:"cap_height"` + ProofOfWorkBits uint64 `json:"proof_of_work_bits"` + ReductionStrategy struct { + ConstantArityBits []uint64 `json:"ConstantArityBits"` + } `json:"reduction_strategy"` + NumQueryRounds uint64 `json:"num_query_rounds"` + } `json:"fri_config"` + } `json:"config"` + FriParams struct { + Config struct { + RateBits uint64 `json:"rate_bits"` + CapHeight uint64 `json:"cap_height"` + ProofOfWorkBits uint64 `json:"proof_of_work_bits"` + ReductionStrategy struct { + ConstantArityBits []uint64 `json:"ConstantArityBits"` + } `json:"reduction_strategy"` + NumQueryRounds uint64 `json:"num_query_rounds"` + } `json:"config"` + Hiding bool `json:"hiding"` + DegreeBits uint64 `json:"degree_bits"` + ReductionArityBits []uint64 `json:"reduction_arity_bits"` + } `json:"fri_params"` + Gates []string `json:"gates"` + SelectorsInfo struct { + SelectorIndices []uint64 `json:"selector_indices"` + Groups []struct { + Start uint64 `json:"start"` + End uint64 `json:"end"` + } `json:"groups"` + } `json:"selectors_info"` + QuotientDegreeFactor uint64 `json:"quotient_degree_factor"` + NumGateConstraints uint64 `json:"num_gate_constraints"` + NumConstants uint64 `json:"num_constants"` + NumPublicInputs uint64 `json:"num_public_inputs"` + KIs []uint64 `json:"k_is"` + NumPartialProducts uint64 `json:"num_partial_products"` +} + +func DeserializeCommonCircuitData(path string) CommonCircuitData { + jsonFile, err := os.Open(path) + if err != nil { + panic(err) + } + + defer jsonFile.Close() + rawBytes, _ := io.ReadAll(jsonFile) + + var raw CommonCircuitDataRaw + err = json.Unmarshal(rawBytes, &raw) + if err != nil { + panic(err) + } + + var commonCircuitData CommonCircuitData + commonCircuitData.Config.NumWires = raw.Config.NumWires + commonCircuitData.Config.NumRoutedWires = raw.Config.NumRoutedWires + commonCircuitData.Config.NumConstants = raw.Config.NumConstants + commonCircuitData.Config.UseBaseArithmeticGate = raw.Config.UseBaseArithmeticGate + commonCircuitData.Config.SecurityBits = raw.Config.SecurityBits + commonCircuitData.Config.NumChallenges = raw.Config.NumChallenges + commonCircuitData.Config.ZeroKnowledge = raw.Config.ZeroKnowledge + commonCircuitData.Config.MaxQuotientDegreeFactor = raw.Config.MaxQuotientDegreeFactor + + commonCircuitData.Config.FriConfig.RateBits = raw.Config.FriConfig.RateBits + commonCircuitData.Config.FriConfig.CapHeight = raw.Config.FriConfig.CapHeight + commonCircuitData.Config.FriConfig.ProofOfWorkBits = raw.Config.FriConfig.ProofOfWorkBits + commonCircuitData.Config.FriConfig.NumQueryRounds = raw.Config.FriConfig.NumQueryRounds + + commonCircuitData.FriParams.DegreeBits = raw.FriParams.DegreeBits + commonCircuitData.DegreeBits = raw.FriParams.DegreeBits + commonCircuitData.FriParams.Config.RateBits = raw.FriParams.Config.RateBits + commonCircuitData.FriParams.Config.CapHeight = raw.FriParams.Config.CapHeight + commonCircuitData.FriParams.Config.ProofOfWorkBits = raw.FriParams.Config.ProofOfWorkBits + commonCircuitData.FriParams.Config.NumQueryRounds = raw.FriParams.Config.NumQueryRounds + commonCircuitData.FriParams.ReductionArityBits = raw.FriParams.ReductionArityBits + + commonCircuitData.GateIds = raw.Gates + + selectorGroupStart := []uint64{} + selectorGroupEnd := []uint64{} + for _, group := range raw.SelectorsInfo.Groups { + selectorGroupStart = append(selectorGroupStart, group.Start) + selectorGroupEnd = append(selectorGroupEnd, group.End) + } + + commonCircuitData.SelectorsInfo = *gates.NewSelectorsInfo( + raw.SelectorsInfo.SelectorIndices, + selectorGroupStart, + selectorGroupEnd, + ) + + commonCircuitData.QuotientDegreeFactor = raw.QuotientDegreeFactor + commonCircuitData.NumGateConstraints = raw.NumGateConstraints + commonCircuitData.NumConstants = raw.NumConstants + commonCircuitData.NumPublicInputs = raw.NumPublicInputs + commonCircuitData.KIs = raw.KIs + commonCircuitData.NumPartialProducts = raw.NumPartialProducts + + return commonCircuitData +} diff --git a/types/common_data_test.go b/types/common_data_test.go new file mode 100644 index 0000000..865a569 --- /dev/null +++ b/types/common_data_test.go @@ -0,0 +1,9 @@ +package types + +import ( + "testing" +) + +func TestDeserializeCommonCircuitData(t *testing.T) { + DeserializeCommonCircuitData("../testdata/decode_block/common_circuit_data.json") +} diff --git a/types/deserialize.go b/types/deserialize.go new file mode 100644 index 0000000..4a8780b --- /dev/null +++ b/types/deserialize.go @@ -0,0 +1,126 @@ +package types + +import ( + "encoding/json" + "io" + "os" +) + +type ProofWithPublicInputsRaw struct { + Proof struct { + WiresCap []string `json:"wires_cap"` + PlonkZsPartialProductsCap []string `json:"plonk_zs_partial_products_cap"` + QuotientPolysCap []string `json:"quotient_polys_cap"` + Openings struct { + Constants [][]uint64 `json:"constants"` + PlonkSigmas [][]uint64 `json:"plonk_sigmas"` + Wires [][]uint64 `json:"wires"` + PlonkZs [][]uint64 `json:"plonk_zs"` + PlonkZsNext [][]uint64 `json:"plonk_zs_next"` + PartialProducts [][]uint64 `json:"partial_products"` + QuotientPolys [][]uint64 `json:"quotient_polys"` + } `json:"openings"` + OpeningProof struct { + CommitPhaseMerkleCaps [][]string `json:"commit_phase_merkle_caps"` + QueryRoundProofs []struct { + InitialTreesProof struct { + EvalsProofs []EvalProofRaw `json:"evals_proofs"` + } `json:"initial_trees_proof"` + Steps []struct { + Evals [][]uint64 `json:"evals"` + MerkleProof struct { + Siblings []string `json:"siblings"` + } `json:"merkle_proof"` + } `json:"steps"` + } `json:"query_round_proofs"` + FinalPoly struct { + Coeffs [][]uint64 `json:"coeffs"` + } `json:"final_poly"` + PowWitness uint64 `json:"pow_witness"` + } `json:"opening_proof"` + } `json:"proof"` + PublicInputs []uint64 `json:"public_inputs"` +} + +type EvalProofRaw struct { + LeafElements []uint64 + MerkleProof MerkleProofRaw +} + +func (e *EvalProofRaw) UnmarshalJSON(data []byte) error { + return json.Unmarshal(data, &[]interface{}{&e.LeafElements, &e.MerkleProof}) +} + +type MerkleProofRaw struct { + Hash []string +} + +func (m *MerkleProofRaw) UnmarshalJSON(data []byte) error { + type SiblingObject struct { + Siblings []string // "siblings" + } + + var siblings SiblingObject + if err := json.Unmarshal(data, &siblings); err != nil { + panic(err) + } + + m.Hash = make([]string, len(siblings.Siblings)) + copy(m.Hash[:], siblings.Siblings) + + return nil +} + +type ProofChallengesRaw struct { + PlonkBetas []uint64 `json:"plonk_betas"` + PlonkGammas []uint64 `json:"plonk_gammas"` + PlonkAlphas []uint64 `json:"plonk_alphas"` + PlonkZeta []uint64 `json:"plonk_zeta"` + FriChallenges struct { + FriAlpha []uint64 `json:"fri_alpha"` + FriBetas [][]uint64 `json:"fri_betas"` + FriPowResponse uint64 `json:"fri_pow_response"` + FriQueryIndices []uint64 `json:"fri_query_indices"` + } `json:"fri_challenges"` +} + +type VerifierOnlyCircuitDataRaw struct { + ConstantsSigmasCap []string `json:"constants_sigmas_cap"` + CircuitDigest string `json:"circuit_digest"` +} + +func ReadProofWithPublicInputs(path string) ProofWithPublicInputsRaw { + jsonFile, err := os.Open(path) + if err != nil { + panic(err) + } + + defer jsonFile.Close() + rawBytes, _ := io.ReadAll(jsonFile) + + var raw ProofWithPublicInputsRaw + err = json.Unmarshal(rawBytes, &raw) + if err != nil { + panic(err) + } + + return raw +} + +func ReadVerifierOnlyCircuitData(path string) VerifierOnlyCircuitDataRaw { + jsonFile, err := os.Open(path) + if err != nil { + panic(err) + } + + defer jsonFile.Close() + rawBytes, _ := io.ReadAll(jsonFile) + + var raw VerifierOnlyCircuitDataRaw + err = json.Unmarshal(rawBytes, &raw) + if err != nil { + panic(err) + } + + return raw +} diff --git a/types/deserialize_test.go b/types/deserialize_test.go new file mode 100644 index 0000000..236987e --- /dev/null +++ b/types/deserialize_test.go @@ -0,0 +1,13 @@ +package types + +import ( + "testing" +) + +func TestReadProofWithPublicInputs(t *testing.T) { + ReadProofWithPublicInputs("../testdata/decode_block/proof_with_public_inputs.json") +} + +func TestReadVerifierOnlyCircuitData(t *testing.T) { + ReadVerifierOnlyCircuitData("../testdata/decode_block/verifier_only_circuit_data.json") +} diff --git a/types/types.go b/types/types.go index c9b744f..c206e1b 100644 --- a/types/types.go +++ b/types/types.go @@ -1,5 +1,7 @@ package types +import "github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" + type FriConfig struct { RateBits uint64 CapHeight uint64 @@ -18,3 +20,29 @@ type FriParams struct { DegreeBits uint64 ReductionArityBits []uint64 } + +type CircuitConfig struct { + NumWires uint64 + NumRoutedWires uint64 + NumConstants uint64 + UseBaseArithmeticGate bool + SecurityBits uint64 + NumChallenges uint64 + ZeroKnowledge bool + MaxQuotientDegreeFactor uint64 + FriConfig FriConfig +} + +type CommonCircuitData struct { + Config CircuitConfig + FriParams + GateIds []string + SelectorsInfo gates.SelectorsInfo + DegreeBits uint64 + QuotientDegreeFactor uint64 + NumGateConstraints uint64 + NumConstants uint64 + NumPublicInputs uint64 + KIs []uint64 + NumPartialProducts uint64 +} diff --git a/types/utils.go b/types/utils.go new file mode 100644 index 0000000..e7bcae5 --- /dev/null +++ b/types/utils.go @@ -0,0 +1,21 @@ +package types + +func ReductionArityBits( + arityBits uint64, + finalPolyBits uint64, + degreeBits uint64, + rateBits uint64, + capHeight uint64, +) []uint64 { + returnArr := make([]uint64, 0) + + for degreeBits > finalPolyBits && degreeBits+rateBits-arityBits >= capHeight { + returnArr = append(returnArr, arityBits) + if degreeBits < arityBits { + panic("degreeBits < arityBits") + } + degreeBits -= arityBits + } + + return returnArr +} diff --git a/variables/circuit.go b/variables/circuit.go index fe73b22..829d362 100644 --- a/variables/circuit.go +++ b/variables/circuit.go @@ -2,9 +2,7 @@ package variables import ( gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" - "github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" - "github.com/succinctlabs/gnark-plonky2-verifier/types" ) type Proof struct { @@ -24,29 +22,3 @@ type VerifierOnlyCircuitData struct { ConstantSigmasCap FriMerkleCap CircuitDigest poseidon.BN254HashOut } - -type CircuitConfig struct { - NumWires uint64 - NumRoutedWires uint64 - NumConstants uint64 - UseBaseArithmeticGate bool - SecurityBits uint64 - NumChallenges uint64 - ZeroKnowledge bool - MaxQuotientDegreeFactor uint64 - FriConfig types.FriConfig -} - -type CommonCircuitData struct { - Config CircuitConfig - FriParams types.FriParams - Gates []gates.Gate - SelectorsInfo gates.SelectorsInfo - DegreeBits uint64 - QuotientDegreeFactor uint64 - NumGateConstraints uint64 - NumConstants uint64 - NumPublicInputs uint64 - KIs []gl.Variable - NumPartialProducts uint64 -} diff --git a/variables/deserialize.go b/variables/deserialize.go new file mode 100644 index 0000000..33acaf3 --- /dev/null +++ b/variables/deserialize.go @@ -0,0 +1,156 @@ +package variables + +import ( + "math/big" + + "github.com/consensys/gnark/frontend" + gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" + "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" + "github.com/succinctlabs/gnark-plonky2-verifier/types" +) + +func DeserializeMerkleCap(merkleCapRaw []string) FriMerkleCap { + n := len(merkleCapRaw) + merkleCap := make([]poseidon.BN254HashOut, n) + for i := 0; i < n; i++ { + capBigInt, _ := new(big.Int).SetString(merkleCapRaw[i], 10) + merkleCap[i] = frontend.Variable(capBigInt) + } + return merkleCap +} + +func DeserializeMerkleProof(merkleProofRaw struct{ Siblings []interface{} }) FriMerkleProof { + n := len(merkleProofRaw.Siblings) + var mp FriMerkleProof + mp.Siblings = make([]poseidon.BN254HashOut, n) + for i := 0; i < n; i++ { + element := merkleProofRaw.Siblings[i].(struct{ Elements []uint64 }) + mp.Siblings[i] = gl.Uint64ArrayToVariableArray(element.Elements) + } + return mp +} + +func DeserializeOpeningSet(openingSetRaw struct { + Constants [][]uint64 + PlonkSigmas [][]uint64 + Wires [][]uint64 + PlonkZs [][]uint64 + PlonkZsNext [][]uint64 + PartialProducts [][]uint64 + QuotientPolys [][]uint64 +}) OpeningSet { + return OpeningSet{ + Constants: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Constants), + PlonkSigmas: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkSigmas), + Wires: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Wires), + PlonkZs: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZs), + PlonkZsNext: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZsNext), + PartialProducts: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PartialProducts), + QuotientPolys: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.QuotientPolys), + } +} + +func StringArrayToHashBN254Array(rawHashes []string) []poseidon.BN254HashOut { + hashes := []poseidon.BN254HashOut{} + + for i := 0; i < len(rawHashes); i++ { + hashBigInt, _ := new(big.Int).SetString(rawHashes[i], 10) + hashVar := frontend.Variable(hashBigInt) + hashes = append(hashes, poseidon.BN254HashOut(hashVar)) + } + + return hashes +} + +func DeserializeFriProof(openingProofRaw struct { + CommitPhaseMerkleCaps [][]string + QueryRoundProofs []struct { + InitialTreesProof struct { + EvalsProofs []types.EvalProofRaw + } + Steps []struct { + Evals [][]uint64 + MerkleProof struct { + Siblings []string + } + } + } + FinalPoly struct { + Coeffs [][]uint64 + } + PowWitness uint64 +}) FriProof { + var openingProof FriProof + openingProof.PowWitness = gl.NewVariable(openingProofRaw.PowWitness) + openingProof.FinalPoly.Coeffs = gl.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs) + + openingProof.CommitPhaseMerkleCaps = make([]FriMerkleCap, len(openingProofRaw.CommitPhaseMerkleCaps)) + for i := 0; i < len(openingProofRaw.CommitPhaseMerkleCaps); i++ { + openingProof.CommitPhaseMerkleCaps[i] = StringArrayToHashBN254Array(openingProofRaw.CommitPhaseMerkleCaps[i]) + } + + numQueryRoundProofs := len(openingProofRaw.QueryRoundProofs) + openingProof.QueryRoundProofs = make([]FriQueryRound, numQueryRoundProofs) + + for i := 0; i < numQueryRoundProofs; i++ { + numEvalProofs := len(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs) + openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs = make([]FriEvalProof, numEvalProofs) + for j := 0; j < numEvalProofs; j++ { + openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].Elements = gl.Uint64ArrayToVariableArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].LeafElements) + openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Siblings = StringArrayToHashBN254Array(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Hash) + } + + numSteps := len(openingProofRaw.QueryRoundProofs[i].Steps) + openingProof.QueryRoundProofs[i].Steps = make([]FriQueryStep, numSteps) + for j := 0; j < numSteps; j++ { + openingProof.QueryRoundProofs[i].Steps[j].Evals = gl.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.QueryRoundProofs[i].Steps[j].Evals) + openingProof.QueryRoundProofs[i].Steps[j].MerkleProof.Siblings = StringArrayToHashBN254Array(openingProofRaw.QueryRoundProofs[i].Steps[j].MerkleProof.Siblings) + } + } + + return openingProof +} + +func DeserializeProofWithPublicInputs(raw types.ProofWithPublicInputsRaw) ProofWithPublicInputs { + var proofWithPis ProofWithPublicInputs + proofWithPis.Proof.WiresCap = DeserializeMerkleCap(raw.Proof.WiresCap) + proofWithPis.Proof.PlonkZsPartialProductsCap = DeserializeMerkleCap(raw.Proof.PlonkZsPartialProductsCap) + proofWithPis.Proof.QuotientPolysCap = DeserializeMerkleCap(raw.Proof.QuotientPolysCap) + proofWithPis.Proof.Openings = DeserializeOpeningSet(struct { + Constants [][]uint64 + PlonkSigmas [][]uint64 + Wires [][]uint64 + PlonkZs [][]uint64 + PlonkZsNext [][]uint64 + PartialProducts [][]uint64 + QuotientPolys [][]uint64 + }(raw.Proof.Openings)) + proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct { + CommitPhaseMerkleCaps [][]string + QueryRoundProofs []struct { + InitialTreesProof struct { + EvalsProofs []types.EvalProofRaw + } + Steps []struct { + Evals [][]uint64 + MerkleProof struct { + Siblings []string + } + } + } + FinalPoly struct{ Coeffs [][]uint64 } + PowWitness uint64 + }(raw.Proof.OpeningProof)) + proofWithPis.PublicInputs = gl.Uint64ArrayToVariableArray(raw.PublicInputs) + + return proofWithPis +} + +func DeserializeVerifierOnlyCircuitData(raw types.VerifierOnlyCircuitDataRaw) VerifierOnlyCircuitData { + var verifierOnlyCircuitData VerifierOnlyCircuitData + verifierOnlyCircuitData.ConstantSigmasCap = DeserializeMerkleCap(raw.ConstantsSigmasCap) + circuitDigestBigInt, _ := new(big.Int).SetString(raw.CircuitDigest, 10) + circuitDigestVar := frontend.Variable(circuitDigestBigInt) + verifierOnlyCircuitData.CircuitDigest = poseidon.BN254HashOut(circuitDigestVar) + return verifierOnlyCircuitData +} diff --git a/variables/deserialize_test.go b/variables/deserialize_test.go new file mode 100644 index 0000000..a1d9017 --- /dev/null +++ b/variables/deserialize_test.go @@ -0,0 +1,17 @@ +package variables + +import ( + "testing" + + "github.com/succinctlabs/gnark-plonky2-verifier/types" +) + +func TestDeserializeProofWithPublicInputs(t *testing.T) { + proofWithPis := DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs("../testdata/decode_block/proof_with_public_inputs.json")) + t.Logf("%+v\n", proofWithPis) +} + +func TestDeserializeVerifierOnlyCircuitData(t *testing.T) { + verifierOnlyCircuitData := DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData("../testdata/decode_block/verifier_only_circuit_data.json")) + t.Logf("%+v\n", verifierOnlyCircuitData) +} diff --git a/verifier/deserialize.go b/verifier/deserialize.go deleted file mode 100644 index 7bdd8d2..0000000 --- a/verifier/deserialize.go +++ /dev/null @@ -1,436 +0,0 @@ -package verifier - -import ( - "encoding/json" - "io" - "math/big" - "os" - - "github.com/consensys/gnark/frontend" - gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" - "github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" - "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" - "github.com/succinctlabs/gnark-plonky2-verifier/variables" -) - -type ProofWithPublicInputsRaw struct { - Proof struct { - WiresCap []string `json:"wires_cap"` - PlonkZsPartialProductsCap []string `json:"plonk_zs_partial_products_cap"` - QuotientPolysCap []string `json:"quotient_polys_cap"` - Openings struct { - Constants [][]uint64 `json:"constants"` - PlonkSigmas [][]uint64 `json:"plonk_sigmas"` - Wires [][]uint64 `json:"wires"` - PlonkZs [][]uint64 `json:"plonk_zs"` - PlonkZsNext [][]uint64 `json:"plonk_zs_next"` - PartialProducts [][]uint64 `json:"partial_products"` - QuotientPolys [][]uint64 `json:"quotient_polys"` - } `json:"openings"` - OpeningProof struct { - CommitPhaseMerkleCaps [][]string `json:"commit_phase_merkle_caps"` - QueryRoundProofs []struct { - InitialTreesProof struct { - EvalsProofs []EvalProofRaw `json:"evals_proofs"` - } `json:"initial_trees_proof"` - Steps []struct { - Evals [][]uint64 `json:"evals"` - MerkleProof struct { - Siblings []string `json:"siblings"` - } `json:"merkle_proof"` - } `json:"steps"` - } `json:"query_round_proofs"` - FinalPoly struct { - Coeffs [][]uint64 `json:"coeffs"` - } `json:"final_poly"` - PowWitness uint64 `json:"pow_witness"` - } `json:"opening_proof"` - } `json:"proof"` - PublicInputs []uint64 `json:"public_inputs"` -} - -type EvalProofRaw struct { - LeafElements []uint64 - MerkleProof MerkleProofRaw -} - -func (e *EvalProofRaw) UnmarshalJSON(data []byte) error { - return json.Unmarshal(data, &[]interface{}{&e.LeafElements, &e.MerkleProof}) -} - -type MerkleProofRaw struct { - Hash []string -} - -func (m *MerkleProofRaw) UnmarshalJSON(data []byte) error { - type SiblingObject struct { - Siblings []string // "siblings" - } - - var siblings SiblingObject - if err := json.Unmarshal(data, &siblings); err != nil { - panic(err) - } - - m.Hash = make([]string, len(siblings.Siblings)) - copy(m.Hash[:], siblings.Siblings) - - return nil -} - -type CommonCircuitDataRaw struct { - Config struct { - NumWires uint64 `json:"num_wires"` - NumRoutedWires uint64 `json:"num_routed_wires"` - NumConstants uint64 `json:"num_constants"` - UseBaseArithmeticGate bool `json:"use_base_arithmetic_gate"` - SecurityBits uint64 `json:"security_bits"` - NumChallenges uint64 `json:"num_challenges"` - ZeroKnowledge bool `json:"zero_knowledge"` - MaxQuotientDegreeFactor uint64 `json:"max_quotient_degree_factor"` - FriConfig struct { - RateBits uint64 `json:"rate_bits"` - CapHeight uint64 `json:"cap_height"` - ProofOfWorkBits uint64 `json:"proof_of_work_bits"` - ReductionStrategy struct { - ConstantArityBits []uint64 `json:"ConstantArityBits"` - } `json:"reduction_strategy"` - NumQueryRounds uint64 `json:"num_query_rounds"` - } `json:"fri_config"` - } `json:"config"` - FriParams struct { - Config struct { - RateBits uint64 `json:"rate_bits"` - CapHeight uint64 `json:"cap_height"` - ProofOfWorkBits uint64 `json:"proof_of_work_bits"` - ReductionStrategy struct { - ConstantArityBits []uint64 `json:"ConstantArityBits"` - } `json:"reduction_strategy"` - NumQueryRounds uint64 `json:"num_query_rounds"` - } `json:"config"` - Hiding bool `json:"hiding"` - DegreeBits uint64 `json:"degree_bits"` - ReductionArityBits []uint64 `json:"reduction_arity_bits"` - } `json:"fri_params"` - Gates []string `json:"gates"` - SelectorsInfo struct { - SelectorIndices []uint64 `json:"selector_indices"` - Groups []struct { - Start uint64 `json:"start"` - End uint64 `json:"end"` - } `json:"groups"` - } `json:"selectors_info"` - QuotientDegreeFactor uint64 `json:"quotient_degree_factor"` - NumGateConstraints uint64 `json:"num_gate_constraints"` - NumConstants uint64 `json:"num_constants"` - NumPublicInputs uint64 `json:"num_public_inputs"` - KIs []uint64 `json:"k_is"` - NumPartialProducts uint64 `json:"num_partial_products"` -} - -type ProofChallengesRaw struct { - PlonkBetas []uint64 `json:"plonk_betas"` - PlonkGammas []uint64 `json:"plonk_gammas"` - PlonkAlphas []uint64 `json:"plonk_alphas"` - PlonkZeta []uint64 `json:"plonk_zeta"` - FriChallenges struct { - FriAlpha []uint64 `json:"fri_alpha"` - FriBetas [][]uint64 `json:"fri_betas"` - FriPowResponse uint64 `json:"fri_pow_response"` - FriQueryIndices []uint64 `json:"fri_query_indices"` - } `json:"fri_challenges"` -} - -type VerifierOnlyCircuitDataRaw struct { - ConstantsSigmasCap []string `json:"constants_sigmas_cap"` - CircuitDigest string `json:"circuit_digest"` -} - -func DeserializeMerkleCap(merkleCapRaw []string) variables.FriMerkleCap { - n := len(merkleCapRaw) - merkleCap := make([]poseidon.BN254HashOut, n) - for i := 0; i < n; i++ { - capBigInt, _ := new(big.Int).SetString(merkleCapRaw[i], 10) - merkleCap[i] = frontend.Variable(capBigInt) - } - return merkleCap -} - -func DeserializeMerkleProof(merkleProofRaw struct{ Siblings []interface{} }) variables.FriMerkleProof { - n := len(merkleProofRaw.Siblings) - var mp variables.FriMerkleProof - mp.Siblings = make([]poseidon.BN254HashOut, n) - for i := 0; i < n; i++ { - element := merkleProofRaw.Siblings[i].(struct{ Elements []uint64 }) - mp.Siblings[i] = gl.Uint64ArrayToVariableArray(element.Elements) - } - return mp -} - -func DeserializeOpeningSet(openingSetRaw struct { - Constants [][]uint64 - PlonkSigmas [][]uint64 - Wires [][]uint64 - PlonkZs [][]uint64 - PlonkZsNext [][]uint64 - PartialProducts [][]uint64 - QuotientPolys [][]uint64 -}) variables.OpeningSet { - return variables.OpeningSet{ - Constants: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Constants), - PlonkSigmas: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkSigmas), - Wires: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Wires), - PlonkZs: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZs), - PlonkZsNext: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZsNext), - PartialProducts: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PartialProducts), - QuotientPolys: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.QuotientPolys), - } -} - -func StringArrayToHashBN254Array(rawHashes []string) []poseidon.BN254HashOut { - hashes := []poseidon.BN254HashOut{} - - for i := 0; i < len(rawHashes); i++ { - hashBigInt, _ := new(big.Int).SetString(rawHashes[i], 10) - hashVar := frontend.Variable(hashBigInt) - hashes = append(hashes, poseidon.BN254HashOut(hashVar)) - } - - return hashes -} - -func DeserializeFriProof(openingProofRaw struct { - CommitPhaseMerkleCaps [][]string - QueryRoundProofs []struct { - InitialTreesProof struct { - EvalsProofs []EvalProofRaw - } - Steps []struct { - Evals [][]uint64 - MerkleProof struct { - Siblings []string - } - } - } - FinalPoly struct { - Coeffs [][]uint64 - } - PowWitness uint64 -}) variables.FriProof { - var openingProof variables.FriProof - openingProof.PowWitness = gl.NewVariable(openingProofRaw.PowWitness) - openingProof.FinalPoly.Coeffs = gl.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs) - - openingProof.CommitPhaseMerkleCaps = make([]variables.FriMerkleCap, len(openingProofRaw.CommitPhaseMerkleCaps)) - for i := 0; i < len(openingProofRaw.CommitPhaseMerkleCaps); i++ { - openingProof.CommitPhaseMerkleCaps[i] = StringArrayToHashBN254Array(openingProofRaw.CommitPhaseMerkleCaps[i]) - } - - numQueryRoundProofs := len(openingProofRaw.QueryRoundProofs) - openingProof.QueryRoundProofs = make([]variables.FriQueryRound, numQueryRoundProofs) - - for i := 0; i < numQueryRoundProofs; i++ { - numEvalProofs := len(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs) - openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs = make([]variables.FriEvalProof, numEvalProofs) - for j := 0; j < numEvalProofs; j++ { - openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].Elements = gl.Uint64ArrayToVariableArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].LeafElements) - openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Siblings = StringArrayToHashBN254Array(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Hash) - } - - numSteps := len(openingProofRaw.QueryRoundProofs[i].Steps) - openingProof.QueryRoundProofs[i].Steps = make([]variables.FriQueryStep, numSteps) - for j := 0; j < numSteps; j++ { - openingProof.QueryRoundProofs[i].Steps[j].Evals = gl.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.QueryRoundProofs[i].Steps[j].Evals) - openingProof.QueryRoundProofs[i].Steps[j].MerkleProof.Siblings = StringArrayToHashBN254Array(openingProofRaw.QueryRoundProofs[i].Steps[j].MerkleProof.Siblings) - } - } - - return openingProof -} - -func DeserializeProofWithPublicInputs(path string) variables.ProofWithPublicInputs { - jsonFile, err := os.Open(path) - if err != nil { - panic(err) - } - - defer jsonFile.Close() - rawBytes, _ := io.ReadAll(jsonFile) - - var raw ProofWithPublicInputsRaw - err = json.Unmarshal(rawBytes, &raw) - if err != nil { - panic(err) - } - - var proofWithPis variables.ProofWithPublicInputs - proofWithPis.Proof.WiresCap = DeserializeMerkleCap(raw.Proof.WiresCap) - proofWithPis.Proof.PlonkZsPartialProductsCap = DeserializeMerkleCap(raw.Proof.PlonkZsPartialProductsCap) - proofWithPis.Proof.QuotientPolysCap = DeserializeMerkleCap(raw.Proof.QuotientPolysCap) - proofWithPis.Proof.Openings = DeserializeOpeningSet(struct { - Constants [][]uint64 - PlonkSigmas [][]uint64 - Wires [][]uint64 - PlonkZs [][]uint64 - PlonkZsNext [][]uint64 - PartialProducts [][]uint64 - QuotientPolys [][]uint64 - }(raw.Proof.Openings)) - proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct { - CommitPhaseMerkleCaps [][]string - QueryRoundProofs []struct { - InitialTreesProof struct { - EvalsProofs []EvalProofRaw - } - Steps []struct { - Evals [][]uint64 - MerkleProof struct { - Siblings []string - } - } - } - FinalPoly struct{ Coeffs [][]uint64 } - PowWitness uint64 - }(raw.Proof.OpeningProof)) - proofWithPis.PublicInputs = gl.Uint64ArrayToVariableArray(raw.PublicInputs) - - return proofWithPis -} - -// TODO: this seemed unused? -// func DeserializeProofChallenges(path string) variables.ProofChallenges { -// jsonFile, err := os.Open(path) -// if err != nil { -// panic(err) -// } - -// defer jsonFile.Close() -// rawBytes, _ := io.ReadAll(jsonFile) - -// var raw ProofChallengesRaw -// err = json.Unmarshal(rawBytes, &raw) -// if err != nil { -// panic(err) -// } - -// var proofChallenges variables.ProofChallenges -// proofChallenges.PlonkBetas = gl.Uint64ArrayToVariableArray(raw.PlonkBetas) -// proofChallenges.PlonkGammas = gl.Uint64ArrayToVariableArray(raw.PlonkGammas) -// proofChallenges.PlonkAlphas = gl.Uint64ArrayToVariableArray(raw.PlonkAlphas) -// proofChallenges.PlonkZeta = gl.Uint64ArrayToQuadraticExtension(raw.PlonkZeta) -// proofChallenges.FriChallenges.FriAlpha = gl.Uint64ArrayToQuadraticExtension(raw.FriChallenges.FriAlpha) -// proofChallenges.FriChallenges.FriBetas = gl.Uint64ArrayToQuadraticExtensionArray(raw.FriChallenges.FriBetas) -// proofChallenges.FriChallenges.FriPowResponse = gl.NewVariable(raw.FriChallenges.FriPowResponse) -// proofChallenges.FriChallenges.FriQueryIndices = gl.Uint64ArrayToVariableArray(raw.FriChallenges.FriQueryIndices) - -// return proofChallenges -// } - -func ReductionArityBits( - arityBits uint64, - finalPolyBits uint64, - degreeBits uint64, - rateBits uint64, - capHeight uint64, -) []uint64 { - returnArr := make([]uint64, 0) - - for degreeBits > finalPolyBits && degreeBits+rateBits-arityBits >= capHeight { - returnArr = append(returnArr, arityBits) - if degreeBits < arityBits { - panic("degreeBits < arityBits") - } - degreeBits -= arityBits - } - - return returnArr -} - -func DeserializeCommonCircuitData(path string) variables.CommonCircuitData { - jsonFile, err := os.Open(path) - if err != nil { - panic(err) - } - - defer jsonFile.Close() - rawBytes, _ := io.ReadAll(jsonFile) - - var raw CommonCircuitDataRaw - err = json.Unmarshal(rawBytes, &raw) - if err != nil { - panic(err) - } - - var commonCircuitData variables.CommonCircuitData - commonCircuitData.Config.NumWires = raw.Config.NumWires - commonCircuitData.Config.NumRoutedWires = raw.Config.NumRoutedWires - commonCircuitData.Config.NumConstants = raw.Config.NumConstants - commonCircuitData.Config.UseBaseArithmeticGate = raw.Config.UseBaseArithmeticGate - commonCircuitData.Config.SecurityBits = raw.Config.SecurityBits - commonCircuitData.Config.NumChallenges = raw.Config.NumChallenges - commonCircuitData.Config.ZeroKnowledge = raw.Config.ZeroKnowledge - commonCircuitData.Config.MaxQuotientDegreeFactor = raw.Config.MaxQuotientDegreeFactor - - commonCircuitData.Config.FriConfig.RateBits = raw.Config.FriConfig.RateBits - commonCircuitData.Config.FriConfig.CapHeight = raw.Config.FriConfig.CapHeight - commonCircuitData.Config.FriConfig.ProofOfWorkBits = raw.Config.FriConfig.ProofOfWorkBits - commonCircuitData.Config.FriConfig.NumQueryRounds = raw.Config.FriConfig.NumQueryRounds - - commonCircuitData.FriParams.DegreeBits = raw.FriParams.DegreeBits - commonCircuitData.DegreeBits = raw.FriParams.DegreeBits - commonCircuitData.FriParams.Config.RateBits = raw.FriParams.Config.RateBits - commonCircuitData.FriParams.Config.CapHeight = raw.FriParams.Config.CapHeight - commonCircuitData.FriParams.Config.ProofOfWorkBits = raw.FriParams.Config.ProofOfWorkBits - commonCircuitData.FriParams.Config.NumQueryRounds = raw.FriParams.Config.NumQueryRounds - commonCircuitData.FriParams.ReductionArityBits = raw.FriParams.ReductionArityBits - - commonCircuitData.Gates = []gates.Gate{} - for _, gate := range raw.Gates { - commonCircuitData.Gates = append(commonCircuitData.Gates, gates.GateInstanceFromId(gate)) - } - - selectorGroupStart := []uint64{} - selectorGroupEnd := []uint64{} - for _, group := range raw.SelectorsInfo.Groups { - selectorGroupStart = append(selectorGroupStart, group.Start) - selectorGroupEnd = append(selectorGroupEnd, group.End) - } - - commonCircuitData.SelectorsInfo = *gates.NewSelectorsInfo( - raw.SelectorsInfo.SelectorIndices, - selectorGroupStart, - selectorGroupEnd, - ) - - commonCircuitData.QuotientDegreeFactor = raw.QuotientDegreeFactor - commonCircuitData.NumGateConstraints = raw.NumGateConstraints - commonCircuitData.NumConstants = raw.NumConstants - commonCircuitData.NumPublicInputs = raw.NumPublicInputs - commonCircuitData.KIs = gl.Uint64ArrayToVariableArray(raw.KIs) - commonCircuitData.NumPartialProducts = raw.NumPartialProducts - - return commonCircuitData -} - -func DeserializeVerifierOnlyCircuitData(path string) variables.VerifierOnlyCircuitData { - jsonFile, err := os.Open(path) - if err != nil { - panic(err) - } - - defer jsonFile.Close() - rawBytes, _ := io.ReadAll(jsonFile) - - var raw VerifierOnlyCircuitDataRaw - err = json.Unmarshal(rawBytes, &raw) - if err != nil { - panic(err) - } - - var verifierOnlyCircuitData variables.VerifierOnlyCircuitData - verifierOnlyCircuitData.ConstantSigmasCap = DeserializeMerkleCap(raw.ConstantsSigmasCap) - circuitDigestBigInt, _ := new(big.Int).SetString(raw.CircuitDigest, 10) - circuitDigestVar := frontend.Variable(circuitDigestBigInt) - verifierOnlyCircuitData.CircuitDigest = poseidon.BN254HashOut(circuitDigestVar) - return verifierOnlyCircuitData -} diff --git a/verifier/deserialize_test.go b/verifier/deserialize_test.go deleted file mode 100644 index 0151764..0000000 --- a/verifier/deserialize_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package verifier - -import ( - "fmt" - "testing" -) - -func TestDeserializeProofWithPublicInputs(t *testing.T) { - proofWithPis := DeserializeProofWithPublicInputs("../data/decode_block/proof_with_public_inputs.json") - fmt.Printf("%+v\n", proofWithPis) - panic("look at stdout") -} - -func TestDeserializeCommonCircuitData(t *testing.T) { - commonCircuitData := DeserializeCommonCircuitData("../data/decode_block/common_circuit_data.json") - fmt.Printf("%+v\n", commonCircuitData) - panic("look at stdout") -} - -func TestDeserializeVerifierOnlyCircuitData(t *testing.T) { - verifierOnlyCircuitData := DeserializeVerifierOnlyCircuitData("../data/decode_block/verifier_only_circuit_data.json") - fmt.Printf("%+v\n", verifierOnlyCircuitData) - panic("look at stdout") -} diff --git a/verifier/util.go b/verifier/util.go new file mode 100644 index 0000000..6449189 --- /dev/null +++ b/verifier/util.go @@ -0,0 +1,24 @@ +package verifier + +import ( + "github.com/consensys/gnark/frontend" + gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" + "github.com/succinctlabs/gnark-plonky2-verifier/types" + "github.com/succinctlabs/gnark-plonky2-verifier/variables" +) + +type ExampleVerifierCircuit struct { + PublicInputs []gl.Variable `gnark:",public"` + Proof variables.Proof + VerifierOnlyCircuitData variables.VerifierOnlyCircuitData + + // This is configuration for the circuit, it is a constant not a variable + CommonCircuitData types.CommonCircuitData +} + +func (c *ExampleVerifierCircuit) Define(api frontend.API) error { + verifierChip := NewVerifierChip(api, c.CommonCircuitData) + verifierChip.Verify(c.Proof, c.PublicInputs, c.VerifierOnlyCircuitData) + + return nil +} diff --git a/verifier/verifier.go b/verifier/verifier.go index 0ff36ba..2ec08e5 100644 --- a/verifier/verifier.go +++ b/verifier/verifier.go @@ -7,6 +7,7 @@ import ( gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" "github.com/succinctlabs/gnark-plonky2-verifier/plonk" "github.com/succinctlabs/gnark-plonky2-verifier/poseidon" + "github.com/succinctlabs/gnark-plonky2-verifier/types" "github.com/succinctlabs/gnark-plonky2-verifier/variables" ) @@ -17,11 +18,12 @@ type VerifierChip struct { poseidonBN254Chip *poseidon.BN254Chip `gnark:"-"` plonkChip *plonk.PlonkChip `gnark:"-"` friChip *fri.Chip `gnark:"-"` + commonData types.CommonCircuitData `gnark:"-"` } -func NewVerifierChip(api frontend.API, commonCircuitData variables.CommonCircuitData) *VerifierChip { +func NewVerifierChip(api frontend.API, commonCircuitData types.CommonCircuitData) *VerifierChip { glChip := gl.New(api) - friChip := fri.NewChip(api, &commonCircuitData.FriParams) + friChip := fri.NewChip(api, &commonCircuitData, &commonCircuitData.FriParams) plonkChip := plonk.NewPlonkChip(api, commonCircuitData) poseidonGlChip := poseidon.NewGoldilocksChip(api) poseidonBN254Chip := poseidon.NewBN254Chip(api) @@ -32,6 +34,7 @@ func NewVerifierChip(api frontend.API, commonCircuitData variables.CommonCircuit poseidonBN254Chip: poseidonBN254Chip, plonkChip: plonkChip, friChip: friChip, + commonData: commonCircuitData, } } @@ -42,10 +45,9 @@ func (c *VerifierChip) GetPublicInputsHash(publicInputs []gl.Variable) poseidon. func (c *VerifierChip) GetChallenges( proof variables.Proof, publicInputsHash poseidon.GoldilocksHashOut, - commonData variables.CommonCircuitData, verifierData variables.VerifierOnlyCircuitData, ) variables.ProofChallenges { - config := commonData.Config + config := c.commonData.Config numChallenges := config.NumChallenges challenger := challenger.NewChip(c.api) @@ -63,7 +65,7 @@ func (c *VerifierChip) GetChallenges( challenger.ObserveCap(proof.QuotientPolysCap) plonkZeta := challenger.GetExtensionChallenge() - challenger.ObserveOpenings(fri.ToOpenings(proof.Openings)) + challenger.ObserveOpenings(c.friChip.ToOpenings(proof.Openings)) return variables.ProofChallenges{ PlonkBetas: plonkBetas, @@ -74,7 +76,7 @@ func (c *VerifierChip) GetChallenges( proof.OpeningProof.CommitPhaseMerkleCaps, proof.OpeningProof.FinalPoly, proof.OpeningProof.PowWitness, - commonData.DegreeBits, + c.commonData.DegreeBits, config.FriConfig, ), } @@ -141,13 +143,12 @@ func (c *VerifierChip) Verify( proof variables.Proof, publicInputs []gl.Variable, verifierData variables.VerifierOnlyCircuitData, - commonData variables.CommonCircuitData, ) { c.rangeCheckProof(proof) // Generate the parts of the witness that is for the plonky2 proof input publicInputsHash := c.GetPublicInputsHash(publicInputs) - proofChallenges := c.GetChallenges(proof, publicInputsHash, commonData, verifierData) + proofChallenges := c.GetChallenges(proof, publicInputsHash, verifierData) c.plonkChip.Verify(proofChallenges, proof.Openings, publicInputsHash) @@ -159,8 +160,8 @@ func (c *VerifierChip) Verify( } c.friChip.VerifyFriProof( - fri.GetInstance(&commonData, c.glChip, proofChallenges.PlonkZeta, commonData.DegreeBits), - fri.ToOpenings(proof.Openings), + c.friChip.GetInstance(proofChallenges.PlonkZeta), + c.friChip.ToOpenings(proof.Openings), &proofChallenges.FriChallenges, initialMerkleCaps, &proof.OpeningProof, diff --git a/verifier/verifier_test.go b/verifier/verifier_test.go index aa3ac11..901dcd5 100644 --- a/verifier/verifier_test.go +++ b/verifier/verifier_test.go @@ -4,52 +4,34 @@ import ( "testing" "github.com/consensys/gnark-crypto/ecc" - "github.com/consensys/gnark/backend" - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/std/math/emulated" "github.com/consensys/gnark/test" - gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" + "github.com/succinctlabs/gnark-plonky2-verifier/types" "github.com/succinctlabs/gnark-plonky2-verifier/variables" "github.com/succinctlabs/gnark-plonky2-verifier/verifier" ) -type TestVerifierCircuit struct { - Proof variables.Proof - PublicInputs []gl.Variable `gnark:",public"` - - verifierChip *verifier.VerifierChip `gnark:"-"` - plonky2CircuitName string `gnark:"-"` -} - -func (c *TestVerifierCircuit) Define(api frontend.API) error { - circuitDirname := "./data/" + c.plonky2CircuitName + "/" - commonCircuitData := verifier.DeserializeCommonCircuitData(circuitDirname + "common_circuit_data.json") - verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuitDirname + "verifier_only_circuit_data.json") - - c.verifierChip = verifier.NewVerifierChip(api, commonCircuitData) - - c.verifierChip.Verify(c.Proof, c.PublicInputs, verifierOnlyCircuitData, commonCircuitData) - - return nil -} - func TestStepVerifier(t *testing.T) { assert := test.NewAssert(t) testCase := func() { plonky2Circuit := "step" - proofWithPis := verifier.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json") - circuit := TestVerifierCircuit{ - plonky2CircuitName: plonky2Circuit, - Proof: proofWithPis.Proof, - PublicInputs: proofWithPis.PublicInputs, + commonCircuitData := types.DeserializeCommonCircuitData("../testdata/" + plonky2Circuit + "/common_circuit_data.json") + + proofWithPis := variables.DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs("../testdata/" + plonky2Circuit + "/proof_with_public_inputs.json")) + verifierOnlyCircuitData := variables.DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData("../testdata/" + plonky2Circuit + "/verifier_only_circuit_data.json")) + + circuit := verifier.ExampleVerifierCircuit{ + Proof: proofWithPis.Proof, + PublicInputs: proofWithPis.PublicInputs, + VerifierOnlyCircuitData: verifierOnlyCircuitData, + CommonCircuitData: commonCircuitData, } - proofWithPis2 := verifier.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json") - witness := TestVerifierCircuit{ - plonky2CircuitName: plonky2Circuit, - Proof: proofWithPis2.Proof, - PublicInputs: proofWithPis2.PublicInputs, + witness := verifier.ExampleVerifierCircuit{ + Proof: proofWithPis.Proof, + PublicInputs: proofWithPis.PublicInputs, + VerifierOnlyCircuitData: verifierOnlyCircuitData, + CommonCircuitData: commonCircuitData, } err := test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField()) @@ -57,66 +39,3 @@ func TestStepVerifier(t *testing.T) { } testCase() } - -func TestStepVerifier2(t *testing.T) { - assert := test.NewAssert(t) - - plonky2Circuit := "step" - proofWithPis := verifier.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json") - circuit := TestVerifierCircuit{ - plonky2CircuitName: plonky2Circuit, - Proof: proofWithPis.Proof, - PublicInputs: proofWithPis.PublicInputs, - } - - proofWithPis2 := verifier.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json") - witness := TestVerifierCircuit{ - plonky2CircuitName: plonky2Circuit, - Proof: proofWithPis2.Proof, - PublicInputs: proofWithPis2.PublicInputs, - } - - assert.ProverSucceeded( - &circuit, - &witness, - test.WithBackends(backend.GROTH16), - test.WithCurves(ecc.BN254), - test.NoFuzzing(), - test.NoSerializationChecks(), - ) -} - -type testCircuit struct { - Arr [2]emulated.Element[emulated.Secp256k1Fp] - Expected emulated.Element[emulated.Secp256k1Fp] -} - -func (circuit *testCircuit) Define(api frontend.API) error { - field, _ := emulated.NewField[emulated.Secp256k1Fp](api) - - mulRes := field.Mul(&circuit.Arr[0], &circuit.Arr[1]) - field.AssertIsEqual(mulRes, &circuit.Expected) - - return nil -} - -func TestMain(t *testing.T) { - assert := test.NewAssert(t) - - var circuit testCircuit - - assert.ProverSucceeded( - &circuit, - &testCircuit{ - Arr: [2]emulated.Element[emulated.Secp256k1Fp]{ - emulated.ValueOf[emulated.Secp256k1Fp](42), - emulated.ValueOf[emulated.Secp256k1Fp](24), - }, - Expected: emulated.ValueOf[emulated.Secp256k1Fp](1008), - }, - test.WithBackends(backend.GROTH16), - test.WithCurves(ecc.BN254), - test.NoFuzzing(), - test.NoSerializationChecks(), - ) -} From ca5d0904d151d7704687908f29e79281658a195f Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Wed, 11 Oct 2023 15:20:42 -0700 Subject: [PATCH 10/13] benchmark works now --- benchmark.go | 30 +++++++++++++++++++----------- fri/fri.go | 10 +++++----- verifier/util.go | 6 +++--- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/benchmark.go b/benchmark.go index 3fbf46f..883756e 100644 --- a/benchmark.go +++ b/benchmark.go @@ -67,27 +67,28 @@ func runBenchmark(plonky2Circuit string, proofSystem string, profileCircuit bool println("r1cs.GetNbInternalVariables(): ", r1cs.GetNbInternalVariables()) } - witness := verifier.ExampleVerifierCircuit{ - Proof: proofWithPis.Proof, - PublicInputs: proofWithPis.PublicInputs, - VerifierOnlyCircuitData: verifierOnlyCircuitData, - CommonCircuitData: commonCircuitData, - } - if proofSystem == "plonk" { - plonkProof(r1cs, witness, dummy, saveArtifacts) + plonkProof(r1cs, plonky2Circuit, dummy, saveArtifacts) } else if proofSystem == "groth16" { - groth16Proof(r1cs, witness, dummy, saveArtifacts) + groth16Proof(r1cs, plonky2Circuit, dummy, saveArtifacts) } else { panic("Please provide a valid proof system to benchmark, we only support plonk and groth16") } } -func plonkProof(r1cs constraint.ConstraintSystem, assignment verifier.ExampleVerifierCircuit, dummy bool, saveArtifacts bool) { +func plonkProof(r1cs constraint.ConstraintSystem, circuitName string, dummy bool, saveArtifacts bool) { var pk plonk.ProvingKey var vk plonk.VerifyingKey var err error + proofWithPis := variables.DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs("testdata/" + circuitName + "/proof_with_public_inputs.json")) + verifierOnlyCircuitData := variables.DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData("testdata/" + circuitName + "/verifier_only_circuit_data.json")) + assignment := verifier.ExampleVerifierCircuit{ + Proof: proofWithPis.Proof, + PublicInputs: proofWithPis.PublicInputs, + VerifierOnlyCircuitData: verifierOnlyCircuitData, + } + // Don't serialize the circuit for now, since it takes up too much memory // if saveArtifacts { // fR1CS, _ := os.Create("circuit") @@ -166,11 +167,18 @@ func plonkProof(r1cs constraint.ConstraintSystem, assignment verifier.ExampleVer fmt.Printf("proofBytes: %v\n", proofBytes) } -func groth16Proof(r1cs constraint.ConstraintSystem, assignment verifier.ExampleVerifierCircuit, dummy bool, saveArtifacts bool) { +func groth16Proof(r1cs constraint.ConstraintSystem, circuitName string, dummy bool, saveArtifacts bool) { var pk groth16.ProvingKey var vk groth16.VerifyingKey var err error + proofWithPis := variables.DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs("testdata/" + circuitName + "/proof_with_public_inputs.json")) + verifierOnlyCircuitData := variables.DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData("testdata/" + circuitName + "/verifier_only_circuit_data.json")) + assignment := verifier.ExampleVerifierCircuit{ + Proof: proofWithPis.Proof, + PublicInputs: proofWithPis.PublicInputs, + VerifierOnlyCircuitData: verifierOnlyCircuitData, + } // Don't serialize the circuit for now, since it takes up too much memory // if saveArtifacts { // fR1CS, _ := os.Create("circuit") diff --git a/fri/fri.go b/fri/fri.go index cd13cf1..7fe5b43 100644 --- a/fri/fri.go +++ b/fri/fri.go @@ -15,11 +15,11 @@ import ( ) type Chip struct { - api frontend.API `gnark:"-"` - gl gl.Chip `gnark:"-"` - poseidonBN254Chip *poseidon.BN254Chip - commonData *types.CommonCircuitData - friParams *types.FriParams `gnark:"-"` + api frontend.API `gnark:"-"` + gl gl.Chip `gnark:"-"` + poseidonBN254Chip *poseidon.BN254Chip `gnark:"-"` + commonData *types.CommonCircuitData `gnark:"-"` + friParams *types.FriParams `gnark:"-"` } func NewChip( diff --git a/verifier/util.go b/verifier/util.go index 6449189..150ada5 100644 --- a/verifier/util.go +++ b/verifier/util.go @@ -8,9 +8,9 @@ import ( ) type ExampleVerifierCircuit struct { - PublicInputs []gl.Variable `gnark:",public"` - Proof variables.Proof - VerifierOnlyCircuitData variables.VerifierOnlyCircuitData + PublicInputs []gl.Variable `gnark:",public"` + Proof variables.Proof `gnark:"-"` + VerifierOnlyCircuitData variables.VerifierOnlyCircuitData `gnark:"-"` // This is configuration for the circuit, it is a constant not a variable CommonCircuitData types.CommonCircuitData From 19da211317ebe6ad6ad2086f10697329da1f9a6a Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Wed, 11 Oct 2023 15:23:53 -0700 Subject: [PATCH 11/13] rename another file --- benchmark.go | 2 +- fri/fri_test.go | 2 +- plonk/gates/gates_test.go | 2 +- plonk/plonk_test.go | 2 +- types/common_data.go | 2 +- types/common_data_test.go | 4 ++-- verifier/verifier_test.go | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/benchmark.go b/benchmark.go index 883756e..67efe6e 100644 --- a/benchmark.go +++ b/benchmark.go @@ -24,7 +24,7 @@ import ( ) func runBenchmark(plonky2Circuit string, proofSystem string, profileCircuit bool, dummy bool, saveArtifacts bool) { - commonCircuitData := types.DeserializeCommonCircuitData("testdata/" + plonky2Circuit + "/common_circuit_data.json") + commonCircuitData := types.ReadCommonCircuitData("testdata/" + plonky2Circuit + "/common_circuit_data.json") proofWithPis := variables.DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs("testdata/" + plonky2Circuit + "/proof_with_public_inputs.json")) verifierOnlyCircuitData := variables.DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData("testdata/" + plonky2Circuit + "/verifier_only_circuit_data.json")) diff --git a/fri/fri_test.go b/fri/fri_test.go index 19fb51d..6634bdf 100644 --- a/fri/fri_test.go +++ b/fri/fri_test.go @@ -112,7 +112,7 @@ func TestDecodeBlockFriVerification(t *testing.T) { verifierOnlyCircuitDataFilename := "../testdata/decode_block/verifier_only_circuit_data.json" proofWithPis := variables.DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs(proofWithPIsFilename)) - commonCircuitData := types.DeserializeCommonCircuitData(commonCircuitDataFilename) + commonCircuitData := types.ReadCommonCircuitData(commonCircuitDataFilename) verifierOnlyCircuitData := variables.DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData(verifierOnlyCircuitDataFilename)) testCase := func() { diff --git a/plonk/gates/gates_test.go b/plonk/gates/gates_test.go index 0f64769..8e793c9 100644 --- a/plonk/gates/gates_test.go +++ b/plonk/gates/gates_test.go @@ -690,7 +690,7 @@ type TestGateCircuit struct { } func (circuit *TestGateCircuit) Define(api frontend.API) error { - commonCircuitData := types.DeserializeCommonCircuitData("../../testdata/decode_block/common_circuit_data.json") + commonCircuitData := types.ReadCommonCircuitData("../../testdata/decode_block/common_circuit_data.json") numSelectors := commonCircuitData.SelectorsInfo.NumSelectors() glApi := gl.New(api) diff --git a/plonk/plonk_test.go b/plonk/plonk_test.go index 5a7b898..5b27c1b 100644 --- a/plonk/plonk_test.go +++ b/plonk/plonk_test.go @@ -44,7 +44,7 @@ func TestPlonkDecodeBlock(t *testing.T) { verifierOnlyCircuitDataFilename := "../testdata/decode_block/verifier_only_circuit_data.json" proofWithPis := variables.DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs(proofWithPIsFilename)) - commonCircuitData := types.DeserializeCommonCircuitData(commonCircuitDataFilename) + commonCircuitData := types.ReadCommonCircuitData(commonCircuitDataFilename) verifierOnlyCircuitData := variables.DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData(verifierOnlyCircuitDataFilename)) testCase := func() { diff --git a/types/common_data.go b/types/common_data.go index 3c386f3..9117e89 100644 --- a/types/common_data.go +++ b/types/common_data.go @@ -58,7 +58,7 @@ type CommonCircuitDataRaw struct { NumPartialProducts uint64 `json:"num_partial_products"` } -func DeserializeCommonCircuitData(path string) CommonCircuitData { +func ReadCommonCircuitData(path string) CommonCircuitData { jsonFile, err := os.Open(path) if err != nil { panic(err) diff --git a/types/common_data_test.go b/types/common_data_test.go index 865a569..0215efc 100644 --- a/types/common_data_test.go +++ b/types/common_data_test.go @@ -4,6 +4,6 @@ import ( "testing" ) -func TestDeserializeCommonCircuitData(t *testing.T) { - DeserializeCommonCircuitData("../testdata/decode_block/common_circuit_data.json") +func TestReadCommonCircuitData(t *testing.T) { + ReadCommonCircuitData("../testdata/decode_block/common_circuit_data.json") } diff --git a/verifier/verifier_test.go b/verifier/verifier_test.go index 901dcd5..c41c9e8 100644 --- a/verifier/verifier_test.go +++ b/verifier/verifier_test.go @@ -15,7 +15,7 @@ func TestStepVerifier(t *testing.T) { testCase := func() { plonky2Circuit := "step" - commonCircuitData := types.DeserializeCommonCircuitData("../testdata/" + plonky2Circuit + "/common_circuit_data.json") + commonCircuitData := types.ReadCommonCircuitData("../testdata/" + plonky2Circuit + "/common_circuit_data.json") proofWithPis := variables.DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs("../testdata/" + plonky2Circuit + "/proof_with_public_inputs.json")) verifierOnlyCircuitData := variables.DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData("../testdata/" + plonky2Circuit + "/verifier_only_circuit_data.json")) From 4841d382d7474c6224dcb12c4fab26dd29e24523 Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Wed, 11 Oct 2023 17:33:09 -0700 Subject: [PATCH 12/13] Modified another name --- poseidon/{bn254constants.go => bn254_constants.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename poseidon/{bn254constants.go => bn254_constants.go} (100%) diff --git a/poseidon/bn254constants.go b/poseidon/bn254_constants.go similarity index 100% rename from poseidon/bn254constants.go rename to poseidon/bn254_constants.go From 8b96b0fd87ce3c1f7a8ac234184b7f92ca7f0a6a Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Wed, 11 Oct 2023 17:38:57 -0700 Subject: [PATCH 13/13] Removed extraneous range check --- goldilocks/base.go | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/goldilocks/base.go b/goldilocks/base.go index d51a978..393d19e 100644 --- a/goldilocks/base.go +++ b/goldilocks/base.go @@ -317,36 +317,32 @@ func (p *Chip) RangeCheck(x Variable) { // in big endian binary. This function will first verify that x is at most 64 bits wide. Then it // checks that if the bits[0:31] (in big-endian) are all 1, then bits[32:64] are all zero. - // Use the range checker component to range-check the variable. - rangeChecker := rangecheck.New(p.api) - rangeChecker.Check(x.Limb, 64) - result, err := p.api.Compiler().NewHint(SplitLimbsHint, 2, x.Limb) if err != nil { panic(err) } // We check that this is a valid decomposition of the Goldilock's element and range-check each limb. - mostSigBits := result[0] - leastSigBits := result[1] + mostSigLimb := result[0] + leastSigLimb := result[1] p.api.AssertIsEqual( p.api.Add( - p.api.Mul(mostSigBits, uint64(math.Pow(2, 32))), - leastSigBits, + p.api.Mul(mostSigLimb, uint64(math.Pow(2, 32))), + leastSigLimb, ), x.Limb, ) - rangeChecker.Check(mostSigBits, 32) - rangeChecker.Check(leastSigBits, 32) + p.rangeChecker.Check(mostSigLimb, 32) + p.rangeChecker.Check(leastSigLimb, 32) // If the most significant bits are all 1, then we need to check that the least significant bits are all zero // in order for element to be less than the Goldilock's modulus. // Otherwise, we don't need to do any checks, since we already know that the element is less than the Goldilocks modulus. - shouldCheck := p.api.IsZero(p.api.Sub(mostSigBits, uint64(math.Pow(2, 32))-1)) + shouldCheck := p.api.IsZero(p.api.Sub(mostSigLimb, uint64(math.Pow(2, 32))-1)) p.api.AssertIsEqual( p.api.Select( shouldCheck, - leastSigBits, + leastSigLimb, frontend.Variable(0), ), frontend.Variable(0),