From 046d814f289f6231b2bb43f858bc6b8f35ea4638 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Tue, 28 Nov 2023 18:30:38 +0100 Subject: [PATCH] Squashed commit of the following: commit 6c05ea49ffc24072758384e99b0f98680381e34b Author: Ivo Kubjas Date: Tue Nov 28 16:24:47 2023 +0100 perf: use G2 precomputed lines for Miller loop (#930) * feat: add lazy line eval for Miller loop * chore: go mod * fix: DoublePairFixed order * refactor: remove fixed Q specialized methods * chore: serialize lines for KZG key * chore: go generate * docs: add init docs * feat: add fixed KZG verification key init * test: add constant and fixed VK test cases * test: use fixed init * feat: add fixed Groth16 verification * fix: unused import * refactor: merge last manual iteration commit a99d19821d1c6920834f7a1625d6f4d73b536585 Author: Ivo Kubjas Date: Tue Nov 28 16:20:44 2023 +0100 feat: add PLONK in-circuit verifier (#880) * test: add recursion hash tests * fix: accumulate MSM result * refactor: take emulated element for additional data * fix: handled infinity point in native multi scalar exp * fix: use only nbBits when creating scalar * feat: add PLONK verifier * feat: PlaceholderVerifyingKey takes the vk as argument * feat: f -> scalarApi * feat: addition of computeIthLagrangeAtZeta * feat: bsb commitments are added to pi * refactor: PlaceholderProof takes the proof as argument * fix: compute ith lagrange ok, hashToField failing * fix: native short hash output size * feat: add bw6 * docs: add package documentation * refactor: describe error in panic * refactor: init curve and pairing implicitly * refactor: remove comments * docs: add package examples * feat: add all supported witness assignments * test: add MSM test * fix: remove todo panic * feat: add option shortcuts * fix: include hash to field in shortcut option * feat: use only CCS for placeholder proof and verifyingkey * chore: typos and cleanup * docs: add KZG package documentation --------- Co-authored-by: Thomas Piellard commit 62b52ea8a01c0d4f18c229fb51c502e4a521a4ea Merge: ec072170 97156f33 Author: Youssef El Housni Date: Fri Nov 24 10:44:33 2023 -0500 Merge pull request #933 from Consensys/perf/karabina-cycloSq Perf: variant of the Karabina cyclotomic squaring commit 97156f333357a2f0e0783e9b3aa64746a70541a1 Author: Youssef El Housni Date: Fri Nov 24 10:27:00 2023 -0500 refactor: apply PR review suggestions commit f52c4cbb3bae13f57b262ff18a67a707698645c0 Author: Youssef El Housni Date: Thu Nov 23 01:50:41 2023 -0500 perf(bls12-377): implement a variant of Karabina cyclo square commit d7e8d7876536a1f18f42334c5bb46f701e50bb4e Author: Youssef El Housni Date: Wed Nov 22 23:28:26 2023 -0500 perf(bw6): implement a variant of Karabina cyclo square commit ec0721702eb02a0d8b094a5f589fe646a41d8d89 Merge: 3aa2559d 5479586a Author: Youssef El Housni Date: Wed Nov 22 18:16:46 2023 -0500 Merge pull request #931 from Consensys/perf/bw6-finalExp Perf: optimize addition chains in BW6-761 final exponentiation commit 5479586a39b5f1d24148dfb1a69538186c9382c2 Author: Youssef El Housni Date: Wed Nov 22 13:07:50 2023 -0500 perf(bw6/finalExp): replace Add(x,x) by MulConst(x,2) commit 65cd6ee3e23d501be8c69ad21cbd64ccff20b2c2 Author: Youssef El Housni Date: Tue Nov 21 21:39:55 2023 -0500 fix(linter): ineffectual assignment commit d948c7ce8d539845448796ec6338745b654c8ddb Author: Youssef El Housni Date: Tue Nov 21 21:27:02 2023 -0500 perf(bw6/finalExp): optimize addition chains commit 3aa2559d8dbdd41459ebb72144d04a8fa0bf4de0 Author: Gautam Botrel Date: Mon Nov 20 14:03:52 2023 -0600 feat: if we don't compress we don't need the dict (#929) --- backend/plonk/bls12-377/marshal.go | 2 + backend/plonk/bls12-381/marshal.go | 2 + backend/plonk/bls24-315/marshal.go | 2 + backend/plonk/bls24-317/marshal.go | 2 + backend/plonk/bn254/marshal.go | 2 + backend/plonk/bw6-633/marshal.go | 2 + backend/plonk/bw6-761/marshal.go | 2 + go.mod | 3 +- go.sum | 12 +- .../zkpschemes/plonk/plonk.marshal.go.tmpl | 2 + std/algebra/emulated/fields_bw6761/e6.go | 129 +++- .../emulated/fields_bw6761/e6_pairing.go | 136 ++-- std/algebra/emulated/fields_bw6761/e6_test.go | 24 +- std/algebra/emulated/sw_bw6761/g2.go | 45 +- std/algebra/emulated/sw_bw6761/pairing.go | 481 ++---------- .../emulated/sw_bw6761/pairing_test.go | 92 +-- .../emulated/sw_bw6761/precomputations.go | 718 ++---------------- std/algebra/native/fields_bls12377/e12.go | 94 ++- .../native/fields_bls12377/e12_pairing.go | 30 +- .../native/fields_bls12377/e12_test.go | 12 +- std/algebra/native/fields_bls24315/e24.go | 12 +- .../native/fields_bls24315/e24_pairing.go | 8 +- .../native/fields_bls24315/e24_test.go | 14 +- std/commitments/kzg/verifier.go | 101 +++ std/commitments/kzg/verifier_test.go | 109 +++ std/compress/lzss/compress.go | 5 +- std/recursion/groth16/verifier.go | 173 +++++ std/recursion/groth16/verifier_test.go | 92 +++ 28 files changed, 1027 insertions(+), 1279 deletions(-) diff --git a/backend/plonk/bls12-377/marshal.go b/backend/plonk/bls12-377/marshal.go index be1e58618d..d4c1397b5f 100644 --- a/backend/plonk/bls12-377/marshal.go +++ b/backend/plonk/bls12-377/marshal.go @@ -349,6 +349,7 @@ func (vk *VerifyingKey) writeTo(w io.Writer, options ...func(*curve.Encoder)) (n &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, vk.CommitmentConstraintIndexes, } @@ -388,6 +389,7 @@ func (vk *VerifyingKey) ReadFrom(r io.Reader) (int64, error) { &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, &vk.CommitmentConstraintIndexes, } diff --git a/backend/plonk/bls12-381/marshal.go b/backend/plonk/bls12-381/marshal.go index 808e6ebfd4..ad50b7ac50 100644 --- a/backend/plonk/bls12-381/marshal.go +++ b/backend/plonk/bls12-381/marshal.go @@ -349,6 +349,7 @@ func (vk *VerifyingKey) writeTo(w io.Writer, options ...func(*curve.Encoder)) (n &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, vk.CommitmentConstraintIndexes, } @@ -388,6 +389,7 @@ func (vk *VerifyingKey) ReadFrom(r io.Reader) (int64, error) { &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, &vk.CommitmentConstraintIndexes, } diff --git a/backend/plonk/bls24-315/marshal.go b/backend/plonk/bls24-315/marshal.go index 8f83f8a48a..41d4f69054 100644 --- a/backend/plonk/bls24-315/marshal.go +++ b/backend/plonk/bls24-315/marshal.go @@ -349,6 +349,7 @@ func (vk *VerifyingKey) writeTo(w io.Writer, options ...func(*curve.Encoder)) (n &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, vk.CommitmentConstraintIndexes, } @@ -388,6 +389,7 @@ func (vk *VerifyingKey) ReadFrom(r io.Reader) (int64, error) { &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, &vk.CommitmentConstraintIndexes, } diff --git a/backend/plonk/bls24-317/marshal.go b/backend/plonk/bls24-317/marshal.go index 59470dc834..93d125eb7b 100644 --- a/backend/plonk/bls24-317/marshal.go +++ b/backend/plonk/bls24-317/marshal.go @@ -349,6 +349,7 @@ func (vk *VerifyingKey) writeTo(w io.Writer, options ...func(*curve.Encoder)) (n &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, vk.CommitmentConstraintIndexes, } @@ -388,6 +389,7 @@ func (vk *VerifyingKey) ReadFrom(r io.Reader) (int64, error) { &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, &vk.CommitmentConstraintIndexes, } diff --git a/backend/plonk/bn254/marshal.go b/backend/plonk/bn254/marshal.go index 852de72b9f..dbf2843552 100644 --- a/backend/plonk/bn254/marshal.go +++ b/backend/plonk/bn254/marshal.go @@ -349,6 +349,7 @@ func (vk *VerifyingKey) writeTo(w io.Writer, options ...func(*curve.Encoder)) (n &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, vk.CommitmentConstraintIndexes, } @@ -388,6 +389,7 @@ func (vk *VerifyingKey) ReadFrom(r io.Reader) (int64, error) { &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, &vk.CommitmentConstraintIndexes, } diff --git a/backend/plonk/bw6-633/marshal.go b/backend/plonk/bw6-633/marshal.go index 2d60b8b7db..d0cac16c98 100644 --- a/backend/plonk/bw6-633/marshal.go +++ b/backend/plonk/bw6-633/marshal.go @@ -349,6 +349,7 @@ func (vk *VerifyingKey) writeTo(w io.Writer, options ...func(*curve.Encoder)) (n &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, vk.CommitmentConstraintIndexes, } @@ -388,6 +389,7 @@ func (vk *VerifyingKey) ReadFrom(r io.Reader) (int64, error) { &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, &vk.CommitmentConstraintIndexes, } diff --git a/backend/plonk/bw6-761/marshal.go b/backend/plonk/bw6-761/marshal.go index 51bd484e7b..33c85beda5 100644 --- a/backend/plonk/bw6-761/marshal.go +++ b/backend/plonk/bw6-761/marshal.go @@ -349,6 +349,7 @@ func (vk *VerifyingKey) writeTo(w io.Writer, options ...func(*curve.Encoder)) (n &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, vk.CommitmentConstraintIndexes, } @@ -388,6 +389,7 @@ func (vk *VerifyingKey) ReadFrom(r io.Reader) (int64, error) { &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, &vk.CommitmentConstraintIndexes, } diff --git a/go.mod b/go.mod index f4f401e015..447974ce43 100644 --- a/go.mod +++ b/go.mod @@ -6,12 +6,11 @@ require ( github.com/bits-and-blooms/bitset v1.8.0 github.com/blang/semver/v4 v4.0.0 github.com/consensys/bavard v0.1.13 - github.com/consensys/gnark-crypto v0.12.2-0.20231023220848-538dff926c15 + github.com/consensys/gnark-crypto v0.12.2-0.20231117165148-e77308824822 github.com/fxamacker/cbor/v2 v2.5.0 github.com/google/go-cmp v0.5.9 github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b github.com/icza/bitio v1.1.0 - github.com/klauspost/compress v1.17.1 github.com/ingonyama-zk/iciclegnark v0.1.0 github.com/leanovate/gopter v0.2.9 github.com/rs/zerolog v1.30.0 diff --git a/go.sum b/go.sum index 40db4b3190..9a9d59fd1a 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ 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= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.12.2-0.20231023220848-538dff926c15 h1:fu5ienFKWWqrfMPbWnhw4zfIFZW3pzVIbv3KtASymbU= -github.com/consensys/gnark-crypto v0.12.2-0.20231023220848-538dff926c15/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/consensys/gnark-crypto v0.12.2-0.20231117165148-e77308824822 h1:PvEjRgB/U4bv0jl9w65Wy9g0nIdkkW7vkNoR8Vq/als= +github.com/consensys/gnark-crypto v0.12.2-0.20231117165148-e77308824822/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -19,13 +19,14 @@ github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0Z github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/icza/bitio v1.1.0 h1:ysX4vtldjdi3Ygai5m1cWy4oLkhWTAi+SyO6HC8L9T0= github.com/icza/bitio v1.1.0/go.mod h1:0jGnlLAx8MKMr9VGnn/4YrvZiprkvBelsVIbA9Jjr9A= +github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6 h1:8UsGZ2rr2ksmEru6lToqnXgA8Mz1DP11X4zSJ159C3k= github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6/go.mod h1:xQig96I1VNBDIWGCdTt54nHt6EeI639SmHycLYL7FkA= github.com/ingonyama-zk/icicle v0.0.0-20230928131117-97f0079e5c71 h1:YxI1RTPzpFJ3MBmxPl3Bo0F7ume7CmQEC1M9jL6CT94= github.com/ingonyama-zk/icicle v0.0.0-20230928131117-97f0079e5c71/go.mod h1:kAK8/EoN7fUEmakzgZIYdWy1a2rBnpCaZLqSHwZWxEk= github.com/ingonyama-zk/iciclegnark v0.1.0 h1:88MkEghzjQBMjrYRJFxZ9oR9CTIpB8NG2zLeCJSvXKQ= github.com/ingonyama-zk/iciclegnark v0.1.0/go.mod h1:wz6+IpyHKs6UhMMoQpNqz1VY+ddfKqC/gRwR/64W6WU= -github.com/klauspost/compress v1.17.1 h1:NE3C767s2ak2bweCZo3+rdP4U/HoyVXLv/X9f2gPS5g= -github.com/klauspost/compress v1.17.1/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= @@ -41,6 +42,7 @@ github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFV github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= @@ -62,6 +64,8 @@ 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.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= diff --git a/internal/generator/backend/template/zkpschemes/plonk/plonk.marshal.go.tmpl b/internal/generator/backend/template/zkpschemes/plonk/plonk.marshal.go.tmpl index 5e976e2560..c3fef8a0ea 100644 --- a/internal/generator/backend/template/zkpschemes/plonk/plonk.marshal.go.tmpl +++ b/internal/generator/backend/template/zkpschemes/plonk/plonk.marshal.go.tmpl @@ -330,6 +330,7 @@ func (vk *VerifyingKey) writeTo(w io.Writer, options ...func(*curve.Encoder)) (n &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, vk.CommitmentConstraintIndexes, } @@ -369,6 +370,7 @@ func (vk *VerifyingKey) ReadFrom(r io.Reader) (int64, error) { &vk.Kzg.G1, &vk.Kzg.G2[0], &vk.Kzg.G2[1], + &vk.Kzg.Lines, &vk.CommitmentConstraintIndexes, } diff --git a/std/algebra/emulated/fields_bw6761/e6.go b/std/algebra/emulated/fields_bw6761/e6.go index 0bf6e38df4..53164e302a 100644 --- a/std/algebra/emulated/fields_bw6761/e6.go +++ b/std/algebra/emulated/fields_bw6761/e6.go @@ -1,6 +1,8 @@ package fields_bw6761 import ( + "math/big" + bw6761 "github.com/consensys/gnark-crypto/ecc/bw6-761" "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/std/math/emulated" @@ -103,10 +105,101 @@ func (e Ext6) Square(x *E6) *E6 { } } -// Karabina's compressed cyclotomic square +// Karabina's compressed cyclotomic square SQR12345 +// https://eprint.iacr.org/2010/542.pdf +// Sec. 5.6 with minor modifications to fit our tower +func (e Ext6) CyclotomicSquareKarabina12345(x *E6) *E6 { + x = e.Reduce(x) + + // h4 = -g4 + 3((g3+g5)(g1+c*g2)-g1g5-c*g3g2) + g1g5 := e.fp.Mul(&x.B0.A1, &x.B1.A2) + g3g2 := e.fp.Mul(&x.B1.A0, &x.B0.A2) + h4 := mulFpByNonResidue(e.fp, &x.B0.A2) + h4 = e.fp.Add(h4, &x.B0.A1) + t := e.fp.Add(&x.B1.A0, &x.B1.A2) + h4 = e.fp.Mul(h4, t) + h4 = e.fp.Sub(h4, g1g5) + t = mulFpByNonResidue(e.fp, g3g2) + h4 = e.fp.Sub(h4, t) + h4 = e.fp.MulConst(h4, big.NewInt(3)) + h4 = e.fp.Sub(h4, &x.B1.A1) + + // h3 = 2(g3+3c*g1g5) + h3 := mulFpByNonResidue(e.fp, g1g5) + h3 = e.fp.MulConst(h3, big.NewInt(3)) + h3 = e.fp.Add(h3, &x.B1.A0) + h3 = e.fp.MulConst(h3, big.NewInt(2)) + + // h2 = 3((g1+g5)(g1+c*g5)-(c+1)*g1g5)-2g2 + t = mulFpByNonResidue(e.fp, &x.B1.A2) + t = e.fp.Add(t, &x.B0.A1) + h2 := e.fp.Add(&x.B1.A2, &x.B0.A1) + h2 = e.fp.Mul(h2, t) + t = e.fp.MulConst(g1g5, big.NewInt(3)) + h2 = e.fp.Add(h2, t) + h2 = e.fp.MulConst(h2, big.NewInt(3)) + t = e.fp.MulConst(&x.B0.A2, big.NewInt(2)) + h2 = e.fp.Sub(h2, t) + + // h1 = 3((g3+g2)(g3+c*g2)-(c+1)*g3g2)-2g1 + t = mulFpByNonResidue(e.fp, &x.B0.A2) + t = e.fp.Add(t, &x.B1.A0) + h1 := e.fp.Add(&x.B0.A2, &x.B1.A0) + h1 = e.fp.Mul(h1, t) + t = e.fp.MulConst(g3g2, big.NewInt(3)) + h1 = e.fp.Add(h1, t) + h1 = e.fp.MulConst(h1, big.NewInt(3)) + t = e.fp.MulConst(&x.B0.A1, big.NewInt(2)) + h1 = e.fp.Sub(h1, t) + + // h5 = 2(g5+3g3g2) + h5 := e.fp.MulConst(g3g2, big.NewInt(3)) + h5 = e.fp.Add(h5, &x.B1.A2) + h5 = e.fp.MulConst(h5, big.NewInt(2)) + + return &E6{ + B0: E3{ + A0: x.B0.A0, + A1: *h1, + A2: *h2, + }, + B1: E3{ + A0: *h3, + A1: *h4, + A2: *h5, + }, + } +} + +// DecompressKarabina12345 decompresses Karabina's cyclotomic square result SQR12345 +func (e Ext6) DecompressKarabina12345(x *E6) *E6 { + x = e.Reduce(x) + + // h0 = (2g4^2 + g3g5 - 3g2g1)*c + 1 + t0 := e.fp.Mul(&x.B0.A1, &x.B0.A2) + t0 = e.fp.MulConst(t0, big.NewInt(3)) + t1 := e.fp.Mul(&x.B1.A0, &x.B1.A2) + h0 := e.fp.Mul(&x.B1.A1, &x.B1.A1) + h0 = e.fp.MulConst(h0, big.NewInt(2)) + h0 = e.fp.Add(h0, t1) + h0 = e.fp.Sub(h0, t0) + h0 = mulFpByNonResidue(e.fp, h0) + h0 = e.fp.Add(h0, e.fp.One()) + + return &E6{ + B0: E3{ + A0: *h0, + A1: x.B0.A1, + A2: x.B0.A2, + }, + B1: x.B1, + } +} + +// Karabina's compressed cyclotomic square SQR2345 // https://eprint.iacr.org/2010/542.pdf // Th. 3.2 with minor modifications to fit our tower -func (e Ext6) CyclotomicSquareCompressed(x *E6) *E6 { +func (e Ext6) CyclotomicSquareKarabina2345(x *E6) *E6 { x = e.Reduce(x) z := e.Copy(x) @@ -137,7 +230,7 @@ func (e Ext6) CyclotomicSquareCompressed(x *E6) *E6 { t[6] = mulFpByNonResidue(e.fp, t[5]) // t5 = 4 * nr * g1 * g5 + 2 * g3 t[5] = e.fp.Add(t[6], &x.B1.A0) - t[5] = e.fp.Add(t[5], t[5]) + t[5] = e.fp.MulConst(t[5], big.NewInt(2)) // z3 = 6 * nr * g1 * g5 + 2 * g3 z.B1.A0 = *e.fp.Add(t[5], t[6]) @@ -152,7 +245,7 @@ func (e Ext6) CyclotomicSquareCompressed(x *E6) *E6 { t[1] = e.fp.Mul(&x.B0.A2, &x.B0.A2) // t6 = 2 * nr * g5² + 2 * g1² - 2*g2 - t[6] = e.fp.Add(t[6], t[6]) + t[6] = e.fp.MulConst(t[6], big.NewInt(2)) // z2 = 3 * nr * g5² + 3 * g1² - 2*g2 z.B0.A2 = *e.fp.Add(t[6], t[5]) @@ -163,7 +256,7 @@ func (e Ext6) CyclotomicSquareCompressed(x *E6) *E6 { // t6 = g3² + nr * g2² - g1 t[6] = e.fp.Sub(t[5], &x.B0.A1) // t6 = 2 * g3² + 2 * nr * g2² - 2 * g1 - t[6] = e.fp.Add(t[6], t[6]) + t[6] = e.fp.MulConst(t[6], big.NewInt(2)) // z1 = 3 * g3² + 3 * nr * g2² - 2 * g1 z.B0.A1 = *e.fp.Add(t[6], t[5]) @@ -174,14 +267,14 @@ func (e Ext6) CyclotomicSquareCompressed(x *E6) *E6 { // t6 = 2 * g3 * g2 + g5 t[6] = e.fp.Add(t[5], &x.B1.A2) // t6 = 4 * g3 * g2 + 2 * g5 - t[6] = e.fp.Add(t[6], t[6]) + t[6] = e.fp.MulConst(t[6], big.NewInt(2)) // z5 = 6 * g3 * g2 + 2 * g5 z.B1.A2 = *e.fp.Add(t[5], t[6]) return z } -// DecompressKarabina Karabina's cyclotomic square result +// DecompressKarabina2345 decompresses Karabina's cyclotomic square result SQR2345 // if g3 != 0 // // g4 = (E * g5^2 + 3 * g1^2 - 2 * g2)/4g3 @@ -192,7 +285,7 @@ func (e Ext6) CyclotomicSquareCompressed(x *E6) *E6 { // // if g3=g2=0 then g4=g5=g1=0 and g0=1 (x=1) // Theorem 3.1 is well-defined for all x in Gϕₙ\{1} -func (e Ext6) DecompressKarabina(x *E6) *E6 { +func (e Ext6) DecompressKarabina2345(x *E6) *E6 { x = e.Reduce(x) @@ -207,7 +300,7 @@ func (e Ext6) DecompressKarabina(x *E6) *E6 { // t1 = g2 selector1 := e.fp.IsZero(&x.B1.A0) _t[0] = e.fp.Mul(&x.B0.A1, &x.B0.A1) - _t[0] = e.fp.Add(_t[0], _t[0]) + _t[0] = e.fp.MulConst(_t[0], big.NewInt(2)) _t[1] = &x.B0.A2 // if g2 == g3 == 0 @@ -218,13 +311,13 @@ func (e Ext6) DecompressKarabina(x *E6) *E6 { // t1 = 4 * g3 t[0] = e.fp.Mul(&x.B0.A1, &x.B0.A1) t[1] = e.fp.Sub(t[0], &x.B0.A2) - t[1] = e.fp.Add(t[1], t[1]) + t[1] = e.fp.MulConst(t[1], big.NewInt(2)) t[1] = e.fp.Add(t[1], t[0]) t[2] = e.fp.Mul(&x.B1.A2, &x.B1.A2) t[0] = mulFpByNonResidue(e.fp, t[2]) t[0] = e.fp.Add(t[0], t[1]) t[1] = e.fp.Add(&x.B1.A0, &x.B1.A0) - t[1] = e.fp.Add(t[1], t[1]) + t[1] = e.fp.MulConst(t[1], big.NewInt(2)) // g4 = (E * g5^2 + 3 * g1^2 - 2 * g2)/4g3 or (2 * g1 * g5)/g2 t[0] = e.fp.Select(selector1, _t[0], t[0]) @@ -240,11 +333,11 @@ func (e Ext6) DecompressKarabina(x *E6) *E6 { // t2 = 2 * g4² - 3 * g2 * g1 t[2] = e.fp.Mul(&z.B1.A1, &z.B1.A1) t[2] = e.fp.Sub(t[2], t[1]) - t[2] = e.fp.Add(t[2], t[2]) + t[2] = e.fp.MulConst(t[2], big.NewInt(2)) t[2] = e.fp.Sub(t[2], t[1]) // t1 = g3 * g5 (g3 can be 0) t[1] = e.fp.Mul(&x.B1.A0, &x.B1.A2) - // c₀ = E * (2 * g4² + g3 * g5 - 3 * g2 * g1) + 1 + // g0 = E * (2 * g4² + g3 * g5 - 3 * g2 * g1) + 1 t[2] = e.fp.Add(t[2], t[1]) z.B0.A0 = *mulFpByNonResidue(e.fp, t[2]) @@ -302,20 +395,20 @@ func (e Ext6) CyclotomicSquare(x *E6) *E6 { var z E6 z.B0.A0 = *e.fp.Sub(t[0], &x.B0.A0) - z.B0.A0 = *e.fp.Add(&z.B0.A0, &z.B0.A0) + z.B0.A0 = *e.fp.MulConst(&z.B0.A0, big.NewInt(2)) z.B0.A0 = *e.fp.Add(&z.B0.A0, t[0]) z.B0.A1 = *e.fp.Sub(t[2], &x.B0.A1) - z.B0.A1 = *e.fp.Add(&z.B0.A1, &z.B0.A1) + z.B0.A1 = *e.fp.MulConst(&z.B0.A1, big.NewInt(2)) z.B0.A1 = *e.fp.Add(&z.B0.A1, t[2]) z.B0.A2 = *e.fp.Sub(t[4], &x.B0.A2) - z.B0.A2 = *e.fp.Add(&z.B0.A2, &z.B0.A2) + z.B0.A2 = *e.fp.MulConst(&z.B0.A2, big.NewInt(2)) z.B0.A2 = *e.fp.Add(&z.B0.A2, t[4]) z.B1.A0 = *e.fp.Add(t[8], &x.B1.A0) - z.B1.A0 = *e.fp.Add(&z.B1.A0, &z.B1.A0) + z.B1.A0 = *e.fp.MulConst(&z.B1.A0, big.NewInt(2)) z.B1.A0 = *e.fp.Add(&z.B1.A0, t[8]) z.B1.A1 = *e.fp.Add(t[6], &x.B1.A1) - z.B1.A1 = *e.fp.Add(&z.B1.A1, &z.B1.A1) + z.B1.A1 = *e.fp.MulConst(&z.B1.A1, big.NewInt(2)) z.B1.A1 = *e.fp.Add(&z.B1.A1, t[6]) z.B1.A2 = *e.fp.Add(t[7], &x.B1.A2) z.B1.A2 = *e.fp.Add(&z.B1.A2, &z.B1.A2) diff --git a/std/algebra/emulated/fields_bw6761/e6_pairing.go b/std/algebra/emulated/fields_bw6761/e6_pairing.go index 434483d1bd..54dcbee4be 100644 --- a/std/algebra/emulated/fields_bw6761/e6_pairing.go +++ b/std/algebra/emulated/fields_bw6761/e6_pairing.go @@ -1,31 +1,44 @@ package fields_bw6761 -func (e Ext6) nSquareCompressed(z *E6, n int) *E6 { +import ( + "math/big" + + "github.com/consensys/gnark/std/math/emulated" +) + +func (e Ext6) nSquareKarabina2345(z *E6, n int) *E6 { for i := 0; i < n; i++ { - z = e.CyclotomicSquareCompressed(z) + z = e.CyclotomicSquareKarabina2345(z) + } + return z +} + +func (e Ext6) nSquareKarabina12345(z *E6, n int) *E6 { + for i := 0; i < n; i++ { + z = e.CyclotomicSquareKarabina12345(z) } return z } // ExpX0Minus1 set z to z^{x₀-1} in E6 and return z -// x₀-1 = 91893752504881257682351033800651177983 +// x₀-1 = 9586122913090633728 func (e Ext6) ExpX0Minus1(z *E6) *E6 { z = e.Reduce(z) result := e.Copy(z) - result = e.nSquareCompressed(result, 5) - result = e.DecompressKarabina(result) + result = e.nSquareKarabina12345(result, 5) + result = e.DecompressKarabina12345(result) result = e.Mul(result, z) z33 := e.Copy(result) - result = e.nSquareCompressed(result, 7) - result = e.DecompressKarabina(result) + result = e.nSquareKarabina12345(result, 7) + result = e.DecompressKarabina12345(result) result = e.Mul(result, z33) - result = e.nSquareCompressed(result, 4) - result = e.DecompressKarabina(result) + result = e.nSquareKarabina12345(result, 4) + result = e.DecompressKarabina12345(result) result = e.Mul(result, z) result = e.CyclotomicSquare(result) result = e.Mul(result, z) - result = e.nSquareCompressed(result, 46) - result = e.DecompressKarabina(result) + result = e.nSquareKarabina2345(result, 46) + result = e.DecompressKarabina2345(result) return result } @@ -35,40 +48,56 @@ func (e Ext6) ExpX0Minus1(z *E6) *E6 { func (e Ext6) ExpX0Minus1Square(z *E6) *E6 { z = e.Reduce(z) result := e.Copy(z) - result = e.CyclotomicSquare(result) - t0 := e.Mul(z, result) + result = e.nSquareKarabina12345(result, 3) + result = e.DecompressKarabina12345(result) + t0 := e.CyclotomicSquare(result) + t2 := e.Mul(z, t0) + result = e.Mul(result, t2) + t0 = e.Mul(z, result) t1 := e.CyclotomicSquare(t0) - t0 = e.Mul(t0, t1) - result = e.Mul(result, t0) - t1 = e.Mul(t1, result) - t0 = e.Mul(t0, t1) - t2 := e.CyclotomicSquare(t0) - t2 = e.Mul(t1, t2) - t0 = e.Mul(t0, t2) - t2 = e.nSquareCompressed(t2, 7) - t2 = e.DecompressKarabina(t2) + t1 = e.Mul(t2, t1) + t3 := e.nSquareKarabina12345(t1, 7) + t3 = e.DecompressKarabina12345(t3) + t2 = e.Mul(t2, t3) + t2 = e.nSquareKarabina12345(t2, 11) + t2 = e.DecompressKarabina12345(t2) t1 = e.Mul(t1, t2) - t1 = e.nSquareCompressed(t1, 11) - t1 = e.DecompressKarabina(t1) - t1 = e.Mul(t0, t1) - t1 = e.nSquareCompressed(t1, 9) - t1 = e.DecompressKarabina(t1) t0 = e.Mul(t0, t1) - t0 = e.CyclotomicSquare(t0) + t0 = e.nSquareKarabina12345(t0, 7) + t0 = e.DecompressKarabina12345(t0) result = e.Mul(result, t0) - result = e.nSquareCompressed(result, 92) - result = e.DecompressKarabina(result) + result = e.nSquareKarabina12345(result, 3) + result = e.DecompressKarabina12345(result) + result = e.Mul(z, result) + result = e.nSquareKarabina2345(result, 92) + result = e.DecompressKarabina2345(result) return result } // ExpX0Plus1 set z to z^(x₀+1) in E6 and return z -// x₀+1 = 91893752504881257682351033800651177985 +// x₀+1 = 9586122913090633730 func (e Ext6) ExpX0Plus1(z *E6) *E6 { - result := e.ExpX0Minus1(z) - t := e.CyclotomicSquare(z) + z = e.Reduce(z) + result := e.Copy(z) + t := e.CyclotomicSquare(result) + result = e.nSquareKarabina12345(t, 4) + result = e.DecompressKarabina12345(result) + result = e.Mul(result, z) + z33 := e.Copy(result) + result = e.nSquareKarabina12345(result, 7) + result = e.DecompressKarabina12345(result) + result = e.Mul(result, z33) + result = e.nSquareKarabina12345(result, 4) + result = e.DecompressKarabina12345(result) + result = e.Mul(result, z) + result = e.CyclotomicSquare(result) + result = e.Mul(result, z) + result = e.nSquareKarabina2345(result, 46) + result = e.DecompressKarabina2345(result) result = e.Mul(result, t) + return result } @@ -78,19 +107,18 @@ func (e Ext6) ExptMinus1Div3(z *E6) *E6 { z = e.Reduce(z) result := e.Copy(z) result = e.CyclotomicSquare(result) + result = e.CyclotomicSquare(result) result = e.Mul(result, z) - t0 := e.Mul(result, z) - t0 = e.CyclotomicSquare(t0) - result = e.Mul(result, t0) - t0 = result - t0 = e.nSquareCompressed(t0, 7) - t0 = e.DecompressKarabina(t0) + result = e.CyclotomicSquare(result) + result = e.Mul(result, z) + t0 := e.nSquareKarabina12345(result, 7) + t0 = e.DecompressKarabina2345(t0) result = e.Mul(result, t0) - result = e.nSquareCompressed(result, 5) - result = e.DecompressKarabina(result) + result = e.nSquareKarabina12345(result, 5) + result = e.DecompressKarabina12345(result) result = e.Mul(result, z) - result = e.nSquareCompressed(result, 46) - result = e.DecompressKarabina(result) + result = e.nSquareKarabina2345(result, 46) + result = e.DecompressKarabina2345(result) return result } @@ -100,11 +128,12 @@ func (e Ext6) ExptMinus1Div3(z *E6) *E6 { // C1 = (ht+hy)/2 = 11 func (e Ext6) ExpC1(z *E6) *E6 { z = e.Reduce(z) - result := e.CyclotomicSquare(z) + result := e.Copy(z) + result = e.CyclotomicSquare(result) + result = e.CyclotomicSquare(result) + result = e.Mul(result, z) + result = e.CyclotomicSquare(result) result = e.Mul(result, z) - t0 := e.Mul(z, result) - t0 = e.CyclotomicSquare(t0) - result = e.Mul(result, t0) return result } @@ -114,12 +143,10 @@ func (e Ext6) ExpC1(z *E6) *E6 { // C2 = (ht**2+3*hy**2)/4 = 103 func (e Ext6) ExpC2(z *E6) *E6 { z = e.Reduce(z) - result := e.CyclotomicSquare(z) result = e.Mul(result, z) - t0 := result - t0 = e.nSquareCompressed(t0, 4) - t0 = e.DecompressKarabina(t0) + t0 := e.nSquareKarabina12345(result, 4) + t0 = e.DecompressKarabina12345(t0) result = e.Mul(result, t0) result = e.CyclotomicSquare(result) result = e.Mul(result, z) @@ -193,11 +220,8 @@ func (e Ext6) Mul014By014(d0, d1, c0, c1 *baseEl) [5]*baseEl { x14 = e.fp.Sub(x14, x1) x14 = e.fp.Sub(x14, one) - zC0B0 := e.fp.Add(one, one) - zC0B0 = e.fp.Add(zC0B0, zC0B0) - zC0B0 = e.fp.Neg(zC0B0) - - zC0B0 = e.fp.Add(zC0B0, x0) + four := emulated.ValueOf[emulated.BW6761Fp](big.NewInt(4)) + zC0B0 := e.fp.Sub(x0, &four) return [5]*baseEl{zC0B0, x01, x1, x04, x14} } diff --git a/std/algebra/emulated/fields_bw6761/e6_test.go b/std/algebra/emulated/fields_bw6761/e6_test.go index c4a557afaa..ecf3104517 100644 --- a/std/algebra/emulated/fields_bw6761/e6_test.go +++ b/std/algebra/emulated/fields_bw6761/e6_test.go @@ -245,18 +245,18 @@ func TestConjugateFp6(t *testing.T) { assert.NoError(err) } -type e6CyclotomicSquareCompressed struct { +type e6CyclotomicSquareKarabina2345 struct { A, B E6 } -func (circuit *e6CyclotomicSquareCompressed) Define(api frontend.API) error { +func (circuit *e6CyclotomicSquareKarabina2345) Define(api frontend.API) error { e := NewExt6(api) - expected := e.CyclotomicSquareCompressed(&circuit.A) + expected := e.CyclotomicSquareKarabina2345(&circuit.A) e.AssertIsEqual(expected, &circuit.B) return nil } -func TestCyclotomicSquareCompressedFp6(t *testing.T) { +func TestCyclotomicSquareKarabina2345Fp6(t *testing.T) { assert := test.NewAssert(t) // witness values var a, b bw6761.E6 @@ -264,27 +264,27 @@ func TestCyclotomicSquareCompressedFp6(t *testing.T) { b.Set(&a) b.CyclotomicSquareCompressed(&a) - witness := e6CyclotomicSquareCompressed{ + witness := e6CyclotomicSquareKarabina2345{ A: FromE6(&a), B: FromE6(&b), } - err := test.IsSolved(&e6CyclotomicSquareCompressed{}, &witness, ecc.BN254.ScalarField()) + err := test.IsSolved(&e6CyclotomicSquareKarabina2345{}, &witness, ecc.BN254.ScalarField()) assert.NoError(err) } -type e6DecompressKarabina struct { +type e6DecompressKarabina2345 struct { A, B E6 } -func (circuit *e6DecompressKarabina) Define(api frontend.API) error { +func (circuit *e6DecompressKarabina2345) Define(api frontend.API) error { e := NewExt6(api) - expected := e.DecompressKarabina(&circuit.A) + expected := e.DecompressKarabina2345(&circuit.A) e.AssertIsEqual(expected, &circuit.B) return nil } -func TestDecompressKarabinaFp6(t *testing.T) { +func TestDecompressKarabina2345Fp6(t *testing.T) { assert := test.NewAssert(t) // witness values var a, b bw6761.E6 @@ -292,12 +292,12 @@ func TestDecompressKarabinaFp6(t *testing.T) { b.Set(&a) a.DecompressKarabina(&a) - witness := e6DecompressKarabina{ + witness := e6DecompressKarabina2345{ A: FromE6(&b), B: FromE6(&a), } - err := test.IsSolved(&e6DecompressKarabina{}, &witness, ecc.BN254.ScalarField()) + err := test.IsSolved(&e6DecompressKarabina2345{}, &witness, ecc.BN254.ScalarField()) assert.NoError(err) } diff --git a/std/algebra/emulated/sw_bw6761/g2.go b/std/algebra/emulated/sw_bw6761/g2.go index 8567c3e61c..ede32dc663 100644 --- a/std/algebra/emulated/sw_bw6761/g2.go +++ b/std/algebra/emulated/sw_bw6761/g2.go @@ -6,11 +6,50 @@ import ( "github.com/consensys/gnark/std/math/emulated" ) -type G2Affine = sw_emulated.AffinePoint[BaseField] +// g2AffP is the raw G2 element without precomputations. +type g2AffP = sw_emulated.AffinePoint[BaseField] -func NewG2Affine(v bw6761.G2Affine) G2Affine { - return G2Affine{ +// G2Affine represents G2 element with optional embedded line precomputations. +type G2Affine struct { + P g2AffP + Lines *lineEvaluations +} + +func newG2AffP(v bw6761.G2Affine) g2AffP { + return sw_emulated.AffinePoint[BaseField]{ X: emulated.ValueOf[BaseField](v.X), Y: emulated.ValueOf[BaseField](v.Y), } } + +// NewG2Affine returns the witness of v without precomputations. In case of +// pairing the precomputation will be done in-circuit. +func NewG2Affine(v bw6761.G2Affine) G2Affine { + return G2Affine{ + P: newG2AffP(v), + } +} + +// NewG2AffineFixed returns witness of v with precomputations for efficient +// pairing computation. +func NewG2AffineFixed(v bw6761.G2Affine) G2Affine { + lines := precomputeLines(v) + return G2Affine{ + P: newG2AffP(v), + Lines: &lines, + } +} + +// NewG2AffineFixedPlaceholder returns a placeholder for the circuit compilation +// when witness will be given with line precomputations using +// [NewG2AffineFixed]. +func NewG2AffineFixedPlaceholder() G2Affine { + var lines lineEvaluations + for i := 0; i < len(bw6761.LoopCounter)-1; i++ { + lines[0][i] = &lineEvaluation{} + lines[1][i] = &lineEvaluation{} + } + return G2Affine{ + Lines: &lines, + } +} diff --git a/std/algebra/emulated/sw_bw6761/pairing.go b/std/algebra/emulated/sw_bw6761/pairing.go index 02026ad42e..343563eac2 100644 --- a/std/algebra/emulated/sw_bw6761/pairing.go +++ b/std/algebra/emulated/sw_bw6761/pairing.go @@ -15,7 +15,7 @@ type Pairing struct { api frontend.API *fields_bw6761.Ext6 curveF *emulated.Field[BaseField] - lines [4][189]emulated.Element[BaseField] + g2gen *G2Affine } type GTEl = fields_bw6761.E6 @@ -44,10 +44,18 @@ func NewPairing(api frontend.API) (*Pairing, error) { api: api, Ext6: fields_bw6761.NewExt6(api), curveF: ba, - lines: getPrecomputedLines(), }, nil } +func (pr Pairing) generators() *G2Affine { + if pr.g2gen == nil { + _, _, _, g2gen := bw6761.Generators() + cg2gen := NewG2AffineFixed(g2gen) + pr.g2gen = &cg2gen + } + return pr.g2gen +} + // FinalExponentiation computes the exponentiation zᵈ where // // d = (p⁶-1)/r = (p⁶-1)/Φ₆(p) ⋅ Φ₆(p)/r = (p³-1)(p+1)(p²-p+1)/r @@ -99,13 +107,6 @@ func (pr Pairing) FinalExponentiation(z *GTEl) *GTEl { return result } -// lineEvaluation represents a sparse Fp6 Elmt (result of the line evaluation) -// line: 1 + R0(x/y) + R1(1/y) = 0 instead of R0'*y + R1'*x + R2' = 0 This -// makes the multiplication by lines (MulBy014) -type lineEvaluation struct { - R0, R1 emulated.Element[BaseField] -} - // Pair calculates the reduced pairing for a set of points // ∏ᵢ e(Pᵢ, Qᵢ). // @@ -181,46 +182,51 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) { if n == 0 || n != len(Q) { return nil, errors.New("invalid inputs sizes") } + lines := make([]lineEvaluations, len(Q)) + for i := range Q { + if Q[i].Lines == nil { + Qlines := pr.precomputeLines(&Q[i].P) + Q[i].Lines = &Qlines + } + lines[i] = *Q[i].Lines + } + return pr.millerLoopLines(P, lines) + +} + +// MillerLoopFixedQ computes the multi-Miller loop as in MillerLoop +// but Qᵢ are fixed points in G2 known in advance. +func (pr Pairing) millerLoopLines(P []*G1Affine, lines []lineEvaluations) (*GTEl, error) { + + // check input size match + n := len(P) + if n == 0 || n != len(lines) { + return nil, errors.New("invalid inputs sizes") + } // precomputations - negQ := make([]*G2Affine, n) - imQ := make([]*G2Affine, n) - imQneg := make([]*G2Affine, n) - accQ := make([]*G2Affine, n) - yInv := make([]*emulated.Element[BaseField], n) - xNegOverY := make([]*emulated.Element[BaseField], n) + yInv := make([]*emulated.Element[emulated.BW6761Fp], n) + xNegOverY := make([]*emulated.Element[emulated.BW6761Fp], n) for k := 0; k < n; k++ { - // P and Q are supposed to be on G1 and G2 respectively of prime order r. + // P are supposed to be on G1 respectively of prime order r. // The point (x,0) is of order 2. But this function does not check // subgroup membership. yInv[k] = pr.curveF.Inverse(&P[k].Y) xNegOverY[k] = pr.curveF.MulMod(&P[k].X, yInv[k]) xNegOverY[k] = pr.curveF.Neg(xNegOverY[k]) - // negQ = -Q = (x, -y) - negQ[k] = &G1Affine{X: Q[k].X, Y: *pr.curveF.Neg(&Q[k].Y)} - // imQ = (w*x, -y) - imQ[k] = &G1Affine{X: *pr.curveF.MulMod(&Q[k].X, &thirdRootOne), Y: negQ[k].Y} - // imQneg = (w*x, y) - imQneg[k] = &G1Affine{X: imQ[k].X, Y: Q[k].Y} - // point accumulator initialized to imQ - accQ[k] = imQ[k] } - // f_{x₀+1+λ(x₀³-x₀²-x₀),Q}(P) + // f_{x₀+1+λ(x₀³-x₀²-x₀),Q}(P), Q is known in advance + var prodLines [5]*emulated.Element[emulated.BW6761Fp] result := pr.Ext6.One() - var l0, l1 *lineEvaluation - - var prodLines [5]*emulated.Element[BaseField] - // i = 188, separately to avoid an E6 Square - // (Square(res) = 1² = 1) - // k = 0, separately to avoid MulBy014 (res × ℓ) - // (assign line to res) - accQ[0], l0 = pr.doubleStep(imQ[0]) + + // i = 188 + // k = 0 result = &fields_bw6761.E6{ B0: fields_bw6761.E3{ - A0: *pr.curveF.MulMod(&l0.R1, yInv[0]), - A1: *pr.curveF.MulMod(&l0.R0, xNegOverY[0]), + A0: *pr.curveF.MulMod(&lines[0][0][188].R1, yInv[0]), + A1: *pr.curveF.MulMod(&lines[0][0][188].R0, xNegOverY[0]), A2: result.B0.A2, }, B1: fields_bw6761.E3{ @@ -233,12 +239,12 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) { if n >= 2 { // k = 1, separately to avoid MulBy014 (res × ℓ) // (res is also a line at this point, so we use Mul014By014 ℓ × ℓ) - accQ[1], l0 = pr.doubleStep(accQ[1]) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[1]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[1]), - } - prodLines = pr.Mul014By014(&l0.R1, &l0.R0, &result.B0.A0, &result.B0.A1) + prodLines = pr.Mul014By014( + pr.curveF.MulMod(&lines[1][0][188].R1, yInv[1]), + pr.curveF.MulMod(&lines[1][0][188].R0, xNegOverY[1]), + &result.B0.A0, + &result.B0.A1, + ) result = &fields_bw6761.E6{ B0: fields_bw6761.E3{ A0: *prodLines[0], @@ -255,114 +261,42 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) { if n >= 3 { // k = 2, separately to avoid MulBy014 (res × ℓ) - // (res has a zero E2 element, so we use Mul01234By034) - accQ[2], l0 = pr.doubleStep(accQ[2]) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[2]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[2]), - } - result = pr.Mul01245By014(prodLines, &l0.R1, &l0.R0) + // (res has a zero E2 element, so we use Mul01245By014) + result = pr.Mul01245By014( + prodLines, + pr.curveF.MulMod(&lines[2][0][188].R1, yInv[2]), + pr.curveF.MulMod(&lines[2][0][188].R0, xNegOverY[2]), + ) // k >= 3 for k := 3; k < n; k++ { - accQ[k], l0 = pr.doubleStep(accQ[k]) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[k]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[k]), - } - result = pr.MulBy014(result, &l0.R1, &l0.R0) + result = pr.MulBy014(result, + pr.curveF.MulMod(&lines[k][0][188].R1, yInv[k]), + pr.curveF.MulMod(&lines[k][0][188].R0, xNegOverY[k]), + ) } } - for i := 187; i >= 1; i-- { + for i := 187; i >= 0; i-- { // mutualize the square among n Miller loops // (∏ᵢfᵢ)² result = pr.Square(result) - j := loopCounter2[i]*3 + loopCounter1[i] - for k := 0; k < n; k++ { - switch j { - // cases -4, -2, 2 and 4 are omitted as they do not occur given the - // static loop counters. - case -3: - accQ[k], l0, l1 = pr.doubleAndAddStep(accQ[k], imQneg[k]) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[k]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[k]), - } - result = pr.MulBy014(result, &l0.R1, &l0.R0) - l1 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l1.R0, xNegOverY[k]), - R1: *pr.curveF.MulMod(&l1.R1, yInv[k]), - } - result = pr.MulBy014(result, &l1.R1, &l1.R0) - case -1: - accQ[k], l0, l1 = pr.doubleAndAddStep(accQ[k], negQ[k]) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[k]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[k]), - } - result = pr.MulBy014(result, &l0.R1, &l0.R0) - l1 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l1.R0, xNegOverY[k]), - R1: *pr.curveF.MulMod(&l1.R1, yInv[k]), - } - result = pr.MulBy014(result, &l1.R1, &l1.R0) - case 0: - accQ[k], l0 = pr.doubleStep(accQ[k]) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[k]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[k]), - } - result = pr.MulBy014(result, &l0.R1, &l0.R0) - case 1: - accQ[k], l0, l1 = pr.doubleAndAddStep(accQ[k], Q[k]) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[k]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[k]), - } - result = pr.MulBy014(result, &l0.R1, &l0.R0) - l1 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l1.R0, xNegOverY[k]), - R1: *pr.curveF.MulMod(&l1.R1, yInv[k]), - } - result = pr.MulBy014(result, &l1.R1, &l1.R0) - case 3: - accQ[k], l0, l1 = pr.doubleAndAddStep(accQ[k], imQ[k]) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[k]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[k]), - } - result = pr.MulBy014(result, &l0.R1, &l0.R0) - l1 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l1.R0, xNegOverY[k]), - R1: *pr.curveF.MulMod(&l1.R1, yInv[k]), - } - result = pr.MulBy014(result, &l1.R1, &l1.R0) - default: - return nil, errors.New("invalid loopCounter") - } + result = pr.MulBy014(result, + pr.curveF.MulMod(&lines[k][0][i].R1, yInv[k]), + pr.curveF.MulMod(&lines[k][0][i].R0, xNegOverY[k]), + ) } - } - // i = 0, j = -3 - // The resulting accumulator point is the infinity point because - // [(x₀+1) + λ(x₀³-x₀²-x₀)]Q = [3(x₀-1)² ⋅ r]Q = ∞ - // since we're using affine coordinates, the addStep in the last iteration - // (j=-3) will fail as the slope of a vertical line in indefinite. But in - // projective coordinates, vertinal lines meet at (0:1:0) so the result - // should be unchanged if we ommit the addStep in this case. Moreover we - // just compute before the tangent line and not the full doubleStep as we - // only care about the Miller loop result in Fp6 and not the point itself. - result = pr.Square(result) - for k := 0; k < n; k++ { - l0 = pr.tangentCompute(accQ[k]) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[k]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[k]), + if i > 0 && loopCounter2[i]*3+loopCounter1[i] != 0 { + for k := 0; k < n; k++ { + result = pr.MulBy014(result, + pr.curveF.MulMod(&lines[k][1][i].R1, yInv[k]), + pr.curveF.MulMod(&lines[k][1][i].R0, xNegOverY[k]), + ) + } } - result = pr.MulBy014(result, &l0.R1, &l0.R0) } return result, nil @@ -371,7 +305,7 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) { // addStep adds two points in affine coordinates, and evaluates the line in Miller loop // https://eprint.iacr.org/2022/1162 (Section 6.1) -func (pr Pairing) addStep(p1, p2 *G2Affine) (*G2Affine, *lineEvaluation) { +func (pr Pairing) addStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation) { // compute λ = (y2-y1)/(x2-x1) p2ypy := pr.curveF.Sub(&p2.Y, &p1.Y) @@ -388,7 +322,7 @@ func (pr Pairing) addStep(p1, p2 *G2Affine) (*G2Affine, *lineEvaluation) { λpxrx := pr.curveF.Mul(λ, pxrx) yr := pr.curveF.Sub(λpxrx, &p1.Y) - var res G2Affine + var res g2AffP res.X = *xr res.Y = *yr @@ -403,10 +337,10 @@ func (pr Pairing) addStep(p1, p2 *G2Affine) (*G2Affine, *lineEvaluation) { // doubleAndAddStep doubles p1 and adds p2 to the result in affine coordinates, and evaluates the line in Miller loop // https://eprint.iacr.org/2022/1162 (Section 6.1) -func (pr Pairing) doubleAndAddStep(p1, p2 *G2Affine) (*G2Affine, *lineEvaluation, *lineEvaluation) { +func (pr Pairing) doubleAndAddStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *lineEvaluation) { var line1, line2 lineEvaluation - var p G2Affine + var p g2AffP // compute λ1 = (y2-y1)/(x2-x1) n := pr.curveF.Sub(&p1.Y, &p2.Y) @@ -455,9 +389,9 @@ func (pr Pairing) doubleAndAddStep(p1, p2 *G2Affine) (*G2Affine, *lineEvaluation // doubleStep doubles a point in affine coordinates, and evaluates the line in Miller loop // https://eprint.iacr.org/2022/1162 (Section 6.1) -func (pr Pairing) doubleStep(p1 *G2Affine) (*G2Affine, *lineEvaluation) { +func (pr Pairing) doubleStep(p1 *g2AffP) (*g2AffP, *lineEvaluation) { - var p G2Affine + var p g2AffP var line lineEvaluation // λ = 3x²/2y @@ -489,7 +423,7 @@ func (pr Pairing) doubleStep(p1 *G2Affine) (*G2Affine, *lineEvaluation) { } // tangentCompute computes the line that goes through p1 and p2 but does not compute p1+p2 -func (pr Pairing) tangentCompute(p1 *G2Affine) *lineEvaluation { +func (pr Pairing) tangentCompute(p1 *g2AffP) *lineEvaluation { // λ = 3x²/2y n := pr.curveF.Mul(&p1.X, &p1.X) @@ -506,266 +440,3 @@ func (pr Pairing) tangentCompute(p1 *G2Affine) *lineEvaluation { return &line } - -// ---------------------------- -// Fixed-argument pairing -// ---------------------------- -// -// The second argument Q is g2 the fixed canonical generator of G2. -// -// g2.X = 0x110133241d9b816c852a82e69d660f9d61053aac5a7115f4c06201013890f6d26b41c5dab3da268734ec3f1f09feb58c5bbcae9ac70e7c7963317a300e1b6bace6948cb3cd208d700e96efbc2ad54b06410cf4fe1bf995ba830c194cd025f1c -// g2.Y = 0x17c3357761369f8179eb10e4b6d2dc26b7cf9acec2181c81a78e2753ffe3160a1d86c80b95a59c94c97eb733293fef64f293dbd2c712b88906c170ffa823003ea96fcd504affc758aa2d3a3c5a02a591ec0594f9eac689eb70a16728c73b61 - -// MillerLoopFixed computes the single Miller loop -// fᵢ_{x₀+1+λ(x₀³-x₀²-x₀),Qᵢ}(Pᵢ), where g2 is fixed. -func (pr Pairing) MillerLoopFixedQ(P *G1Affine) (*GTEl, error) { - - // P and Q are supposed to be on G1 and G2 respectively of prime order r. - // The point (x,0) is of order 2. But this function does not check - // subgroup membership. - yInv := pr.curveF.Inverse(&P.Y) - xNegOverY := pr.curveF.MulMod(&P.X, yInv) - xNegOverY = pr.curveF.Neg(xNegOverY) - - // f_{x₀+1+λ(x₀³-x₀²-x₀),Q}(P) - result := pr.Ext6.One() - - // i = 188, separately to avoid an E6 Square - // (Square(res) = 1² = 1) - // and avoid MulBy014 (res × ℓ) - // (assign line to res) - result = &fields_bw6761.E6{ - B0: fields_bw6761.E3{ - A0: *pr.curveF.MulMod(&pr.lines[1][188], yInv), - A1: *pr.curveF.MulMod(&pr.lines[0][188], xNegOverY), - A2: result.B0.A2, - }, - B1: fields_bw6761.E3{ - A0: result.B1.A0, - A1: *pr.curveF.One(), - A2: result.B1.A2, - }, - } - - for i := 187; i >= 1; i-- { - // mutualize the square among n Miller loops - // (∏ᵢfᵢ)² - result = pr.Square(result) - - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[1][i], yInv), - pr.curveF.MulMod(&pr.lines[0][i], xNegOverY), - ) - - if loopCounter2[i]*3+loopCounter1[i] != 0 { - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[3][i], yInv), - pr.curveF.MulMod(&pr.lines[2][i], xNegOverY), - ) - } - } - - // i = 0 - result = pr.Square(result) - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[1][0], yInv), - pr.curveF.MulMod(&pr.lines[0][0], xNegOverY), - ) - - return result, nil -} - -// DoubleMillerLoopFixedQ computes the double Miller loop -// fᵢ_{u,g2}(T) * fᵢ_{u,Q}(P), where g2 is fixed. -func (pr Pairing) DoubleMillerLoopFixedQ(P [2]*G1Affine, Q *G2Affine) (*GTEl, error) { - - // P and Q are supposed to be on G1 and G2 respectively of prime order r. - // The point (x,0) is of order 2. But this function does not check - // subgroup membership. - yInv := make([]*emulated.Element[BaseField], 2) - xNegOverY := make([]*emulated.Element[BaseField], 2) - yInv[1] = pr.curveF.Inverse(&P[1].Y) - xNegOverY[1] = pr.curveF.MulMod(&P[1].X, yInv[1]) - xNegOverY[1] = pr.curveF.Neg(xNegOverY[1]) - yInv[0] = pr.curveF.Inverse(&P[0].Y) - xNegOverY[0] = pr.curveF.MulMod(&P[0].X, yInv[0]) - xNegOverY[0] = pr.curveF.Neg(xNegOverY[0]) - // negQ = -Q = (x, -y) - negQ := &G1Affine{X: Q.X, Y: *pr.curveF.Neg(&Q.Y)} - // imQ = (w*x, -y) - imQ := &G1Affine{X: *pr.curveF.MulMod(&Q.X, &thirdRootOne), Y: negQ.Y} - // imQneg = (w*x, y) - imQneg := &G1Affine{X: imQ.X, Y: Q.Y} - // point accumulator initialized to imQ - accQ := imQ - - // f_{x₀+1+λ(x₀³-x₀²-x₀),Q}(P[1]) - result := pr.Ext6.One() - var l0, l1 *lineEvaluation - - for i := 188; i >= 1; i-- { - // mutualize the square among n Miller loops - // (∏ᵢfᵢ)² - result = pr.Square(result) - - j := loopCounter2[i]*3 + loopCounter1[i] - - switch j { - // cases -4, -2, 2 and 4 are omitted as they do not occur given the - // static loop counters. - case -3: - accQ, l0, l1 = pr.doubleAndAddStep(accQ, imQneg) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[1]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[1]), - } - result = pr.MulBy014(result, &l0.R1, &l0.R0) - l1 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l1.R0, xNegOverY[1]), - R1: *pr.curveF.MulMod(&l1.R1, yInv[1]), - } - result = pr.MulBy014(result, &l1.R1, &l1.R0) - - // fixed-argument - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[1][i], yInv[0]), - pr.curveF.MulMod(&pr.lines[0][i], xNegOverY[0]), - ) - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[3][i], yInv[0]), - pr.curveF.MulMod(&pr.lines[2][i], xNegOverY[0]), - ) - case -1: - accQ, l0, l1 = pr.doubleAndAddStep(accQ, negQ) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[1]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[1]), - } - result = pr.MulBy014(result, &l0.R1, &l0.R0) - l1 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l1.R0, xNegOverY[1]), - R1: *pr.curveF.MulMod(&l1.R1, yInv[1]), - } - result = pr.MulBy014(result, &l1.R1, &l1.R0) - - // fixed-argument - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[1][i], yInv[0]), - pr.curveF.MulMod(&pr.lines[0][i], xNegOverY[0]), - ) - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[3][i], yInv[0]), - pr.curveF.MulMod(&pr.lines[2][i], xNegOverY[0]), - ) - case 0: - accQ, l0 = pr.doubleStep(accQ) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[1]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[1]), - } - result = pr.MulBy014(result, &l0.R1, &l0.R0) - - // fixed-argument - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[1][i], yInv[0]), - pr.curveF.MulMod(&pr.lines[0][i], xNegOverY[0]), - ) - case 1: - accQ, l0, l1 = pr.doubleAndAddStep(accQ, Q) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[1]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[1]), - } - result = pr.MulBy014(result, &l0.R1, &l0.R0) - l1 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l1.R0, xNegOverY[1]), - R1: *pr.curveF.MulMod(&l1.R1, yInv[1]), - } - result = pr.MulBy014(result, &l1.R1, &l1.R0) - - // fixed-argument - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[1][i], yInv[0]), - pr.curveF.MulMod(&pr.lines[0][i], xNegOverY[0]), - ) - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[3][i], yInv[0]), - pr.curveF.MulMod(&pr.lines[2][i], xNegOverY[0]), - ) - case 3: - accQ, l0, l1 = pr.doubleAndAddStep(accQ, imQ) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[1]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[1]), - } - result = pr.MulBy014(result, &l0.R1, &l0.R0) - l1 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l1.R0, xNegOverY[1]), - R1: *pr.curveF.MulMod(&l1.R1, yInv[1]), - } - result = pr.MulBy014(result, &l1.R1, &l1.R0) - - // fixed-argument - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[1][i], yInv[0]), - pr.curveF.MulMod(&pr.lines[0][i], xNegOverY[0]), - ) - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[3][i], yInv[0]), - pr.curveF.MulMod(&pr.lines[2][i], xNegOverY[0]), - ) - default: - return nil, errors.New("invalid loopCounter") - } - } - - // i = 0, j = -3 - // The resulting accumulator point is the infinity point because - // [(x₀+1) + λ(x₀³-x₀²-x₀)]Q = [3(x₀-1)² ⋅ r]Q = ∞ - // since we're using affine coordinates, the addStep in the last iteration - // (j=-3) will fail as the slope of a vertical line in indefinite. But in - // projective coordinates, vertinal lines meet at (0:1:0) so the result - // should be unchanged if we ommit the addStep in this case. Moreover we - // just compute before the tangent line and not the full doubleStep as we - // only care about the Miller loop result in Fp6 and not the point itself. - result = pr.Square(result) - l0 = pr.tangentCompute(accQ) - l0 = &lineEvaluation{ - R0: *pr.curveF.MulMod(&l0.R0, xNegOverY[1]), - R1: *pr.curveF.MulMod(&l0.R1, yInv[1]), - } - result = pr.MulBy014(result, &l0.R1, &l0.R0) - // fixed-argument - result = pr.MulBy014(result, - pr.curveF.MulMod(&pr.lines[1][0], yInv[0]), - pr.curveF.MulMod(&pr.lines[0][0], xNegOverY[0]), - ) - - return result, nil -} - -// PairFixedQ calculates the reduced pairing for a set of points -// e(P, g2), where g2 is fixed. -// -// This function doesn't check that the inputs are in the correct subgroups. -func (pr Pairing) PairFixedQ(P *G1Affine) (*GTEl, error) { - res, err := pr.MillerLoopFixedQ(P) - if err != nil { - return nil, fmt.Errorf("miller loop: %w", err) - } - res = pr.FinalExponentiation(res) - return res, nil -} - -// DoublePairFixedQ calculates the reduced pairing for a set of points -// e(P, Q) * e(T, g2), where g2 is fixed. -// -// This function doesn't check that the inputs are in the correct subgroups. -func (pr Pairing) DoublePairFixedQ(P [2]*G1Affine, Q *G2Affine) (*GTEl, error) { - res, err := pr.DoubleMillerLoopFixedQ(P, Q) - if err != nil { - return nil, fmt.Errorf("double miller loop: %w", err) - } - res = pr.FinalExponentiation(res) - return res, nil -} diff --git a/std/algebra/emulated/sw_bw6761/pairing_test.go b/std/algebra/emulated/sw_bw6761/pairing_test.go index 48de9bf9e0..87ec008826 100644 --- a/std/algebra/emulated/sw_bw6761/pairing_test.go +++ b/std/algebra/emulated/sw_bw6761/pairing_test.go @@ -94,6 +94,20 @@ func TestPairTestSolve(t *testing.T) { assert.NoError(err) } +func TestPairFixedTestSolve(t *testing.T) { + assert := test.NewAssert(t) + p, q := randomG1G2Affines() + res, err := bw6761.Pair([]bw6761.G1Affine{p}, []bw6761.G2Affine{q}) + assert.NoError(err) + witness := PairCircuit{ + InG1: NewG1Affine(p), + InG2: NewG2AffineFixed(q), + Res: NewGTEl(res), + } + err = test.IsSolved(&PairCircuit{InG2: NewG2AffineFixedPlaceholder()}, &witness, ecc.BN254.ScalarField()) + assert.NoError(err) +} + type MultiPairCircuit struct { InG1 G1Affine InG2 G2Affine @@ -180,84 +194,6 @@ func TestPairingCheckTestSolve(t *testing.T) { assert.NoError(err) } -// ---------------------------- -// Fixed-argument pairing -// ---------------------------- -// -// The second argument Q is the fixed canonical generator of G2. -// -// g2.X = 0x110133241d9b816c852a82e69d660f9d61053aac5a7115f4c06201013890f6d26b41c5dab3da268734ec3f1f09feb58c5bbcae9ac70e7c7963317a300e1b6bace6948cb3cd208d700e96efbc2ad54b06410cf4fe1bf995ba830c194cd025f1c -// g2.Y = 0x17c3357761369f8179eb10e4b6d2dc26b7cf9acec2181c81a78e2753ffe3160a1d86c80b95a59c94c97eb733293fef64f293dbd2c712b88906c170ffa823003ea96fcd504affc758aa2d3a3c5a02a591ec0594f9eac689eb70a16728c73b61 - -type PairFixedCircuit struct { - InG1 G1Affine - Res GTEl -} - -func (c *PairFixedCircuit) Define(api frontend.API) error { - pairing, err := NewPairing(api) - if err != nil { - return fmt.Errorf("new pairing: %w", err) - } - res, err := pairing.PairFixedQ(&c.InG1) - if err != nil { - return fmt.Errorf("pair: %w", err) - } - pairing.AssertIsEqual(res, &c.Res) - return nil -} - -func TestPairFixedTestSolve(t *testing.T) { - assert := test.NewAssert(t) - p, _ := randomG1G2Affines() - _, _, _, G2AffGen := bw6761.Generators() - res, err := bw6761.Pair([]bw6761.G1Affine{p}, []bw6761.G2Affine{G2AffGen}) - assert.NoError(err) - witness := PairFixedCircuit{ - InG1: NewG1Affine(p), - Res: NewGTEl(res), - } - err = test.IsSolved(&PairFixedCircuit{}, &witness, ecc.BN254.ScalarField()) - assert.NoError(err) -} - -type DoublePairFixedCircuit struct { - In1G1 G1Affine - In2G1 G1Affine - In1G2 G2Affine - Res GTEl -} - -func (c *DoublePairFixedCircuit) Define(api frontend.API) error { - pairing, err := NewPairing(api) - if err != nil { - return fmt.Errorf("new pairing: %w", err) - } - res, err := pairing.DoublePairFixedQ([2]*G1Affine{&c.In1G1, &c.In2G1}, &c.In1G2) - if err != nil { - return fmt.Errorf("pair: %w", err) - } - pairing.AssertIsEqual(res, &c.Res) - return nil -} - -func TestDoublePairFixedTestSolve(t *testing.T) { - assert := test.NewAssert(t) - p1, q := randomG1G2Affines() - p2, _ := randomG1G2Affines() - _, _, _, G2AffGen := bw6761.Generators() - res, err := bw6761.Pair([]bw6761.G1Affine{p1, p2}, []bw6761.G2Affine{G2AffGen, q}) - assert.NoError(err) - witness := DoublePairFixedCircuit{ - In1G1: NewG1Affine(p1), - In2G1: NewG1Affine(p2), - In1G2: NewG2Affine(q), - Res: NewGTEl(res), - } - err = test.IsSolved(&DoublePairFixedCircuit{}, &witness, ecc.BN254.ScalarField()) - assert.NoError(err) -} - // bench func BenchmarkPairing(b *testing.B) { diff --git a/std/algebra/emulated/sw_bw6761/precomputations.go b/std/algebra/emulated/sw_bw6761/precomputations.go index 0a02ff6d7b..29f049bce7 100644 --- a/std/algebra/emulated/sw_bw6761/precomputations.go +++ b/std/algebra/emulated/sw_bw6761/precomputations.go @@ -1,669 +1,69 @@ package sw_bw6761 import ( - "sync" - + bw6761 "github.com/consensys/gnark-crypto/ecc/bw6-761" "github.com/consensys/gnark/std/math/emulated" ) -// precomputed lines going through Q and multiples of Q -// where Q is the fixed canonical generator of G2 -// -// Q.X = 0x110133241d9b816c852a82e69d660f9d61053aac5a7115f4c06201013890f6d26b41c5dab3da268734ec3f1f09feb58c5bbcae9ac70e7c7963317a300e1b6bace6948cb3cd208d700e96efbc2ad54b06410cf4fe1bf995ba830c194cd025f1c -// Q.Y = 0x17c3357761369f8179eb10e4b6d2dc26b7cf9acec2181c81a78e2753ffe3160a1d86c80b95a59c94c97eb733293fef64f293dbd2c712b88906c170ffa823003ea96fcd504affc758aa2d3a3c5a02a591ec0594f9eac689eb70a16728c73b61 - -type baseEl = emulated.Element[BaseField] - -var precomputedLines [4][189]baseEl -var precomputedLinesOnce sync.Once +// lineEvaluation represents a sparse Fp6 Elmt (result of the line evaluation) +// line: 1 + R0(x/y) + R1(1/y) = 0 instead of R0'*y + R1'*x + R2' = 0 This +// makes the multiplication by lines (MulBy014) +type lineEvaluation struct { + R0, R1 emulated.Element[BaseField] +} +type lineEvaluations [2][len(bw6761.LoopCounter) - 1]*lineEvaluation -func getPrecomputedLines() [4][189]baseEl { - precomputedLinesOnce.Do(func() { - precomputedLines = computePrecomputedLines() - }) - return precomputedLines +func precomputeLines(Q bw6761.G2Affine) lineEvaluations { + var cLines lineEvaluations + nLines := bw6761.PrecomputeLines(Q) + for j := range cLines[0] { + cLines[0][j] = &lineEvaluation{ + R0: emulated.ValueOf[BaseField](nLines[0][j].R0), + R1: emulated.ValueOf[BaseField](nLines[0][j].R1), + } + cLines[1][j] = &lineEvaluation{ + R0: emulated.ValueOf[BaseField](nLines[1][j].R0), + R1: emulated.ValueOf[BaseField](nLines[1][j].R1), + } + } + return cLines } -func computePrecomputedLines() [4][189]baseEl { - var PrecomputedLines [4][189]baseEl - // i = 188 j = 0 - PrecomputedLines[0][188] = emulated.ValueOf[BaseField]("4601722206214295589033088118535164033177870656592393416182096720489015375349530497029363906228062576089643123713140574049771600086112717246828284242782907384274009546064259364292020067384886633838728785085024491886709733695441232") - PrecomputedLines[1][188] = emulated.ValueOf[BaseField]("3236784823006863466220910026173765602174401950878036630758358824838437862247058427793759575023892215394054069008320620643640558315304032361447991476750076954187501466307705591468937850275918000275643689484882669396511455818909363") - // i = 187 j = 0 - PrecomputedLines[0][187] = emulated.ValueOf[BaseField]("4284789655013537363710179286068174786772309617997172492875713618334010224041698623742954093647630044979590696811111164975595092645867490218999600504619327786427075567895145591027412670194923356675080657179976322498310050902640523") - PrecomputedLines[1][187] = emulated.ValueOf[BaseField]("3397077585795497770574956326615748114624499481864974680679794687756340652124038636739703112837391756600057731371987592607050612125672213939529572905167024548876842558316659173179147459198230753321661513330822067010574384973022555") - // i = 186 j = 3 - PrecomputedLines[0][186] = emulated.ValueOf[BaseField]("1091218109139043282885863378251414023636707952314494512372017652056066775447345582100836025388344721550644843738483035932390251464065810927296998086029013978640474160190153308907248340838991167773800991890772343915279880213727062") - PrecomputedLines[1][186] = emulated.ValueOf[BaseField]("1932776294962294607326429681443867590647757998709969192146711063851317722986642914651257815274395176263091471604122034263563029802869462271974741247507241537190216497945753260923732481508423404907321219572689937399399368195704348") - PrecomputedLines[2][186] = emulated.ValueOf[BaseField]("1167511316335148398324667389573191338189911188523766691946541436850923544315370902735475929874422878371203198033582100003913387275481716694511228659348082334915004259698541139727514336425787780973815806097545196965816776735499316") - PrecomputedLines[3][186] = emulated.ValueOf[BaseField]("2232147160804702884423918597342996957835298299780156070425000360564717706225474915966264161194163856897624977960159816970762695368466669819933690851287248431427008562532340374129779212941298363468687914653260398814409814536898700") - // i = 185 j = 0 - PrecomputedLines[0][185] = emulated.ValueOf[BaseField]("4306004365533618104109465014384942345157633268446223951065825943259943902363054326485029738013348784033879397763697209004558286305504012553322685432568902284266798288509918199237758986260160353745025118056507076964718412200474980") - PrecomputedLines[1][185] = emulated.ValueOf[BaseField]("5317846815027928872027613253615316395074256905491637198887969705823256420589631614168749537597578371751367448584458328091779472154865596580401722980439239350433503000609691988033596752719329540220674293362655543781993007414133383") - // i = 184 j = 0 - PrecomputedLines[0][184] = emulated.ValueOf[BaseField]("6421916924517227492429982731209978531258674731359925152390387866121182338289516345823943563081211701852337791457795568248902135968560498937316951201929059763508154635231637895327320269539372239958994090925499869310860986253930201") - PrecomputedLines[1][184] = emulated.ValueOf[BaseField]("1686639416390596371553909149095788961102940263395631521907287043550337997450943996462705979234109248163103596400703514709833294645758815792512648361448153221566523943762780235884649119800769196410541762065839619252631807329090400") - // i = 183 j = 0 - PrecomputedLines[0][183] = emulated.ValueOf[BaseField]("114180830592984977608620197891299258218097289300462265571701992566828885245678086954282598493180224315526740165796002388700857620749087925225196526364545673995004707545174481617926132341198681064474105987363733245947798260480021") - PrecomputedLines[1][183] = emulated.ValueOf[BaseField]("3643314528606611673549077340603412386053042463599462417346484334589212006592934006344061880772131103404526782421964102589866962439448410017161380283698685419352722215199790426320563536567649897993742663645650081369281521868591534") - // i = 182 j = 0 - PrecomputedLines[0][182] = emulated.ValueOf[BaseField]("1688781593013252202379324989130651254204553658263455673413039374103132244330512227184037116111497079310793760489525262660487540543772659221909636681163656965516816665546804331362111396729665567623773273510723669438274720439381576") - PrecomputedLines[1][182] = emulated.ValueOf[BaseField]("5193662126481262079756387379977171046664714957086394774928779609243972397458622726105179616127621272398676788700476587946061649662787381825305427284456092085078167585950026775781619955464645576626263196914090116793028720585355481") - // i = 181 j = 0 - PrecomputedLines[0][181] = emulated.ValueOf[BaseField]("6209325124145239397598057826971218736702656412059021495624233205137199082483268094371872462575283057254647931585279829235136285083590372314804121031720427317525847055896280145588498274054925464619306135927111436825130374258987514") - PrecomputedLines[1][181] = emulated.ValueOf[BaseField]("1010036127161986089883406275933044583728615228275798613559152479035653938286105077506616278778086885698838149352983372472274935209107911460860800570032291053269269264676570250105939952537570296490530893420393830672599263484907593") - // i = 180 j = -3 - PrecomputedLines[0][180] = emulated.ValueOf[BaseField]("3916228906012440253680477868908277251188577745381915527147519311139261470401587060157132237422167594920897130917968660806249831166496286071990001152498332736769111249089722262822452866904553313342810671126322183997326609281401583") - PrecomputedLines[1][180] = emulated.ValueOf[BaseField]("3435089271581010462145195911014096957530126526254735357340434973538495700622046265485990757746992495980170396689021322325804572193781170277216716200627690025249089996091294085258675338244847987082579742015932982288506050846801367") - PrecomputedLines[2][180] = emulated.ValueOf[BaseField]("2092456650515366730031987771316607202541762165703719836977478738322079795443253020269257496488401455876600213975362916923917314143513070424323372549014825342086761376907156571063602331303475993817855431561965996939828394721782593") - PrecomputedLines[3][180] = emulated.ValueOf[BaseField]("6122599343245408702600384763049321564036931568283100932099921667936978634943943045806116525776697821713388531514318882641704622862282367112968413235610663665510382250760330294750688640834276927034495199398556442136786749389317895") - // i = 179 j = 0 - PrecomputedLines[0][179] = emulated.ValueOf[BaseField]("2511580551397099010509156635216328707755934194815457044079051714639178304720486457528769378752459457724113502551911503989967751565016715972609480447192036056055039234581972315469267363618696732916527984903826194214600735642319929") - PrecomputedLines[1][179] = emulated.ValueOf[BaseField]("5236472788607503982524038470940158051826098915931331379976687924803796292051708055582509266856976616002835930583332408804995941668529244992278273158141526570518774812582018031213946165449114235122523836895477325571581042012028314") - // i = 178 j = -3 - PrecomputedLines[0][178] = emulated.ValueOf[BaseField]("1800040314478109155379981516978971807927978753985771292093243510338787993118579044453988179372350623657128285404863657231415514828304930341219926840787023926783731174197374231588404417124836232214161233727655561791136924294415108") - PrecomputedLines[1][178] = emulated.ValueOf[BaseField]("2804331434973313747360020974539045142189940350869252061028836865792880045822923060547593583152729801334865015365392914719118701386614928096404458139252733417581429421730546318906704389393001623046225620830318086821332624756683051") - PrecomputedLines[2][178] = emulated.ValueOf[BaseField]("4010999921375805968870272930021879668093105275880304512189843893600197903154276931811822077163095190015328087423981272784184916779390182971756524393178302760547186651561079225545153363602239291122847568838787351267442061099216202") - PrecomputedLines[3][178] = emulated.ValueOf[BaseField]("6584340050018347280681423899606339541161987220622923184308043318586136566115378253810690431289328806239175170506538394612454436990768398488496929349106290361186183199132928039289063200363255216189738034088179050204170911896584164") - // i = 177 j = 0 - PrecomputedLines[0][177] = emulated.ValueOf[BaseField]("1726061023290836353179062634745502209899779569524834789308289547123213283973848080035664750629441061589219352338927276240139068374410873973059216682750238724779941510904773266077989956039532262991092557793969212159854495230862985") - PrecomputedLines[1][177] = emulated.ValueOf[BaseField]("1869481926743730917071424311764961273208736749090789559157861316592814440537481639260176341853100863466049497097529708062437289228998726553060613609659652146673372729676870794229410647181863143859417329385468871464108699012273846") - // i = 176 j = 3 - PrecomputedLines[0][176] = emulated.ValueOf[BaseField]("1793856615109417544088516938753960964286334983251529993717647594862500706265566364226045939516389855497516791858306940602084518785322491855363658977981397037532005228517905667670972924240011942702220857789530663664665855554661222") - PrecomputedLines[1][176] = emulated.ValueOf[BaseField]("6395681833640894351709246408264671690875088694587688739687699328485856788238236843578177291133035935076604936426130742942110635837371378818936098673000308956223463158303247180215145841735445353551571220444236560630404547986209151") - PrecomputedLines[2][176] = emulated.ValueOf[BaseField]("2658682327531363340886128523639936936794527892563754531362906969704238916622746439525897392384544276189617954255779173048784430461921811078498554047189350865557776717733143006886329081619462673131362508883137636048162229001001752") - PrecomputedLines[3][176] = emulated.ValueOf[BaseField]("5617554506492221938975106502341524911009083485697351396054750293054330722247646308915037251220568495308451049624878789498457236602788959655661892769719935053597205105831249795638145145160065336641583965498951605487903540981050802") - // i = 175 j = 0 - PrecomputedLines[0][175] = emulated.ValueOf[BaseField]("4470825980738541959726721215854613341075368401570063568735045574729298521280405311388012358627027886827869852758362621710083501885879349449153525400484725770873456029339549390419942617945037345005301748390450340592093970111359648") - PrecomputedLines[1][175] = emulated.ValueOf[BaseField]("1920568269358036725699475088712901539873940686097511566671943459117851140609958127041667654873888431108367861061290576749035032066751452068241877286059270867844790516311803884123933497833146654049795784282665587712174325905132873") - // i = 174 j = 0 - PrecomputedLines[0][174] = emulated.ValueOf[BaseField]("5291384463484550783828111596416354076934608698798352210861001411148434599869192035754382317926833597940265596903863701701788020967880271864100145931495422846851649251335105459602027077341966720233978984790404433500118923981944200") - PrecomputedLines[1][174] = emulated.ValueOf[BaseField]("3474094727155888343948366737511294507806212772178038965971065737773346795180126935784209107320980882788680952477240615967935772085115185124196534170261596941607671230574363788110421854443479506298253443971821547731182829113123758") - // i = 173 j = 0 - PrecomputedLines[0][173] = emulated.ValueOf[BaseField]("291159196638023833126170878103962505591607284608066095971122730560627573500586990219507525188803791560522939176145008398336699153787221653227248248679740995364715081700438265042240313974596422431379084154243300992164241337305047") - PrecomputedLines[1][173] = emulated.ValueOf[BaseField]("6637317848210107927777296198352103696418016960893139157040698743859956793987416974109447386120759632207128207385903665276310974970806579773735756047615944951621704212430487647997793051862976764280585794774975775226509571642012340") - // i = 172 j = 3 - PrecomputedLines[0][172] = emulated.ValueOf[BaseField]("2896810465976073493801911194359719472039621862530606610348926118077429042177497167032204517123568128544943241127796124713416640564286772536699713462008786003585732747296391431773911293376178622434550785330571364764018950598140281") - PrecomputedLines[1][172] = emulated.ValueOf[BaseField]("4467780101676510281057903463361611394824850531998065167477996007953191976696291514533668019146536239987670464917412247254495086054690728549700926765864200643470435884309849171046000608577799964445823074181488503901546261068862692") - PrecomputedLines[2][172] = emulated.ValueOf[BaseField]("6272874977137170475628881314521834520164802977112863597206461767527978691719236433645395640481127588156828153563372518828973086791188240123830748726657346202491578701145062590487795733410523861316913042654984845940431454041270826") - PrecomputedLines[3][172] = emulated.ValueOf[BaseField]("1491519716322459721476131635974774555179040450041728831056366076429022306831905396756755500249298779816133035692361613992371069670991372872597941652981525923051283306282081842575371025653013841958071420611736931252604211356071193") - // i = 171 j = 0 - PrecomputedLines[0][171] = emulated.ValueOf[BaseField]("6235152558585444833493261246207340539804815046978363622291717651978489706660435740588616632493125821972920945508541635592163696120037180705138229828421746317536693647276274336413212776398698284731916429701610474931192570311724369") - PrecomputedLines[1][171] = emulated.ValueOf[BaseField]("2242672995139372462518294141548297566108953081821049993780338631576943780891567110286309915075208848428813595805761752053821655145068096776825637230030519832332866845461170464293849009631853717299166685335971374640413019426278822") - // i = 170 j = 3 - PrecomputedLines[0][170] = emulated.ValueOf[BaseField]("1429112810826305113526238024068625519617466029256408943654835886511226415318108590963818255082352675735276265680900244338259945649853087097891859279422169569976330990028761011846609181766104569064844095718653016473753086326169683") - PrecomputedLines[1][170] = emulated.ValueOf[BaseField]("813257970458576737350931150692350224241454191961120910165875211113010579758220571491319151091620887394870103181754304418786013541661782866413149178950930415672806510706468797621548448679182563747650309708282309926241128288673135") - PrecomputedLines[2][170] = emulated.ValueOf[BaseField]("4615750120910655458062027499234169678376889872550909552027422821903093257029585915682695214715621199838795424793869266363821929915750873802222291947479724423100732276424960820653424133885708067276050345616746879636049613871724548") - PrecomputedLines[3][170] = emulated.ValueOf[BaseField]("2638402868714127517218145901538866889787798408569326361013240257145955029560417297271208866993745742109396095491575331998333504570744548528767176847869288148827357015366601590545284586737024599703154347220653254040080070976337387") - // i = 169 j = 0 - PrecomputedLines[0][169] = emulated.ValueOf[BaseField]("5151053341945160206168664078810674786626229464615324047316643094827022265609681594014045415804609654596019048771436372513937327411900645278608871991536593143635447460485268900090456257568071987996227531987643282129888289795315787") - PrecomputedLines[1][169] = emulated.ValueOf[BaseField]("4433808739393296174309455467258529089977837943895638563487610473212932875402456433695523862673003713626322557768899732261336799338902558617024412348901220971079947263098919960666503561149253055091635599396540987777068978448589942") - // i = 168 j = -3 - PrecomputedLines[0][168] = emulated.ValueOf[BaseField]("6573223359061173030393223133587057276018849035205508504868826180775040314361353866958802262264508674286374515698526491670274560376396065049758844992950298456959398440073914900051030331074092036623459108691740030899630765167991804") - PrecomputedLines[1][168] = emulated.ValueOf[BaseField]("433563974948430427145344771367180664437544635785104771951413151629760183394516728212069088933279038869983505880491252805362319646939442623952219790532410824637016808664128139205897840527209397149113432381134849938543997936884322") - PrecomputedLines[2][168] = emulated.ValueOf[BaseField]("4780438282108523499566089886493747223520600917434700114406865073037482480152520938722159790890960945691254743766968215641137493966211783939811018374792848222347243639100762780690923695318149020751623537076408377114194177696633685") - PrecomputedLines[3][168] = emulated.ValueOf[BaseField]("4398587526357486098002805624557711076050197843122002073647939149855114862782129256464606723482050274657562960400962939800415311926127759986216984470993028744802713704731703741576155965585649125162356816261139543815225445809074181") - // i = 167 j = 0 - PrecomputedLines[0][167] = emulated.ValueOf[BaseField]("1647664286159942497853030191368343827570740490539376712617435901117835353856034051805911137507399235191594161042407712721047214542679095949784491999942252413102189504539951390607797346810193659400896920380179521693479129340870667") - PrecomputedLines[1][167] = emulated.ValueOf[BaseField]("2390287243773902242827076870477280124811775106501454290834199465068296153193080900637929806619586936243431863370083347240345585229599137089325914019290067280079041375854153097245939993055850496740464076243793307860295157220489626") - // i = 166 j = 3 - PrecomputedLines[0][166] = emulated.ValueOf[BaseField]("1709949524102589335847024052923955037315354604476833601571466852493572947268595108101545007187963974951788163063772644877512200289677146556030347420379930797247490496246244568568366831695984141657359289286221852473683503769654596") - PrecomputedLines[1][166] = emulated.ValueOf[BaseField]("5893228435550224958157425121741517506045893261892569389741766590829366373878060500577175254669696862906574707093963266493237865832467079001148718602123158286651558066342826773724504656661517285037169488249399183378203836969057275") - PrecomputedLines[2][166] = emulated.ValueOf[BaseField]("4921983716737681000020818352454095467819829881281876982451644207064948583097442692356739526117975859626329445105576138093211975899941930818396721119247635647664410038740022271464816311809170130035908923628827870553651390809645802") - PrecomputedLines[3][166] = emulated.ValueOf[BaseField]("5029845452797108141104211578426309150462531240073265769929326427375198592202381636899891851441329434234634550874094633387930815132677505491831139226402537766580191195789214542567421298499734903290553980122172973997208601705231659") - // i = 165 j = 0 - PrecomputedLines[0][165] = emulated.ValueOf[BaseField]("232572658672356797578043680617364321714987274969275103384954673212085034692277243801536023990339429694630902665031278912607605354670471863738561553739117166877166249283856098435668003254327820655318227276087352237830333067397901") - PrecomputedLines[1][165] = emulated.ValueOf[BaseField]("1177003727892546832866508390022270538418538637811025906900098412455823364300811651099613431544482191415414696640978119758171995565582917710180141194046220261448537016001183780200162781547581979982676317862484246620865147679291007") - // i = 164 j = 0 - PrecomputedLines[0][164] = emulated.ValueOf[BaseField]("2349331348722034078094792909294804855570951673402701960283569222334892024519680930010762814852187567219323305147207170737074416468468147497844346987827839689162791474940276610135929682703627664335709075399106574798477419568510404") - PrecomputedLines[1][164] = emulated.ValueOf[BaseField]("4643592453902905429004614211524140894845659434425593111572454756461288139175970093152918726074460168876790628276619819105484323910842976004056293477403091127131033849251587843923973198464228459201150194269377117357851959140188983") - // i = 163 j = 3 - PrecomputedLines[0][163] = emulated.ValueOf[BaseField]("52333827582414640990444534040624682671317644434073521325969166221486850859764683430510421110637534653003049014936771816647586553444768944089642009319835647240758299476088602838239048121990973268096414788580977151073980666905173") - PrecomputedLines[1][163] = emulated.ValueOf[BaseField]("5006684479864566702650706524533038451782099505978373537938019834872314066037685041434363897742556522136697745017124053405850753653625837991051365133733468176243186518320051581480634917947326031233212380721027184237318081704860647") - PrecomputedLines[2][163] = emulated.ValueOf[BaseField]("5395654817304820758994256808056443755302607472199986470885449004836905491060935175671751260574929678123841275884311222036169994045893346568582934629470732910646691606254245944852080137051701323813006245299620576672799106022769191") - PrecomputedLines[3][163] = emulated.ValueOf[BaseField]("650736239870954558727404407995742820117382750229335308197505424837541407737453157093401352116197759550277694567784174548449221820880569998450653552639238746278423134232062947534257012891122077779859567838318586182926302109543544") - // i = 162 j = 0 - PrecomputedLines[0][162] = emulated.ValueOf[BaseField]("966717885432164187094459687544853956185577913816048544255971196493117042692563379865241269084260979556031191892848503771930723476206819278309877985692266623192674173120914799472153518381472278820426394303797572079804504184790592") - PrecomputedLines[1][162] = emulated.ValueOf[BaseField]("3020563500188388877315150135981069820453062660195966231237216820091970048960040900415963172445058143765783985486909755563513372900233756646993726834722183040094649261040765637788368630807503529899998612992257688511729617092599566") - // i = 161 j = 0 - PrecomputedLines[0][161] = emulated.ValueOf[BaseField]("2723607430772659730961790718447048641080044768560277644165932027404231869402860898365710504322696991333576407490560210763843022332678136578931828844357649891343819627199496798332807949085545953320422192134670525530072902264941810") - PrecomputedLines[1][161] = emulated.ValueOf[BaseField]("5129647963722466620942267952017113426807349734845472346580002125338862335088074302957583315286637384286504759748385986635964533515779512711081531549908778015105442463377527732867005927843773890731693246823345607932059642142760798") - // i = 160 j = 0 - PrecomputedLines[0][160] = emulated.ValueOf[BaseField]("4577081852725837198311485026729893776093048114534072194182826126558577801376180078853990029623202669787826337303348968528811571259730377323605351607188692812693591153711457444300581467449173000389674163550804048515753424541817422") - PrecomputedLines[1][160] = emulated.ValueOf[BaseField]("6823267443517190019085934072639764787968936714958209215443747270739622300855648847686288401398497539575198945858259391975943073313266494176351501686559627127468167527194301984132678997501550728894241645116121821284329222527177962") - // i = 159 j = -3 - PrecomputedLines[0][159] = emulated.ValueOf[BaseField]("324666234286344014142243331706963725161768120676466297357473498737699334487145813076943214189021251649111237638123254146524201058991160673739004317499134741949534700426970766872442991803079017288149670074860050490378349499214790") - PrecomputedLines[1][159] = emulated.ValueOf[BaseField]("6636617842236151333529964795471565361123586529270909295929312662528628437720181288422740806930288827619317815525172605840744493547399413754001814728110749523835116156866350602345640678920229273484885229046952992387064993457157436") - PrecomputedLines[2][159] = emulated.ValueOf[BaseField]("1169179279619239804760750507913447876532533844848139969203384466214658111893717691761594819542977135521349003566911643497169771797238574098650840878350350576524995523069126926065245425919471114523133443004728427891243447229624997") - PrecomputedLines[3][159] = emulated.ValueOf[BaseField]("2390427752410237822703140443565386259958384606729063432115446405419710053220952184622592611083931480113986415359456896163696394246582897076631508221080761843074406385325595566132184951204637527250104024067754267802701541998679557") - // i = 158 j = 0 - PrecomputedLines[0][158] = emulated.ValueOf[BaseField]("3491904621617458570467400788193922471061198912031461784747449931748081025059466670568428332079097896613569081003140863723140077212586281756178360708378112359111486236347800618246901043921316993513560276265805960807878983619245559") - PrecomputedLines[1][158] = emulated.ValueOf[BaseField]("417856161039822250074025130344193295614063765635472298026365759996884135822621963191274082696570821282309331068298315248982310647089513266052159284058406772587255082241693604593372878764622714817790390306552672168290744941573972") - // i = 157 j = 3 - PrecomputedLines[0][157] = emulated.ValueOf[BaseField]("4416768778599945461484847862340231334711151920303921966291479519171793363978734600584343456569070959362086842259460846000247532597524419720784251527346762651605556856226230166708907343085002581478167277794058294334559739054882282") - PrecomputedLines[1][157] = emulated.ValueOf[BaseField]("1852250632907130188790893656467026455875589500512379999240781207064612732149124265752964795049049985863460565553287636692334980501445894984189522931023218131754348919092652254131161270167055415009583904450484090003403007608216201") - PrecomputedLines[2][157] = emulated.ValueOf[BaseField]("6419587158487718559878776704806672864160369506950210711711280857313527636662817583186572880263258124425113400796353147829983523112230494675357910189445382699469684963105565162531093198544478048674343136597682281113733105381561484") - PrecomputedLines[3][157] = emulated.ValueOf[BaseField]("3722521298055602645113974315645129742353660711003216708553366823782751701485535270778468429985655461253844592752384773735943768616708965636222693924487722919702682456701829091211690631752269481530604403689987227114111118801741291") - // i = 156 j = 0 - PrecomputedLines[0][156] = emulated.ValueOf[BaseField]("5545397166873684773113053583641661672108126538637820134423766600317555663306128116352446557181332464485047243194281156743833711442696272262603883214065623959398816145024510953571106836545478602195020059304848842043236857015989475") - PrecomputedLines[1][156] = emulated.ValueOf[BaseField]("2021590172970888707299215336977681125009536065721635254366967178736120889484508938106586665954402299023024059935122342894157282324534073308900827186536479866968034667597034915763748285429919026521587470306288580300219266936435751") - // i = 155 j = -3 - PrecomputedLines[0][155] = emulated.ValueOf[BaseField]("2016865517214075442991619362432436346237505752533125825957302068177615343035502121762958126205312972599032371564787346477939284797660841551376056858103023635292164833972540987459452711445577182426858038678074119933397740796188486") - PrecomputedLines[1][155] = emulated.ValueOf[BaseField]("4921345336829462778422198035628471967952412359162858241819721707968328922396138974134758163031865261007952041010331403775328345606360716582715294577475815722137271438236084963126900294584198188573469683598274793001598489599256460") - PrecomputedLines[2][155] = emulated.ValueOf[BaseField]("5452289706620705804122345049563462587304628763777977219263610747055789773510449643975645265547749639659444244640337694551203034035261233368893792061960538755835274166778837905048877917573980193672340922379035547913555181646229675") - PrecomputedLines[3][155] = emulated.ValueOf[BaseField]("5330445646284714072427223464819908250873719099893171438520402130309158016777695740685710535487563917271490762774254768988035428482089657277539422521799971990067449345899767156841349406799431919183289922328930736393420384380134402") - // i = 154 j = 0 - PrecomputedLines[0][154] = emulated.ValueOf[BaseField]("253912214657176650779918926993734061117688943036911490719333378236618949753645725163602990742193281812052940313043489777988352564974178451182405372274947126939291999108991745538124642855162625248568122897774021118657024053312683") - PrecomputedLines[1][154] = emulated.ValueOf[BaseField]("90454792504233772539673107359188540647097721046630177682340822562308368630868281445493887876764666553007223881517444670503149218141008821745056939702373642828660491180908094902056900653734980980380688909835110896102319539002977") - // i = 153 j = 0 - PrecomputedLines[0][153] = emulated.ValueOf[BaseField]("6028738756457492013157559987618981254929533455069995957583780714104521228354324336665057575842907015569076760475281374260515946359427739417293714745131308832966623853621805462030358839593520487417623566459988488074177330491690115") - PrecomputedLines[1][153] = emulated.ValueOf[BaseField]("1631726893290625522967477247480127881963815714733592087840583915245097436988929044123570137356058690088183128562372529403839139498072059028902685488333113667077839046050085914776299141708527188673659500983012708933861459824370354") - // i = 152 j = -3 - PrecomputedLines[0][152] = emulated.ValueOf[BaseField]("5933803588081086836643239680396970245259265430854718440369458799593483447844770571690936853076432836031619939245130596952627136235619761911719664250570429698192340677267247016627691113223709288555832534009759604452293307865143494") - PrecomputedLines[1][152] = emulated.ValueOf[BaseField]("5550204757083904566420810705852033305679349032748397343293761160397094554860340453829269107483927221899278788731018461771943481285186546907778589805772690228002061319154636587342918455042668146557380849513813601461971655743687056") - PrecomputedLines[2][152] = emulated.ValueOf[BaseField]("5429392460871260615699079029883938895836745062461512650968419621941700112039072543911058280706056517701803479157512850062007543761793301890234430901759239345753853600059003936486418961130146759088508684002234349028962962738685068") - PrecomputedLines[3][152] = emulated.ValueOf[BaseField]("215901435142930451312237140515151372543713525366036765710265909611361979775752756507445753622709378297284041357450332076126978470060269809606181904660211968469485287903524957875773224720255771036744293584738133055279492104737994") - // i = 151 j = 0 - PrecomputedLines[0][151] = emulated.ValueOf[BaseField]("2217293244223503800342403802356275665761021417440395243162100358918795095532458487975221684743329261847466915573304126110010215444704511730329892139369564310926788959661698224464272668381456474342031548863057544802188409502254976") - PrecomputedLines[1][151] = emulated.ValueOf[BaseField]("3032194119911089122528491590697665117123806514556903354257236683855345124475823193585527248686809547112579726301073625230584295621251331002111854329737234183946579207765098307179350519051519256775154498600279600797852210708198376") - // i = 150 j = 0 - PrecomputedLines[0][150] = emulated.ValueOf[BaseField]("3317725176190874681964926700784232223615994993578507763097512731747224333990127117353469138689288343877122942681200365845677839967780121222325648610973030551825533993376537297018053710863282315262763507163658751165792166003247917") - PrecomputedLines[1][150] = emulated.ValueOf[BaseField]("5311779975568348866438266113993956098697070498926704949763810071482344968514706381575287770513988277963044893761326124770442604005626456815424800417298954303878320163148098474713806918505566913500600776461117972760217108510400910") - // i = 149 j = 0 - PrecomputedLines[0][149] = emulated.ValueOf[BaseField]("415155167990909811773274527448565627660867339446865646154781434352236186331864123798900488790219924256132831458276407042546585642359457666570994480814911450794692261305789559623175773270786604043226061133341558724866809936660719") - PrecomputedLines[1][149] = emulated.ValueOf[BaseField]("5132669865916179457696452861924723931652065582428728251052829101967757160674775905534892979784141098082940401101234100043172892634948165525152188787897019723204057104822162990347257969957048742649064916404071127374631731037783787") - // i = 148 j = 3 - PrecomputedLines[0][148] = emulated.ValueOf[BaseField]("4140004734327878216201045763193531111409413457779764546283946394296932495071554746768260262011715289440991089370686959220415992218328800724536628417686911729756470325374372983040533731696917966729370346256691263147315029964417433") - PrecomputedLines[1][148] = emulated.ValueOf[BaseField]("5178761700027705413555156019361934121977511563684255818901017175838012722352349528434988833378110316523353798871708165886738677088272124845182724155472081107868405450423263348442225855283938083889870097371759935545657257393660743") - PrecomputedLines[2][148] = emulated.ValueOf[BaseField]("4695923425938084215087822823878724487099638070602575187528539251307287838561931020132982664450582460622253248261068258993590911594659794278303802029261890344535175816521628380905890439052026981269530236011516177022689249116647786") - PrecomputedLines[3][148] = emulated.ValueOf[BaseField]("83528947143211173825194412878697539272293480449701172031899761574582354182272541367121649048326072317795681794964152795904204202564610458519701137277940395274219699446009240947218090898932240186508194787221672254383477999336292") - // i = 147 j = 0 - PrecomputedLines[0][147] = emulated.ValueOf[BaseField]("151330053509034414994578636429425902053986786209892471274991525950831207463597520422983269342506983481008826046782392196380970176079709382608576483491871347753616020923167675319120990845115558945083570810266672945358625888108975") - PrecomputedLines[1][147] = emulated.ValueOf[BaseField]("5167491934529740282963729196518203437756002188349193552571241004047127958410940743196333385903439868011966656948604086680076339273646285728893389483436487495087981055968161190372633493259530748320012260258671783021341427233010876") - // i = 146 j = 0 - PrecomputedLines[0][146] = emulated.ValueOf[BaseField]("1114470723805581119184572097688824076189102046592493285463120237308793702368235633939040330876356116630125837423184649276149246843910103071261490581616432947384638209879233093598840409201085659072783743986568100816590424861898608") - PrecomputedLines[1][146] = emulated.ValueOf[BaseField]("6478777454598824156094943494586967960469393198794904011417099271970302029910680845103571038668910097824920386480718598598173544918091048834436449425890641609187952938773707865251723261486358437197859060313186213189210893005143284") - // i = 145 j = -3 - PrecomputedLines[0][145] = emulated.ValueOf[BaseField]("5859048622402069660036399935093585979604387754240347020221644378577333395030687729583771272159017531113058916586134938926883652393431747789333732232766810000369351298331399490404676517013544774690353892825693625562225579232134104") - PrecomputedLines[1][145] = emulated.ValueOf[BaseField]("5130546493861392794307807336052690029200583399365091783170538676884818669069412208829663181252666936935600613069111913888311401666154773585381780173937110082909600581595352660767798085758658916528837369630263916920834131646570216") - PrecomputedLines[2][145] = emulated.ValueOf[BaseField]("2108411833057507512223957404319309047383861110883456473273524034749089770620099048622453493049814509579167338063647043613852813952598011253428280877972494566190259092437580681150999842418960600345792711661706349548971961797181565") - PrecomputedLines[3][145] = emulated.ValueOf[BaseField]("708505628301545791337509871984655495035967667250979838482537030174702586032171072906665305184787620631564903687145362843392236437965976088144658101185950961085417107422270026571519877928676536019489776985913311663627609273904453") - // i = 144 j = 0 - PrecomputedLines[0][144] = emulated.ValueOf[BaseField]("1110693141506833443806812185356385657611154222022956119590162362046526185899629723001989265777826816933834594500045594892823893494919273443552937721223945431485877663287749801345271403238264692363210636517643455903357602891457290") - PrecomputedLines[1][144] = emulated.ValueOf[BaseField]("603929437399447291214728195951492966191103124355063750553076589829671952973145516286561956436266736365337087448302435015635010597001789338483106033528008186612669695616779426601106014489886431783937516089415892537636015452587873") - // i = 143 j = 0 - PrecomputedLines[0][143] = emulated.ValueOf[BaseField]("1486313396257225319276454417156949032235657107769651771999072596075215391850952818655646828707669204590200946140222685601763062865837088768474997694507956127217411232824640625777584603274979885819664470425193993045396278061554670") - PrecomputedLines[1][143] = emulated.ValueOf[BaseField]("5900091056252635525061247890639784854912554186160436040691327117040239450463401250320405408025474934781221398674442720989333863513889420429293126000723066765887369389159668421318382662346470829811188424370478317951507216345256643") - // i = 142 j = 0 - PrecomputedLines[0][142] = emulated.ValueOf[BaseField]("2792214896204349446812807850849074442364083133360182878815559121269639917337029363471023254536409861081182182842928669453464821839537737772926644433219600872696347238197912222306544693056149978277507630422064429186112081667145266") - PrecomputedLines[1][142] = emulated.ValueOf[BaseField]("3944833749529436605658652267849673696497888958101001890165078244794151784397599858860254268537666046558802898859348382115556708759230970010852200503643863189853426075395343165134428906535715936830920322947079380746476083547373561") - // i = 141 j = 0 - PrecomputedLines[0][141] = emulated.ValueOf[BaseField]("417856790372798077015113846490617233071837258253813598704739825574397265998748349018546952531836869989491058332284609105381556940328508752945025067012370823786220503025032772358278513253286721537773229007859176953964580903195727") - PrecomputedLines[1][141] = emulated.ValueOf[BaseField]("3212095295566726705955520648736709733214732630239873901431866202929498890238143597713014321210267543461754987631611427191371921286136904225726012666396381699549816558028560296677824912419015468670527904167438613604543861012490881") - // i = 140 j = -3 - PrecomputedLines[0][140] = emulated.ValueOf[BaseField]("6454652960715100287228837394962613813864449960018709130892915714253696419021214154832054652581717272410134436821903319869939794983804221461689920428475008780101250011049231364935669307075928640376378229913679881637394701636737270") - PrecomputedLines[1][140] = emulated.ValueOf[BaseField]("4330478820859849211086998075624162533796478046322369047534830098235600627275134989518159311577872109499354455070789488270437693314611100870115090161624057461733224827616650657400092680610335909558941615999861146131436385364638808") - PrecomputedLines[2][140] = emulated.ValueOf[BaseField]("858293139758627108215187205269437801824125169052800366429342716136717086471757029929438123993480089882929860186241630315111576602418646305030928478620782188276456539301601359470127933194535982283045054240161101411651017048286627") - PrecomputedLines[3][140] = emulated.ValueOf[BaseField]("5227206335183556341740750730697286334874771364666852277057794888432894496595221781561994053642178607365548748041278338868871460536603201138958142818647966045713904898925900602596824373321003503289242417763131324999615120446619142") - // i = 139 j = 0 - PrecomputedLines[0][139] = emulated.ValueOf[BaseField]("6061183520623123725589769021285572001479789372351644764609461692939780384165064167719928513044495562706770395832575876513874629527231851623713680740316664822309168015470185638170819110129556875969482829992633944123125377558202569") - PrecomputedLines[1][139] = emulated.ValueOf[BaseField]("6638743522580856341158564937403879228051631568619778907717013129201344333030523763340630776780970212886218386113539324071014532332375465792484714829314652990224787865019761417248495535237113451295259942116314962267177857737645266") - // i = 138 j = -3 - PrecomputedLines[0][138] = emulated.ValueOf[BaseField]("4613201178001957129220355825431588428522349943345108194412238432864585090458272273751900747338897976889754065236440077466509756318978363238292987387245777302440033792016880363771237380814734752042079287291688686090965516430849448") - PrecomputedLines[1][138] = emulated.ValueOf[BaseField]("1665407548870793045474076587401340889263185099880576303565184262174562655936391826075556576588193249562650706614327662566000797730855714827683876175311660437080511764204863560130199676589127312887632418700943424352628228848843582") - PrecomputedLines[2][138] = emulated.ValueOf[BaseField]("1655914238938042682721551953036253645052537746651874939938037114097148347201468500148537117382150061034475405427296650617729834662783132704955872642876325349014004370043171807288606000041903234533546215958118359510613083090230570") - PrecomputedLines[3][138] = emulated.ValueOf[BaseField]("4849745136522473566966399310625020500289818714428592684220005115425817386657142570582575781909747557971016323109154388103509887878174433513364641252184356415172199372371474037346808680920949717207937405738624457011320349705365166") - // i = 137 j = 0 - PrecomputedLines[0][137] = emulated.ValueOf[BaseField]("901736082201449083754819885340801075704408863998813128158005442577313496494289416471869404758956530411763940080091857539300845778190660401951269041409695446928577309363369775219696459229579351565985855170562488979593152186976780") - PrecomputedLines[1][137] = emulated.ValueOf[BaseField]("1001009910919327523032462813652578972145867187256987285583595342347716674065364382437719001411863024220494990944043998634009881763715881903122679211258938475917286800934054659626133958862607032250059477031442995482587302562197710") - // i = 136 j = 0 - PrecomputedLines[0][136] = emulated.ValueOf[BaseField]("1260704208583585454923573340419048846830684418938706770827984464987809006471346576124097325137037851487326970768765206484805325033050293845686253143665118237882360616375617892187324896995348006498509282714830651433149367764383338") - PrecomputedLines[1][136] = emulated.ValueOf[BaseField]("4146904343070780886774548283636255552210562066782568724140086706931842548150893909742775877375612341303901723683529979271573649898254285900026209098018635582129262100543849831967889807912740957081744133511298450256079900667190703") - // i = 135 j = 0 - PrecomputedLines[0][135] = emulated.ValueOf[BaseField]("5934405004285776331630280637109070463626784739136943282051799037098249132104511122554510074244540327876064527736509150528218419867398859662403698876411373576157376672220445952316857363235511588325272279467223393469732469391589454") - PrecomputedLines[1][135] = emulated.ValueOf[BaseField]("3853300763714466280621239533765003576889560379702791099289094890338630225166520693233826140813720348044192201950244579487184637298409839680878533788041179595053520650058145442845460866315657638463420171773555348977817651593893300") - // i = 134 j = 0 - PrecomputedLines[0][134] = emulated.ValueOf[BaseField]("4071393582225441537259129740348136928083015327075675947139818040266037848160886082345792501192485369996749135042646411769614852944973561715055093656354124149362614454203390246905090905099260897928953398827135826072133621101404195") - PrecomputedLines[1][134] = emulated.ValueOf[BaseField]("163064925070158099254952264886241234943555067376205015997612082620013849480487004418622298793050415738026006109172604997325700501036308991398166284975128590614460778829761389732430123500510222705991473579068874904567649913483108") - // i = 133 j = 0 - PrecomputedLines[0][133] = emulated.ValueOf[BaseField]("1418055253056202074595134691646273080389280058925225243405714343036410124848094320257507899566341757290227427489602264479370376697910695572778903093150605203445190132527551908453832799926697589813708187671591577598951527150266462") - PrecomputedLines[1][133] = emulated.ValueOf[BaseField]("4155270220852296426069284095173099018808860752865568102978836008384241124182786514727621135289096926318101983300917387205733381093054071103209226340513432729873159990132982563319636636190627483048554684794275717730537206864972738") - // i = 132 j = 0 - PrecomputedLines[0][132] = emulated.ValueOf[BaseField]("2330886315626139608560488604463307042069439883877339752259227046211913815357101972673368411245947078845325193301125955376122337450853187562598776619960568843510592987176521049173659607909314337783813131204696221681811462179088691") - PrecomputedLines[1][132] = emulated.ValueOf[BaseField]("6711986147911438355804568563575069333271094896862220019688012927363594088853071294014660796060718276350481094706075223562102712977643602867969637013015964531826665436102237060386185882331244978345250975580544289533439462447279257") - // i = 131 j = 0 - PrecomputedLines[0][131] = emulated.ValueOf[BaseField]("2459194991253184572352513073915488362359413982519643806017800096086250895884084333687760994466920538720187471885744206660334045092314159558800220531380876636659371375141085558696675851052370181877646188303218710742352859633964342") - PrecomputedLines[1][131] = emulated.ValueOf[BaseField]("1798907412470330186181222251574418897779031365954162228532991291868214950565615990966265694580335533045365235494965998595149631566706795045987443791903411003279763085924753692636782886218284245215570054489439163164726739330788532") - // i = 130 j = 0 - PrecomputedLines[0][130] = emulated.ValueOf[BaseField]("6200227010995243292534007463442727301124348508335846975763125380726292582060924747024816702710789047477511252369137204867777169795203823829426651503047600098271481218636673525637213754344807277089122252066488429612476303820804543") - PrecomputedLines[1][130] = emulated.ValueOf[BaseField]("6183339963554257352986053313573779205151353739061345212410014518341183574948205574318625281851356054888090433850265460982453347498040819644197823676451772870994706563880697505569357671552697683052366439579377964497653703657273613") - // i = 129 j = 0 - PrecomputedLines[0][129] = emulated.ValueOf[BaseField]("3179418169374060428648479451680112473165868327208755428080303333059122452066341836393363276607814567151445118342356457006231585027268454793027792028314743348462081282511356597993842079243330612103229465856549806800369725036881516") - PrecomputedLines[1][129] = emulated.ValueOf[BaseField]("1074440876243557992296297656666926523894847888827413838964195035038704675426637330906565122688220683942757851797564811398813653924552049073155628743092598727862440471499620621997136194644441450660880437794868985296365645976407463") - // i = 128 j = 0 - PrecomputedLines[0][128] = emulated.ValueOf[BaseField]("2656992808450134623226107811040851573895052777253445321570646190215821367927767059861417586581046541647458203705873809488287636783989040464371827681455548309973545083153900514460616688467563484862556513683924061416596829297761281") - PrecomputedLines[1][128] = emulated.ValueOf[BaseField]("4844145081209902609505524435169548005333832418493246907706701276792579054383871336339479329969744299945519805206076736030684085411371482252463723707639516591389550691017538009029350110030156955501292575958216281584402435928015282") - // i = 127 j = 3 - PrecomputedLines[0][127] = emulated.ValueOf[BaseField]("2011974253550710793841707614319665694450124220622509460641614259810013401810340721144190324466096151717630769235513591278366843097918633665449346052590698996537616877458386727075369760392809275502298638397577883974589386211297224") - PrecomputedLines[1][127] = emulated.ValueOf[BaseField]("6759883189410489244241895710608314487646636558844672718364985082787669104517170096580376692069609041874604017863262445678624384432339609560673325735146824752213644659396489133994780351405505353963175199534520940811983252265624615") - PrecomputedLines[2][127] = emulated.ValueOf[BaseField]("3768192070758720977362743048128269743652792172865782600408421041647100863768584258831661376266155960653323061159024418693369114489150496403396836022703123674697982050710775271545733019404845648384932763373012576844034843014226663") - PrecomputedLines[3][127] = emulated.ValueOf[BaseField]("4996817090270925204398124591351581650929992386659735131162538961779700303447917693269175016025592612215970500208241974120205022765011244960015994932562080528715942642394954932931189953414547282447001732552340521661044540625436489") - // i = 126 j = 0 - PrecomputedLines[0][126] = emulated.ValueOf[BaseField]("61030029175891269410795092194963931753546458573367290675218972211227148812010246092773830125486215763104854597618372825714261360352033773901926014862100801844180418267711567376566306882863926155995425312804691687033445561167871") - PrecomputedLines[1][126] = emulated.ValueOf[BaseField]("6833240418488948066920209892932139246256027105595326635285212540472436879581105716676144073328231777396096543811943596316039625629371094363456649650678572026035768513691047630818277854926997745495397934394176338037573909064834929") - // i = 125 j = 0 - PrecomputedLines[0][125] = emulated.ValueOf[BaseField]("3926949350427962695585990018450101508532431417991343152535182583499353333354294146067703587959518218515009410854982144126409191309216905586664235278880727278347038082001447608618625591165227564209266868241878519280739454627913589") - PrecomputedLines[1][125] = emulated.ValueOf[BaseField]("6309962043798723795945059552956223798505736132181994182186095961257327116478835558103704420245912232701804081120812215729741361816214804019930911187892496733432694004299106132040377518510660396793612942971514054694208602506501019") - // i = 124 j = 0 - PrecomputedLines[0][124] = emulated.ValueOf[BaseField]("4488999804938223839571472535025735012412690342654669760528351297118412155837701581755042574106398162784062944826655321643381618013246981215604421509557111054819740593053659366060345354377072326398031111319075975298655323375246802") - PrecomputedLines[1][124] = emulated.ValueOf[BaseField]("6444989125456244545425394136098901739857497273657531818611817253918235907497599508119892300164686750638921852969593078482345991870378784799499090518807626656978947039049504439625214712037653614746128104900832879863879988276182218") - // i = 123 j = 3 - PrecomputedLines[0][123] = emulated.ValueOf[BaseField]("48096764148903583755143048977709097805863506367881065875494375242161357807338208699249280067124184831538166831199608365878819269574548732670387717402535874913726374579033072827257006439676023227938395708736234029547128657519024") - PrecomputedLines[1][123] = emulated.ValueOf[BaseField]("2885079913666629029378113424257839642578093922710003917421662173598381441374102964233268828960354312449054455561942853958742180460052092915358427157540615228259129038054859726324662666857362491353586815224330417492336147671076074") - PrecomputedLines[2][123] = emulated.ValueOf[BaseField]("3043841471664770240132695293319503660849549600823254092922959329815228043755665146670109099702358612421893385494755435653299330932454771820778776072989501322684889256922094409958313718801462190749096656504789733891018826678061754") - PrecomputedLines[3][123] = emulated.ValueOf[BaseField]("3964755972180176436323966637057860893750008381404580562869395428071031238803305006501831093580555070806000231292428936249019977282011769187032253227866421572275838519495412036349811651394855424599078120762727736839420292263462485") - // i = 122 j = 0 - PrecomputedLines[0][122] = emulated.ValueOf[BaseField]("1147423570305216155966394089416724605760345045141884306377095836246940645217647257876825855936992089170612653283726654429767384651124940326503491901401745219743034675518742507445403697342358921463061860241593761756336289164522119") - PrecomputedLines[1][122] = emulated.ValueOf[BaseField]("1400653168263070557443196511526506706425351336877605966710891264057367498166955652141609738759131845843222045163086919342411712873806170027252549920037193747798496958648686134783555143951150979662348022397600974087120311815298929") - // i = 121 j = 3 - PrecomputedLines[0][121] = emulated.ValueOf[BaseField]("4848629817189004581190031618928252397691169400292273151462737052201317336592222326669501659224975531820399232409938503793212004554476876145926583490328399513338352933529323398645256274996466572940688236571797060498039826415776303") - PrecomputedLines[1][121] = emulated.ValueOf[BaseField]("5544527487950438540786567976353286513309130241252879438584120222061584982747917620707291880053404671809935496576304302790977416756689184737791798686432959793818214479200283466088031571739784074765935407802091843712383310733299433") - PrecomputedLines[2][121] = emulated.ValueOf[BaseField]("5683179697250901409522989575566573888308266359124141125691463931015868417522055941441646787069096352388787048945382148685200643438128420640514442659752004342617047060157100278358653282807481368362519403945976463760841519256358005") - PrecomputedLines[3][121] = emulated.ValueOf[BaseField]("4015193801627401118529067340400153381185658888661374065658744995657432104911672137199213869471732156067461339474772923041603387145645908396491661843740044507679652139062696511448585565788502969536240872541545150524475461142991914") - // i = 120 j = 0 - PrecomputedLines[0][120] = emulated.ValueOf[BaseField]("4288837439335358966022320970682704322501253708708512179864196425364227488774750648885019477197521514769857662684703447368455232541366519594011028463745666196187644303062377133432655952115338413364077019586210481492151153882533394") - PrecomputedLines[1][120] = emulated.ValueOf[BaseField]("6711230786907893007908748623469748328179715213743529169694920667477525813744104801178474617246982814360083701328157531202085430108276078940886323514181053003891998099407640230767176745670810179914758840362614799568490407762073099") - // i = 119 j = 0 - PrecomputedLines[0][119] = emulated.ValueOf[BaseField]("413554378658776595501164876190088919308414438064968589716948868117411538135330443667704485985944759138845581832799144492471703206122605761277212923300910870363233962333416257118355152435167571980116339519218448320568686091522060") - PrecomputedLines[1][119] = emulated.ValueOf[BaseField]("6297262784542072715661554435028140949302827861690375106363013216167140265214400108019462805799107026733661225399127154732488782092163034727732105989690602332517101639676965271114862669193714613581755099466534874261129391687766781") - // i = 118 j = 3 - PrecomputedLines[0][118] = emulated.ValueOf[BaseField]("2983298753229977152323135951705985466035371741485329442751503135857043227825215884279541420174496098174791077537084819659951247261120623346318386113107777075030888060458782579622749753862574748396898338124366976276144133985861273") - PrecomputedLines[1][118] = emulated.ValueOf[BaseField]("3937244092143115338932004671719774355768669736676487982793276339336791586253378335050493388635279555326187388831599651140722899137211057678112288706659103180262966143161461781843109792871183956304191755744274332064783999126226281") - PrecomputedLines[2][118] = emulated.ValueOf[BaseField]("2733696733608866087289260002991705592224758347592178237334152606732051902582973806868260081916851181879380681091249755495212273063349966523361751113544397800785886443510833030691223760659900815227739498061573912216017141950639322") - PrecomputedLines[3][118] = emulated.ValueOf[BaseField]("3447346116023692597027327949601168437105182566602907072746064824432937885591845713123463314504333303435002189386048554911879434635935212953780216832655075848382621368493386691645655672987605820386850955801239102880102299086389298") - // i = 117 j = 0 - PrecomputedLines[0][117] = emulated.ValueOf[BaseField]("290772385992205989003842268392935069805600713676054168995478891788672038548991216826202976641995154972645344657841986735832516063908191336543573825112421034745006181624889096669351734716264231721373274177150459199663763065478094") - PrecomputedLines[1][117] = emulated.ValueOf[BaseField]("3292019506796543851445430702320993553807948365652526759401921872579331881880870165659982836507133155007686741550814318483452571439127334976403549783875675171500812427161759032411335276957921133870128540763629302400287478387857054") - // i = 116 j = 0 - PrecomputedLines[0][116] = emulated.ValueOf[BaseField]("4933337379982622525808367378171514734682006772891408711624036888695073657453715290052198254814244894561471536382000141283035744955831857691284830165285170418958890877344092768820121758525762010992645431371368379192630527450391567") - PrecomputedLines[1][116] = emulated.ValueOf[BaseField]("660850871449753192123029385048560910163777949424658222423062565370599825313381090514485712636189623877350319216784062698362526297988273758467813066947250372551363684027442866225073557812481149224724185611740850384821128407685024") - // i = 115 j = 0 - PrecomputedLines[0][115] = emulated.ValueOf[BaseField]("481326854764450570772068592260461055406637567541766934153921077562581658404153295111099308704366026875413962255916341670032055787704869744412189455698518435213580395015910187380289385944733548582699453517614844953747524636966060") - PrecomputedLines[1][115] = emulated.ValueOf[BaseField]("3420809227688631341669679740644412647134601097109661165923282832112778809885638792228909313681711757177052386648346649475521497838129590818669774544604962973921717806873457767712621599594811960795930366883511052271155980303038721") - // i = 114 j = 3 - PrecomputedLines[0][114] = emulated.ValueOf[BaseField]("684809418026755822824253058438625412417627268961531835854114498136804562817130170611497035677023178044635114102224716079155167463023788690123629198688642789173614157135366218960438999272216205071157116652777625492047310641469166") - PrecomputedLines[1][114] = emulated.ValueOf[BaseField]("5166640696283905919399620082219859368947649651772166224210712571165517842457751521392173879950792298566506230141458101552956587780134231473703997680234294099476701153920453787845822302486959392040307239726389452068888390962896457") - PrecomputedLines[2][114] = emulated.ValueOf[BaseField]("1225848359831922306214457248004716386615308053365154620155093059738513399631997830664341068529519872751146070928817179211667300976162683350033065380748927997960100452502445405076083585662063240916615131996881707770541479836532906") - PrecomputedLines[3][114] = emulated.ValueOf[BaseField]("3183467980405159459382133484543120947419935505894893093005336721935126843695893593395289759680648960257687962761513412564242438535941446306048253411519706815016857930329241932935979124772476367891799889429968788126781556590159057") - // i = 113 j = 0 - PrecomputedLines[0][113] = emulated.ValueOf[BaseField]("4626517608297074303998465222691929513752132880642038668324913066825087276695067156470979826318812539456317325461721593605469284549411324254599330937034993001421930210744360228548043152368219046417783422209127357231636814511442814") - PrecomputedLines[1][113] = emulated.ValueOf[BaseField]("3983180414026994442339773406369498782480430663961036515210761780953055939419716704607245841367824985551004597998080550979782500959769863562745076097943094990258671204643135180911363102591744932177410392029554146511771754571301543") - // i = 112 j = 0 - PrecomputedLines[0][112] = emulated.ValueOf[BaseField]("700906576124412811291086856659842275195258622895397636425353544093733685670245448363084087741581123052363188833111664735668171799136833943150612925072937471265266461004370773546132263292121859184858316146896828999548280381303452") - PrecomputedLines[1][112] = emulated.ValueOf[BaseField]("4692134649081002476703999452330156046805727119237089354081639317452715546964599231153077130319567327586394710165251636039202551157971022041837579426842866207332269843223882426757561323716848393489694788769608479640858276714369717") - // i = 111 j = 0 - PrecomputedLines[0][111] = emulated.ValueOf[BaseField]("1634336593167212469726111087588237678289979788278360678182919348642884347360479796581910754301108780131592369234473369879828281697717419752310591911301483800386694367816173405109239641530977162725545732544176131812255789205336540") - PrecomputedLines[1][111] = emulated.ValueOf[BaseField]("5184725322013784060417949167414529593680372589157689476355315098744927077860773135884503916427189964053154110415376925663936201076402862521450607376690027367635571761072728824076432872648592119843172389551071898313845735081029724") - // i = 110 j = 3 - PrecomputedLines[0][110] = emulated.ValueOf[BaseField]("4953319302934812575038999165295500575676791409774699647543406528425762068872173726634472807001304647993529966624124694243595249743482491962931348850325767446611679661248874226095803976227891393066925992955597935289828823988957470") - PrecomputedLines[1][110] = emulated.ValueOf[BaseField]("737693528334438898431278286504826143269591546431662377619978515983630360302832003327633229277274683374824551063238506172875438613867639447412012507544780812924210275380644728627103410245362072050600051053667454750114777947030141") - PrecomputedLines[2][110] = emulated.ValueOf[BaseField]("3001622656638585857511801217301789708361697320249270374331911200105561040742864289651902240628576874070436165017228217112117151443162706218054774400918978527706874258973333719683737630175847920511647263686994660958560642384777280") - PrecomputedLines[3][110] = emulated.ValueOf[BaseField]("2955371716766235083595476802782512312694024877961802653530637208613750128600047733743309160011712940356611152581452205642405634198799174743558191212422888690146861411211423483451438377119945438228140796896482696879292216734966012") - // i = 109 j = 0 - PrecomputedLines[0][109] = emulated.ValueOf[BaseField]("566212511094651326103650324402513675260768764551684782856361232500767090053613654126562334984732125275054601697072126248934983773636047526079992446589428578795051228008677129219092223154897142521267350970627097886575925934072398") - PrecomputedLines[1][109] = emulated.ValueOf[BaseField]("4694230344175341667542145113737216365363426662846928492809719984029782449958204469882253866698488012712926302037291695259127133435421044549374748189772077500141102408895386792102637462624844856073187158713496155412172255268322943") - // i = 108 j = -3 - PrecomputedLines[0][108] = emulated.ValueOf[BaseField]("1563334932490323038084899924732619173549214924802037645248404609061373133331192708939390980051099418970255195294348796506729828980175564189388228950685471575211313645348571431181819230671011458906431929755248519529988950383043558") - PrecomputedLines[1][108] = emulated.ValueOf[BaseField]("2311412559152774300375788856023758369822521516908975703173975766181607168537907050081509698867728203522923410694651912929457339252559503759095125494059547321573842664360913179904229958963585141627873969617228770993980676261040500") - PrecomputedLines[2][108] = emulated.ValueOf[BaseField]("6175484932576535008332986939485368186545707346006529500809917972874655208202311421127303934742877907503092285518028735492781966447056993288871485474747566840336074917424118940873858912878005715629316527794406816857815430726070562") - PrecomputedLines[3][108] = emulated.ValueOf[BaseField]("123461782351177634930277079148606395206607419259034123695631887799047384654128845614852300409005752420063210643732168643901531437376507326408479569877882472340918116769163900404373761149085456763553576075603356470050914486784227") - // i = 107 j = 0 - PrecomputedLines[0][107] = emulated.ValueOf[BaseField]("2266072688291883158927069701738151065911783517304966453663389480757753978872156166093957720219822740237193161041788615078014605864407228585164871986379055520939547980130537619246537828306531563606741183765665629373453332588449192") - PrecomputedLines[1][107] = emulated.ValueOf[BaseField]("515429094414778904504609179778459693982980053019434816014412238894402419646194981385097367993278713184436989416609354918183746310547812647612954769802713599858825453698318280499717719480495694699890143977308826388860019070165085") - // i = 106 j = 0 - PrecomputedLines[0][106] = emulated.ValueOf[BaseField]("6010267371716213143093695909678402022513093521998387240126661727715132008960698736705154118695232557573323370026042606069770730852857100118375407703868918255082260850714722276087906262762688500835963093332420245740853593545194085") - PrecomputedLines[1][106] = emulated.ValueOf[BaseField]("4281963311419191872029752866318517841992413134196684576181285159343053945111111164695870787018911219416379353456306717845371543351196013101034879448657779720874779538361445158199969059295153478919890914171037486882185535487756052") - // i = 105 j = 0 - PrecomputedLines[0][105] = emulated.ValueOf[BaseField]("5033109025773232254183934091944700239231856713098605055038668877944288565346733607655796479139731856249627912046360970116447647293949316671166763832369647495992541316808331439387103495416443655791884868522333160346837144982107819") - PrecomputedLines[1][105] = emulated.ValueOf[BaseField]("4669900460535830482515520442133880272923400282670458928700419218226824432636715019798554131251396295806505565951980674546657468029856175682486586838325399578768679827829147144533201256575038610283060702643703231384047071770887732") - // i = 104 j = 0 - PrecomputedLines[0][104] = emulated.ValueOf[BaseField]("5454443657579324363377843236533931015151471915547623055046017633786313387883877403182401915377828483292869801167098529527030796069300191051702745938365410289948973748970664626027385576751322712014625670196018632538000348121102474") - PrecomputedLines[1][104] = emulated.ValueOf[BaseField]("3133241298818377302733257481994044946647420520220237736360138875613702232726634637562049820513369241910571891206808742626182652789898777775231819638504462620062570796618509435949988642581412369087353609039469091753836564773020135") - // i = 103 j = -3 - PrecomputedLines[0][103] = emulated.ValueOf[BaseField]("2301849413909855674162488780732225201562676616006104959243094303277358428323322327050305311892348065869912402322473064362096306853774859357097769623712937529819889534187399774499938603998860479544485756019870113355345199898509876") - PrecomputedLines[1][103] = emulated.ValueOf[BaseField]("4769376100721203643584138490105487969288775420140134181589021687554748064461808608512166592229118932062808573234716616135297734707261031144278742781947854336453418853179094948475856324990828579869914078888963150707167390109400684") - PrecomputedLines[2][103] = emulated.ValueOf[BaseField]("2376323046012143545352049957873875519653973825890489638934761380270654841992811869649376088018241846893967207987918990869977981056879466904242398708764880914800026189406407451663484394823027179271301159428644427692814343803894277") - PrecomputedLines[3][103] = emulated.ValueOf[BaseField]("4089518776757651749022544766981095582075669030595540409340632143941619427587141177823314253624223163160914150731354990886243264294641208260814057423926152825198636019975190702372273183995827896803754787380902888458019918022259926") - // i = 102 j = 0 - PrecomputedLines[0][102] = emulated.ValueOf[BaseField]("4872199633786861961320061137660550246969907345425715365233729280812060243137569195452166883931936492293633659728504486689475848164870096347435687001947281602000240086205222906666275934244033627794198544576450550622706826706744731") - PrecomputedLines[1][102] = emulated.ValueOf[BaseField]("764164273079444455641809357552234779774544144626136395465042268465909675126831728736916684032579180470274953297527142632930920341077843559622145430140345601412258845118977809703379078517406445366917273261372686452599903434432351") - // i = 101 j = 3 - PrecomputedLines[0][101] = emulated.ValueOf[BaseField]("1138481222158043909429825005297113087949881539191043655773323092458960243267437165694019939226385184659165150538578267029713533666280319072044638200327467170930049042745419600787617447150439577689985541557660176482532702243908440") - PrecomputedLines[1][101] = emulated.ValueOf[BaseField]("4455300025758454639534519022413757975745594248460153197224377412273277761607410730038687015774965120910762436343695971192449449581489423823076517762372006348621691049173740475074002313383891237225650118962005615659136329845120303") - PrecomputedLines[2][101] = emulated.ValueOf[BaseField]("3210463767655913107954350922295873010088631300544162634401958500459347283641926261600873742133062376991887707975154177358003118834068347936603770092842361580469026013565559516593432428767485752729404150412697514672519818123078244") - PrecomputedLines[3][101] = emulated.ValueOf[BaseField]("3897236351686991693518980759085912950422402810098004492800141105249577706175658694833724887157670303699721554411373719170290642099070031256637485458934521636211171385007596172461292876808305757268752259666777373248236573371376195") - // i = 100 j = 0 - PrecomputedLines[0][100] = emulated.ValueOf[BaseField]("4043095220781872017006054807966746640757748818620819777748666199334959371264455489659963392402393583448358132611434041099616898661511397735360831151484256897717931065631791608561310183754921837329313928655091009601540228499784445") - PrecomputedLines[1][100] = emulated.ValueOf[BaseField]("5406649262179124359509896426133671689896244828529858894945031345510404419121406838049367696542348655513507453913868421112342916164549144087743758521137512378354638215435021249013569643525879309796069922143806676478667222192222627") - // i = 99 j = -3 - PrecomputedLines[0][99] = emulated.ValueOf[BaseField]("6210611583500209950609099283083845754343386775986644996495973338504113861060796404338115170687756692399051620877679985388589228603401046696724398332298367241779996900625383743212074129854630884637637834417311509095398640463885161") - PrecomputedLines[1][99] = emulated.ValueOf[BaseField]("5726501072077245235974761111635837696862742235341594290128351842267071162099966467965240252887788857612159886954447208395890185461804071482524387871898110396013302861010041459411476947082162369157387993930218181389615650844996067") - PrecomputedLines[2][99] = emulated.ValueOf[BaseField]("630551511715376341788910558092626996370594613151666291681132040303198169792227073324695905614334843012564821616006131002919719731220925580296216363445909093410447010514067814768040564189299416092344973942045797304024180032472823") - PrecomputedLines[3][99] = emulated.ValueOf[BaseField]("5344695873199798841654560855251216660354077383457151943536727881807747920346947783746112228393404410367589543239351918147241201379773853540214926322257942419416881562554531461956796366484295771413814611929735360541285281978298830") - // i = 98 j = 0 - PrecomputedLines[0][98] = emulated.ValueOf[BaseField]("5334290801535344889401594778161065566537566644991298653727568118562592494615354555268880955374003825857184099538522225799941746892657595206702260559374159572912535022880679585339184831134613632067204404819265411895337983336609908") - PrecomputedLines[1][98] = emulated.ValueOf[BaseField]("812946561548650974446001480996438589466020365155339960556949264789840358258764309798690481447224157262762104835659476455805690459602602633404803923871683159977667513178598859177598979021970955761740649000476953948228711910642458") - // i = 97 j = 0 - PrecomputedLines[0][97] = emulated.ValueOf[BaseField]("1533139684897494629678126084843256462502256189980921509779110976093152867744125844762823787644759271036497420339783684287306011082423746624405280667715393784673969283191523855933717625505860175484093850931748781157432915379826438") - PrecomputedLines[1][97] = emulated.ValueOf[BaseField]("3105206394189523431792859755297651248693196651309981540394912521441506361420010730689916624600680638584780245486097926768401597105192310093466212663729743276706806660677048576741583148240985569812346899056456916105502341086472784") - // i = 96 j = 3 - PrecomputedLines[0][96] = emulated.ValueOf[BaseField]("6642986649277737896895099841157338849756884624223791368568736753789869171621550347374886762871833481613998771197991983362560977795424796669802885544577533937046979408514940747205131194031961638448378971158617113729301655128080500") - PrecomputedLines[1][96] = emulated.ValueOf[BaseField]("763985849257341256339914715065287204175615450272088510224646579871565477113676143092909961490765340157702889934511575518026834191072633853340695222233058383715662860411394565262571083422252868386657072058634490756103926667752273") - PrecomputedLines[2][96] = emulated.ValueOf[BaseField]("2111894809768291771234699635254368429563023687238202955565452114391863181226788809996109782522385019551444976548355096590573442756394819488413598826438205621159997034216435139330286194346631796724090675989720829218090134771863380") - PrecomputedLines[3][96] = emulated.ValueOf[BaseField]("5834555584761253568870488261794415860686576893238808172507818342859167083726502551898547690129966013381778535451716397180093294298482738946917975249397680840145468832566368453858268282532976383934291095736173876314444871374184585") - // i = 95 j = 0 - PrecomputedLines[0][95] = emulated.ValueOf[BaseField]("4554372301264166241512694625156409973186315660619955572770107356027531185393192097476447792179708528750421296628447477553088287851446168233462584388645512846895928787087711505667449324227903556816251973558826672520856058023864978") - PrecomputedLines[1][95] = emulated.ValueOf[BaseField]("4072237732151310407138039382271373859807467820006593734390759255740489586569827077454370070958985964666982375219512156249416895894472792797738360119987295845072417172187075203407891945077491781719818062695939265060511011749334741") - // i = 94 j = 0 - PrecomputedLines[0][94] = emulated.ValueOf[BaseField]("6510899928553873687067597313066987710884205441615256395333009047888231930982473929562832370792158708449142959652644902462625671956767270578113087761349674803610849401013694504995254886310324009708372106250447336111780658151174117") - PrecomputedLines[1][94] = emulated.ValueOf[BaseField]("3716985894399679835698500839130297246131682628773524156193981743084313332999772166147103952311960776512057328690694812579802783619226508819684456878978751163445988521637432649774939222893766338589698431788169606678099020184105659") - // i = 93 j = 3 - PrecomputedLines[0][93] = emulated.ValueOf[BaseField]("5047907951035141625499289119782080570696114189985987894831790618317825143013530787999864121162182855689345001033675318300842414213335676262887456422130547583822551127905049725472675504164411132220200872844876890004454445202796848") - PrecomputedLines[1][93] = emulated.ValueOf[BaseField]("744443940877440155852839401495473654127016275733517126510710750437701880197577129845552629949810062222202490220131566785418840939241657307884394435645700947546109375214237696967397028953889952749537267956254343296685593919841751") - PrecomputedLines[2][93] = emulated.ValueOf[BaseField]("405397734594187466210599173815534415630420994025799265503903411229120704575608241682072998863209399054805243315634503312190255263288112805779208908719331201965374614272443482000461635138424130384687385847020666368559442786917459") - PrecomputedLines[3][93] = emulated.ValueOf[BaseField]("2696790088947677357321226274149871437764533101159544129892669487973615527359684570609962654836322323267289273293861803643578367774704764762323540015313991701554039225880648603140983994202127233185175940529764493913084770994846593") - // i = 92 j = 0 - PrecomputedLines[0][92] = emulated.ValueOf[BaseField]("1778118225306862528653893340786894106058338634993301064843865041738491171509980090474610613329922231665151447630778779262936323295114184794655109554630765558760483766521331613645137958731849488238994508990367916232936238599801931") - PrecomputedLines[1][92] = emulated.ValueOf[BaseField]("4105725370160443778676147094095182156751981636198800700531093765665160264349249532223141327824925114515260913439303886102256066220953645440240448328492268791346838243081878928038732773595681209352663512771678125612393529622126991") - // i = 91 j = 0 - PrecomputedLines[0][91] = emulated.ValueOf[BaseField]("4600362245729613938347146383617215424783938802440644201628282454478556194351323702906397430611076765509583670325072759904615561268681689452702508532237183921664395384926920354024313452086066345089232241798541690259686322185162273") - PrecomputedLines[1][91] = emulated.ValueOf[BaseField]("6872426908284539953361622842949373424213870462893858001102304251139191574488922086389439832568944595393555449548692141770650107664958472796235253782268295422026242252114475104252428564451697348055550628555203918153412459460534810") - // i = 90 j = 0 - PrecomputedLines[0][90] = emulated.ValueOf[BaseField]("972238710294108691821576508451222523325936231175169103221318647177961008156434479190946297408489211903837717946830240136791276876475825835667664504728158588476278139573707686410501625612772061520730264742612657926085350356866829") - PrecomputedLines[1][90] = emulated.ValueOf[BaseField]("1510181743744786712591585351931772930337667831480848631490664096747364724169957789195294155846340729886205788034650789517010294174011248598866252696801023552494521982312355974258161015191981410765377192634370898289227817443383417") - // i = 89 j = 0 - PrecomputedLines[0][89] = emulated.ValueOf[BaseField]("5557506933950386763218483231725931480648969308465314223083209985767634902903171046015407999810542542424552137025017112365331409457975213648715299200605178027178239773253939711354993413274425279759617940801473937158802339625367106") - PrecomputedLines[1][89] = emulated.ValueOf[BaseField]("1025310966880184379491710688665364390880187078341049897527558452857000641929877892487550584006724822722919195503446161976221790997828334084748364502503873679170302110669101931916815125014568929775499684740501231187934011945575051") - // i = 88 j = 0 - PrecomputedLines[0][88] = emulated.ValueOf[BaseField]("6737609173935499145966651085828355289411807624339037123166739321112841227388499205045307103023431429178709920183892337531364898858875360100153697870543555199239854099013655686595855597020820721037875702137136100623742392146547113") - PrecomputedLines[1][88] = emulated.ValueOf[BaseField]("2659485018438977675047464196576279015694875536253089601427805835350948531419304111132951968008946706276266572073652283425392817348050712696346759099142455444582291114849705129489012295302147939302874413708743102287044740793505384") - // i = 87 j = 0 - PrecomputedLines[0][87] = emulated.ValueOf[BaseField]("4441151071852276306298209823658750857395590614091535791519200966732884109870930067806083302428289470764924232908921416597828389865940540731878474135112792372490962316681415335864107748995061444417275473434317270174982090608385971") - PrecomputedLines[1][87] = emulated.ValueOf[BaseField]("4839626429060666648820106860500068908374996974648867422022249155639435134527692095743868784198679123972177173528127658202666042870879477969349613000705157462873430251563459916032762882346570618335137910474671866635860602585367349") - // i = 86 j = 0 - PrecomputedLines[0][86] = emulated.ValueOf[BaseField]("4509661640469976049870221335189922597441654768402802889795384802615621925508423937026572412307489914032465870638670846049030819747364558475564741645709494331762666674404206046263976688444921433821673714720135048965856377229611628") - PrecomputedLines[1][86] = emulated.ValueOf[BaseField]("3487870318670087220135642823070529587459810126962147894043319535952413604020763422619481168610564465706302879778881124586413423575607096272785188951321134130211744054584817344450446549888147090168331179905987560684942220425658421") - // i = 85 j = 0 - PrecomputedLines[0][85] = emulated.ValueOf[BaseField]("1519001864958777427421059765226923260984666053267206576476800868702285323411256327154788822327142278385782412542329663866678475529205929176640075196345571119467595511484440425730279526442276708660390690638808053358152183571843864") - PrecomputedLines[1][85] = emulated.ValueOf[BaseField]("339618474481374233408653340286365880775983516984272638090335996177627212968251512436111248759221452748989633180342131444085812774053387887544791732345486839018109192502385591161195444367505365221930689157110125467756547838849643") - // i = 84 j = 0 - PrecomputedLines[0][84] = emulated.ValueOf[BaseField]("5383707318799980417127243658341454006060231601550683158066499356314664342842964473973932129039747978225819860930748841019638264473752363178099272936190083263481626973641022407497920053616402716500855599794452310459194652961209200") - PrecomputedLines[1][84] = emulated.ValueOf[BaseField]("1349646528445772325728229877724689627031743523671417772446520129629622853654155091055539773980844706622058488772223461616911849918670516363806854356777662287718009008499554764276532161656086868870990280218941085533631039125075371") - // i = 83 j = 0 - PrecomputedLines[0][83] = emulated.ValueOf[BaseField]("1919037141000340015532240777217515754000237076628800751689553494755852848880370990254326438067118347725611618358609018159924461271671767113830563241617627756081864476029381221519946219301823123343613957296437308054897105359297269") - PrecomputedLines[1][83] = emulated.ValueOf[BaseField]("6193622106953370645488984456888022941558613899911812237087544262038237716517979317041586005330078927094776330098927225611063600454806197793086266746766986884718391839124951252821859030591980191698766819150227459130246310661346190") - // i = 82 j = 0 - PrecomputedLines[0][82] = emulated.ValueOf[BaseField]("5604334867184504283101885762199377590849044920799905376603908315985233209750313152086865257550332811558800330290623287217389163687434328275776318719371903699144276765062224548014642774106630025931227796845462926473453370878217054") - PrecomputedLines[1][82] = emulated.ValueOf[BaseField]("5121837820524244380633559304962861949517011132126154417129457763839557571454772023100009470380570446804371859803558477476971571907123955873440777537352059389278975949057671557100601956373951179598842161422364345955824227067821780") - // i = 81 j = 0 - PrecomputedLines[0][81] = emulated.ValueOf[BaseField]("6067039568545267838181130403676950028372045277906346948660766639906798973444122264583559461246057301784807410742590458307288485379144153357711779574231768382567438208479868245345445057744643748674697515903978614414114874814062307") - PrecomputedLines[1][81] = emulated.ValueOf[BaseField]("6880991716540357902750875467195505448773685328233955890419023527621077685216030913665134779737441555378073137742920581503827375790310573288149146115129419180701788936806954316041205676346559444100063149390039298206525864640726623") - // i = 80 j = 0 - PrecomputedLines[0][80] = emulated.ValueOf[BaseField]("6869953723292757957249624864306641209156649908829060369956669082858146731880752960326281552744617251261860654696462155414768691078479849090594684751909462835964342943852143551132859576077229991406111489281697940032774868436176999") - PrecomputedLines[1][80] = emulated.ValueOf[BaseField]("5614709334833871645446373840318419298283648712925576675331700402875726133202590836378902568367322443705376968142770629571737036781249560011213286630255110198242550012818111109270093534607349695639612197752174557798917852647048250") - // i = 79 j = 0 - PrecomputedLines[0][79] = emulated.ValueOf[BaseField]("4980594522020125085337838265204820771621076729908105705805854424277251459039298036884763908300381600489511459131191940043084494214578610644783861208395158996603441510107318092064373656027862697953744766191485979617155122884562584") - PrecomputedLines[1][79] = emulated.ValueOf[BaseField]("4042813205981909877511870025047100983992651260939106481383083811949412209961122330723238535322973674617223461600442099649058372802059938570280751988245230293274349336371780245459427109587547862323557335478307216536115035786329427") - // i = 78 j = 0 - PrecomputedLines[0][78] = emulated.ValueOf[BaseField]("4736014237661124474919325837323255333663929534870042114903754288732701949896601812125046300196794235153463997276154765275115330368384777526897346573674986337596087801165856657251875469708964755706589951812065576029605368880307330") - PrecomputedLines[1][78] = emulated.ValueOf[BaseField]("1957240675950958452986564830220902690609413863957547458393400303485176228644772005244521114574569019356081726863230132145863503283354289808843407877002866564348243635922163753294688198520892938154896179149523387763071879026192281") - // i = 77 j = 0 - PrecomputedLines[0][77] = emulated.ValueOf[BaseField]("1896794919986848060393220222925542229088427272504480911387044183891613533212038341442571592078156720914592673025986869785902458920643524703635569058217402002541817375023305033040017178091785230876069201061027396160787380383913485") - PrecomputedLines[1][77] = emulated.ValueOf[BaseField]("952118686796326173491479294145358823162844313805069901337052929645198665143877135883241333497438934099314203159402316956587916577387445642834370029253487949574816963413865062830574107352788125037245193643382776835744743710856415") - // i = 76 j = 0 - PrecomputedLines[0][76] = emulated.ValueOf[BaseField]("1410246511278881873376558292841685790024282857896728342149001813635677847218604552303527026098386447762274364822183314739464128137999683837672885487186967847641717287157617576045185484714232591611567434185430519840283187165531887") - PrecomputedLines[1][76] = emulated.ValueOf[BaseField]("4119705459903045226159670551727402718128564082540864855361906266183721299733904153174114690207935029103638899913664705930838982224621762050269570580809489779078132146847473253910183165605063622774796014387328879207695757913799201") - // i = 75 j = 0 - PrecomputedLines[0][75] = emulated.ValueOf[BaseField]("2072609478320001524320717173962571134711535941640067489637092238715040645907960807893942921283120113507698307002805316256993964956771568079631701795714954017552892285562026519328855416196541482143510574319254978277137455571778001") - PrecomputedLines[1][75] = emulated.ValueOf[BaseField]("5894714538160407682287836474406214563671983369063207757521309934251027316132097965174061393141629129163127240409904888123486261567289075202307479756611875308157695683933323381961136441686218200020586708364128872743199583389014647") - // i = 74 j = 0 - PrecomputedLines[0][74] = emulated.ValueOf[BaseField]("5106682279392935961031812161867418543946492460670149936266921188569667729835222767203306768397343414328957015700647431747733838833765379422556785306560650405609290868938919653580246910237324702779521559387178746171315070090318153") - PrecomputedLines[1][74] = emulated.ValueOf[BaseField]("3153429055905459861967098840411143630797549188658234822637249428037854322116749300600880527338092057104138600571085314159325239783013442224777221397555888980848209009841714998763507800323867871420465284679548596540839296513048642") - // i = 73 j = 0 - PrecomputedLines[0][73] = emulated.ValueOf[BaseField]("2309558581515697525806105514114501512441326764395967792860310494360211491927848765373205741433111502114874822272883456630217937235469291046785367236821204903743476909251764658419705892503554921768097444904548609966973388109109543") - PrecomputedLines[1][73] = emulated.ValueOf[BaseField]("4406788481817611645656548143390177310692203397871589459859491665399736118029103811823041128102326412085453737102272295417521168777404767030473867233710801470981825554027554437439988384534097338870387847812447345301715080956941196") - // i = 72 j = 0 - PrecomputedLines[0][72] = emulated.ValueOf[BaseField]("70143801456641879605852143513249994253942952838517305812198390578544244249425463845374750697973710144773229658121146105375537294250338032985216846454878464214405585464566225251859329111605976969190077368551199988262487332213472") - PrecomputedLines[1][72] = emulated.ValueOf[BaseField]("4207471934217394013864415886266297391321574222138493922397775146262852761128641397456358704993180728128223826867603382191837257839100565460087185314954741131340867336141963696867361333547653842005819524697714614979577888292080256") - // i = 71 j = 0 - PrecomputedLines[0][71] = emulated.ValueOf[BaseField]("5171411332384846522009308600171271717775656813462368729163310066978131550784041262095622048016317730789429706142084360644722417875472080028887935535933365638293239021887851352065226215946911104922399560360027754023282146751173127") - PrecomputedLines[1][71] = emulated.ValueOf[BaseField]("3308699969390408117425675800034852620724152781693526802125365703296957537619549597281048430703238670047566480207149204289787144466800450766728863836132831936610209196903041136317436653727727840725501386858902193854262207493660820") - // i = 70 j = 0 - PrecomputedLines[0][70] = emulated.ValueOf[BaseField]("2157730189967321961590154478681014647736161701291572661503691745828224724570690384542207251893871380972626395818536195165244317011459475104080304183755778781271580095682599104560528323388969877297057997164532517457316922473122843") - PrecomputedLines[1][70] = emulated.ValueOf[BaseField]("6166779349533636404079090091198084654595551428484168319226064024022096225476313444140911411739596624384367001596401007457610736149102582292110622423512521528219451589757047219684985131650713379980437753685311223968789274660506189") - // i = 69 j = 0 - PrecomputedLines[0][69] = emulated.ValueOf[BaseField]("3693545555393262149090091890796988367031750870154119151938382046789970646209103750043260735558026634783406780454806183283167148193304651913829826658787420693591783609897868879309931049485834140104439475735084228792342105678001859") - PrecomputedLines[1][69] = emulated.ValueOf[BaseField]("3454579417845988721145112391791524361723943876865961783871147642976222000744550940707001904868088850717020216623985541442884486667224875720068404843684775351971798041419211492654134593068373225320963803238503760103944066915840816") - // i = 68 j = 0 - PrecomputedLines[0][68] = emulated.ValueOf[BaseField]("4316617566488630990186800831569323180961600325467315782520452617705469884682333093818828825578494920297533166697413661723199052237884768061452289253625270126685130694402411159604161939860148014467733374435152294915689788782393563") - PrecomputedLines[1][68] = emulated.ValueOf[BaseField]("4190664687932908342055565978870270182687821852907651804349091805994979881604990178094590921338075567591395798595057534786427763408202515738478533832353247698077120923788657200258079726159139609904292140147845063993802634358775287") - // i = 67 j = 0 - PrecomputedLines[0][67] = emulated.ValueOf[BaseField]("84944449596492710546484059085756868056952590611144907344324523446407105322952117478388042103840653905762546055111744847509194704507606178767471978158159198402631558743814408643460715249083238104344191220434949959361481291146430") - PrecomputedLines[1][67] = emulated.ValueOf[BaseField]("5649170502978062479430942300569604180065205047447957641053208532178356906593461516672428743249571520776794263298225069421489557741598532601998487905123429777536764343411900779513959797677672828995577356475491526821338663890518141") - // i = 66 j = 0 - PrecomputedLines[0][66] = emulated.ValueOf[BaseField]("2603576310901490311292135150953384774277318221989961250590025834406631430863918568717331918023797152480102239064769151694292624247190535708671290590222799687160437151107174463689862580134536805376273262065253737549576152380168367") - PrecomputedLines[1][66] = emulated.ValueOf[BaseField]("5309265426363429763309068708763050192687298963793233029854386808966038869914249931311696251275662316034717601938626668997195338046712132642237298096821232686285400955651349643194976882039249387172924417706285549777109346548006226") - // i = 65 j = 0 - PrecomputedLines[0][65] = emulated.ValueOf[BaseField]("1341657118469604693612921962537974911241109483254412491247268402952466550719072000823262496503676334235050127694663208876164873088040296471826215794963805354093057402941426034809948776619882576406112722703520543634493032593845711") - PrecomputedLines[1][65] = emulated.ValueOf[BaseField]("4035700358596121039901170893467410034085393540830625930959994152433747836022300185439015628417359035385883786247038684823876857274515720164396191583808172302780457926458796266440756634932368614447938075150295060770207412294411668") - // i = 64 j = 0 - PrecomputedLines[0][64] = emulated.ValueOf[BaseField]("2930660277843850381294621887137108135255461149809829909821377112483523980356050649163697177214375058704749326539551334374875177166039847118094070598604192734655753566201882039674293825146145171463504903948558735526872827397160225") - PrecomputedLines[1][64] = emulated.ValueOf[BaseField]("5988701523929581560610984180294379754868966835887441912002458746197296016937703656915666559413702631263625903364061495057456665933686956303365386760706868014348860600757271537167901231685104290021746466078585138178535287513704928") - // i = 63 j = 1 - PrecomputedLines[0][63] = emulated.ValueOf[BaseField]("80235409916131560952531634926187129854936220704751108971854293712013441645643075028881285775953897977173679734102951555672688501659893316342601229001442455921225014886258110730476599533006387167516464943028770988848119565334752") - PrecomputedLines[1][63] = emulated.ValueOf[BaseField]("5645697547669765807051699414436415014546553640139306333111837902631467486478350968354759006591722977647564900224120645931064019336202965082317873586323451596595667262804678770022271564685698580435094170621340150377645331219716242") - PrecomputedLines[2][63] = emulated.ValueOf[BaseField]("3515801869518688586368276649287501032232253490995929213693667666745539961609686866702375975294290905260844112197318970382348421828085682589212450872191370133742395530357304231481107985085801003563913938437804645550415387469710798") - PrecomputedLines[3][63] = emulated.ValueOf[BaseField]("2768627463899769153777616923498767453844638297259238819533268522374182517088993723558739521443440612431052316999526415454061437419946607135767416256326448665426899699928320017014638884327653368630859958928958084940598054664681103") - // i = 62 j = 0 - PrecomputedLines[0][62] = emulated.ValueOf[BaseField]("6267498047223543516085913656269800094985799102121638318066218769205732496341485331266997143838105658275997583482766391902624817799699593190625745845913736192058521667981439900412382902440513697704842470946713488669728244855268941") - PrecomputedLines[1][62] = emulated.ValueOf[BaseField]("3172495843608365767106104222699963433932721840779494687213669710696273729035389365567085042159376306508312592323212373903543196676243559717338575217311945824019683796186729014449875006088163914305245567518115276847148486469675416") - // i = 61 j = 0 - PrecomputedLines[0][61] = emulated.ValueOf[BaseField]("6393185299135236521600743898901902046235665740374863049386140970534683752073956151008823232102598322138334082399707737488005513141361456335662035360356893792369078552986570350323576340398072873307536750890795347659446381995315753") - PrecomputedLines[1][61] = emulated.ValueOf[BaseField]("3166198729288470960815119159020024849761120775693905362946234701033914940383170229751355601834908988520196149525495490902436617272651934048057104969447501071537789210462295263005230176802247844207966015330849259576240004475861347") - // i = 60 j = 0 - PrecomputedLines[0][60] = emulated.ValueOf[BaseField]("5933242427515184158698502243153492757724275395762347259631780046452701832550257433588929361739397299375972619193115264312711663457102177517470028944343796283322063886686941390353639393464956981156323711880431964717275018387701682") - PrecomputedLines[1][60] = emulated.ValueOf[BaseField]("3384876030528746801023594675065685553683456870336735909759862775565134849351740466668332316834305760899655594942159390338717729639578479114411185241112463275424847947000663178421045281441831580381246432601271822070328156849153352") - // i = 59 j = 0 - PrecomputedLines[0][59] = emulated.ValueOf[BaseField]("5672202940327026564296098467511666610927719124345712212606253393184823723416117442821889411272955540222239709079800765814222617482044871298073480040855267633335674499253454179232541413791707149482883674890351686946817110883000228") - PrecomputedLines[1][59] = emulated.ValueOf[BaseField]("1154543563423153595437057912539134386506457788445374295296155704509782049894375963754530214242479483842535098794085962783214265333207301572819449746417430876867561757821076871333678284882744783958574290553769899855932651808879891") - // i = 58 j = 1 - PrecomputedLines[0][58] = emulated.ValueOf[BaseField]("5494523358602689993082488462159401069622259263261384810777691036023979885833406510370827546720060333368038309757690955479832125270239855687629856598464690979905305508291102673871528818355512749132999808077739161976625609154087442") - PrecomputedLines[1][58] = emulated.ValueOf[BaseField]("3889513228073300846774483449675405165412370889711908059928933828601820970272115969635282636780877852444112625854996590991089931313708119870086461825677989172964379008275991306511578482249736098151784221021103020403191511383026715") - PrecomputedLines[2][58] = emulated.ValueOf[BaseField]("6817348152092217125383764111706396839178624284239986872074018495517405857300894298296426805941999338096243515994114168580699629757784818540853912737100720606253305749066953497290110273659748415521327759821798449434028823512899749") - PrecomputedLines[3][58] = emulated.ValueOf[BaseField]("408441016040698462301045541028863542738760857595465526119973702087540331044892790379588279572626169110948234965342045564413136195279230719397130789960699105297260241439215852283327432361713263160794764750134587346851224358168016") - // i = 57 j = 0 - PrecomputedLines[0][57] = emulated.ValueOf[BaseField]("904014207283845546342517026949002301938840680520511007708789153126108214252896375908459045568106923898014652347188514281811055130725468054629924731218357339456293621824634651205185088647436836303533136737375420850357755914019482") - PrecomputedLines[1][57] = emulated.ValueOf[BaseField]("3021463156942607689893536499084418526149371959265368563253318239787696616342699376770327365917759552439071753047224832836277854106558072813015494652155076805617663734851882419677941639618620577565736429647390393259125626739995359") - // i = 56 j = 1 - PrecomputedLines[0][56] = emulated.ValueOf[BaseField]("4002254150287973611774892958734645146330948131326012867658556213227131674782652425357472920865508721513207580088282234592571562733081211701929443114916737662262590051958147515409912013925831184717537636821719275182204257920247826") - PrecomputedLines[1][56] = emulated.ValueOf[BaseField]("6650995954704541882285423797183833389117409382304102437747875050599180612204257823713527910062803417144644199841410840855424379322391268435824808936698654249193961626271529930100257320177120483894753385159475230006681183908486693") - PrecomputedLines[2][56] = emulated.ValueOf[BaseField]("1731856182637246105907196771656973728242430938769551437479371960396568886577161343428444049436329132240591124171249486296193200751962793098717390700602949957161885965620835197484237467335434836086020378040872702181906955321234084") - PrecomputedLines[3][56] = emulated.ValueOf[BaseField]("5904794864916998236634031354032726563042662734348742454636711408463512681053968061466581910826684656141140069538364115772383786783233506239578341464005935090344661046021052566188151710733410539127138076584927344794043393631875335") - // i = 55 j = 0 - PrecomputedLines[0][55] = emulated.ValueOf[BaseField]("4184818315804686687449311868339826992614263927786079890563005955265008801366363259097525486014913084688352218860421066209106161062321318169379423339655758015838219920065913612147776347966059741489852222087074304658538242226141107") - PrecomputedLines[1][55] = emulated.ValueOf[BaseField]("1729436668893735497596788528818242711527297679305950102487681037960820908794154296615421895498309550090534641956418734833716440103307336957108046195961644346661843459382175352900679912453154393503174508250710602341932630635617104") - // i = 54 j = 0 - PrecomputedLines[0][54] = emulated.ValueOf[BaseField]("4028424328816457105275613631807939250693277717816481016645317988637513044482980841560103858167381177450927995343298109011721354600136597205734427808625992848504337217529784604969243272238302559636203132991964128317728845228827737") - PrecomputedLines[1][54] = emulated.ValueOf[BaseField]("4137264771117858981063062933914663397753332258247457310892238685897247783937428646711199169425232185719356414250990689144775713028143107210691682540723085798000784988249533331875788444818880345959266557470221936184860579434674460") - // i = 53 j = 0 - PrecomputedLines[0][53] = emulated.ValueOf[BaseField]("5492090801797351752381614128547027199049948697414385519539604670596301854328273645242249057084866409918562550964885250930785720674325209012952987352495642374866705080584069469415536679936119019685669733912277135561695115666877642") - PrecomputedLines[1][53] = emulated.ValueOf[BaseField]("4905858371248820162192245612107925452187136738566936712274495298277389232348237517367524132804376317049991057289942326502212212603680615088237906000153324370826140103086371117307680591832523208571162756505635031406643093406864846") - // i = 52 j = 0 - PrecomputedLines[0][52] = emulated.ValueOf[BaseField]("359178835294545969889883772667754428563026611682186272095920083011124469414808094313939667524828315558286118909738292340246984351389375075929819337763337885079238445278970206970834537857532461850702562141060178054445757061261025") - PrecomputedLines[1][52] = emulated.ValueOf[BaseField]("1312200326277970534697540779331716736924580549853524235566261452574147442129502008927617292522196385102231014786673938381594831519849263038105855332568555929441096380204787419249922531962882779612974600959752032033331017307660602") - // i = 51 j = 1 - PrecomputedLines[0][51] = emulated.ValueOf[BaseField]("2026038287010327744329738730229318435937175762944665742194585349571584968982882870102399978673469017390514886249305090405249521202188733937933343484364277244414353591563737610732282221596182900183491534814411847004967926819041106") - PrecomputedLines[1][51] = emulated.ValueOf[BaseField]("2178832958114348900982310012790318964711295868435660304593515141455040525510122631088935523812017659055054869618428180241202047242515973139827366745153207759156458851652815475377013527980632538198101805204073000208867957404386275") - PrecomputedLines[2][51] = emulated.ValueOf[BaseField]("6837231239325802714630592231544125999222471865115356607824139515924873828006966495355988144154645822325580936288573467243496622172897585520569534506877539567995164641501010714466115854526102902238483776009362232490056033478896718") - PrecomputedLines[3][51] = emulated.ValueOf[BaseField]("1136729064180660079227012334655245987722990291836584884006658508324055189594139195698011309590407342768440767239608918245864512620648063831439081245116083355457158423089087145379675587830588630375397838727299113445737968051491153") - // i = 50 j = 0 - PrecomputedLines[0][50] = emulated.ValueOf[BaseField]("5322920300404976083455522685211004055552447217897022767313521102034409124300458651590360645227025719456716157334813011739843876771661830172780260273424774671669669534448129130732400610261443507441704074262583228691779432057383210") - PrecomputedLines[1][50] = emulated.ValueOf[BaseField]("4045151325025661254472879018016993563055206037649637764035519770429754358392671351288941058414802815561896489955008560794303386044981416397960378880429579440775177944716333205061343212765352728742991869524081985800570044775720863") - // i = 49 j = 0 - PrecomputedLines[0][49] = emulated.ValueOf[BaseField]("5226258037103858585709485815951884774065463282206055949572296863155702213812699262254794092005380545671610118552173661619682770665961766560277265965652287468044256177657874378353508735265637291703944234691599675417196965708036341") - PrecomputedLines[1][49] = emulated.ValueOf[BaseField]("1341647445164990334095065980943134038946017316256003003135703740054153232828619291579732165647244341657832232629026147040555154939494114670981128721804157219231387954429790542158383077677618175725451315626705948038674690506434713") - // i = 48 j = 1 - PrecomputedLines[0][48] = emulated.ValueOf[BaseField]("2669141213632483177349464677526063038092995516731288530055965072139720542416799558066265333235760093953926755294654977219704355890957195369092533432110164420763741078175284654109721413728820682856532679498998179023064591536008179") - PrecomputedLines[1][48] = emulated.ValueOf[BaseField]("2134420113812914182827401634702786987961092298592150550562829030382818487856108796955415571408297807671429201199583453019724819973429332912629032447937549705209104608221786349214759677126963931958078901227230879866726885052445052") - PrecomputedLines[2][48] = emulated.ValueOf[BaseField]("5301401015473682032740337209437935700074314236716542138678584038605557667425729743099901506999562233726460077935119644107638279830497233673245936694865259874079692208240393499480211839576495398325812230566957742585600576497712497") - PrecomputedLines[3][48] = emulated.ValueOf[BaseField]("316237245987919229539675151585623375736684226237110958836699548130958545274822742432583398578011769251755976215515832642492191082965378422712648320438656571781374716032787691902701793949747039075058956435281006837601921806263940") - // i = 47 j = 0 - PrecomputedLines[0][47] = emulated.ValueOf[BaseField]("2469284189539122802768267519758265300210938499804273343134547008175934793307225662932029768301730928461879508577001059172355557259081543667750994109716250014560670437893272354177453387546897128436862489793983234949990285254606452") - PrecomputedLines[1][47] = emulated.ValueOf[BaseField]("1830146984962850968453585106583448314487150616750022651699991784484596999485896101930222322503775558473596214757083742949464480904175941842926026220500858275904724239903775931730004030363174733148460092172413335286081342076154919") - // i = 46 j = -1 - PrecomputedLines[0][46] = emulated.ValueOf[BaseField]("4808750674906929458479780393808057785998730391052017477551570952987054533257389747936619777106961884229021401047614317646231862764036952175790162498761774530665237875686878919242872642150254465632443227768599747003266550581405388") - PrecomputedLines[1][46] = emulated.ValueOf[BaseField]("1891884882567828239204882760611347865028360372463103495087043571568211658813632369204338450133243507396041732069576309883702980103212039678198834251217568056933974768947024453446363465598515701337006224040584611704892464155922646") - PrecomputedLines[2][46] = emulated.ValueOf[BaseField]("1782677192263174653114679652738148432045753091242027102628660919836353128448423680787560496210687690962650265604122324792301295723979276692851810069753634590299780709582183458343210520766053802972379144341478689122268621722390302") - PrecomputedLines[3][46] = emulated.ValueOf[BaseField]("4601255220474206175154039807739446217437347898090772634618295737347141908903052922685778628767090029489974230859891899402569132880114132773342251471175144576481058945676007839307009592378129694341000415552823241628198058676301864") - // i = 45 j = 0 - PrecomputedLines[0][45] = emulated.ValueOf[BaseField]("3313817549411916259720752897067881926542086622610865958536519796066914607656859212778668206734368535950822735444718824275919603099081215658685318755509674356243561416633830397196231266219511716007749348762645681330551126790870376") - PrecomputedLines[1][45] = emulated.ValueOf[BaseField]("3252042130416329114631484338445192030646251740098948126128650603635321744781873461724605669481911071863328041692968946348818588320589336163492834872989177013461385360402636605130251922052366702656283468969500573764322346005244605") - // i = 44 j = 0 - PrecomputedLines[0][44] = emulated.ValueOf[BaseField]("6338761415503833574158993491917412731054381446353019200951359861863236217623802777827212821773685337418478392924282420674032240090520869982950877201025879182995853168001568974019311667681399378678658372257019594917864973673309193") - PrecomputedLines[1][44] = emulated.ValueOf[BaseField]("5145208095186900983628565732407350308228178211161732689086638870941412642066547959806176703516458076133350439172796500965758264802653323628323907233788177515377158457742460353846552206469110836809410531151609398126545913664188630") - // i = 43 j = 0 - PrecomputedLines[0][43] = emulated.ValueOf[BaseField]("5196926067227948572519208302811648552049645971471523826735711828398229766956255254268762415203531419391167114934194578362433366430246628887120782279447934571699353681118100448979965849493514365905012300253959326090661874306957037") - PrecomputedLines[1][43] = emulated.ValueOf[BaseField]("3119923259263949969749529244369104226493012793832028159004381001301808535947984715041184266613240861351948168589053862674232986171291382714515365072351226441523796700113665533763234694043303056681109280325373132113235807147635810") - // i = 42 j = 0 - PrecomputedLines[0][42] = emulated.ValueOf[BaseField]("3701751799991197886131283811604024072336985353686243907343722147267167812517345955394536600725894396109453469705947913105619652148410105985236906738662670825757973774071236977402882686728704766160168756235357103252696719757853080") - PrecomputedLines[1][42] = emulated.ValueOf[BaseField]("4328206745347948324047675202212800610600103831121253704737929492249698600108545495006620418550929295799787934661360306902163955205189032671319126960886388468587745108551360815318758470615289870220975458457801506393380445587040331") - // i = 41 j = 0 - PrecomputedLines[0][41] = emulated.ValueOf[BaseField]("5243931540637815073298817765538453903847853699668038453409399793026947683823322658059258449070462262268954906925773665150004113080811722220228212123648000373937683836475968100704584922681517218113636325461148739730351900244430486") - PrecomputedLines[1][41] = emulated.ValueOf[BaseField]("696303549522548469135732799411259466465742009157193344130063238624867632912352618408234824957796454146834346585274133110077926048562040046657743412672416024185699629924036777170476680150185390702804937742220109575805994018565880") - // i = 40 j = 0 - PrecomputedLines[0][40] = emulated.ValueOf[BaseField]("6556291914440995915077184566874121406081010955823879975783964894145083820107493360375502209467776811107722009865129010270289679418541453362001848171476122313995482719748410193307819143390117395993923732784399598145000236756770778") - PrecomputedLines[1][40] = emulated.ValueOf[BaseField]("5030629984485491079543487382652657069214793759421195749161710920620485872796101353201771155469317379128888992818420203178859483332221009950916704606376754774957762349644308776768989209075348134409711677264115878561405610708211224") - // i = 39 j = 0 - PrecomputedLines[0][39] = emulated.ValueOf[BaseField]("6091140106374548700858627680855718215758601972928087739044474141367987574926899958501533551620021166028801571176174643811954610349422547026888525945983551983557194042193263052574485407169478221268356892419346794783326123815016201") - PrecomputedLines[1][39] = emulated.ValueOf[BaseField]("5948828392020302673989780887295980588705729037684336347591433010129397932006719799073817921549578471357750078662933637274249244592252477864992911501358565593172036494701721206192757798992471786865192758135034397631178011919037343") - // i = 38 j = 0 - PrecomputedLines[0][38] = emulated.ValueOf[BaseField]("386805651598570530441388340523805281783272334115584252445736467104669895592428739901130798336649030556456963006714317965660902340316250431631905429626265279629592255272091423988229378924855038046417269484741767052733920691109051") - PrecomputedLines[1][38] = emulated.ValueOf[BaseField]("4525766759081710684536631674589709318407224846654587977942741430894023706116118416593023639529015026174903223073533435099953484358304277428041608689829938708753912201343208781545656144848211632310624653753477849722613987324257405") - // i = 37 j = 0 - PrecomputedLines[0][37] = emulated.ValueOf[BaseField]("5540817150529726185507644807907302646359758202921121879259874245826174565233088540473190697869957879229268506603897981980937573633705421083663690135557685806659327424996048555355538859184738301549091170119312258022116464715530897") - PrecomputedLines[1][37] = emulated.ValueOf[BaseField]("6718515479962911505845755520433037626091003178541819639197260331297301140454264418644497190790920589684999232040565875697918943358405976806940756273856093062633628493384732067302799962517254636294396334020560227976261698493244667") - // i = 36 j = 0 - PrecomputedLines[0][36] = emulated.ValueOf[BaseField]("3869131705462453083574569418603668066852580690436301014856841457006371403127016588221185386053660625244216382527839982867270233918401458075631441051875942486236219721422637941272410781283146192147117345683725174317594008155342822") - PrecomputedLines[1][36] = emulated.ValueOf[BaseField]("4314980459231262879559055441934626715524184332706886138545230734708327298356917201957592166096564220843513786090287049232111040932514169912041600500621718076064675458551242521198970649693981760632428180630077255231913463976015069") - // i = 35 j = 0 - PrecomputedLines[0][35] = emulated.ValueOf[BaseField]("2427320334264300402360662887694403717302806847738543014302091243118106695361301072589835989745366595724889306543713826268811885589885050074000488307245969105060415804657357182570924945821477542418707894862854377873456920736211574") - PrecomputedLines[1][35] = emulated.ValueOf[BaseField]("6547475230634432672084652762025718565231530626989882119549953997097318533514829027216502342143054309787065484993195775491031212236423786271414014282819624182157087622098437337674637018686871012527469005617383148581769811191593996") - // i = 34 j = 0 - PrecomputedLines[0][34] = emulated.ValueOf[BaseField]("5470420367198776800379064913602474642539418292471993924725551625772329613971394974002758597493934979843640341499153207410684010265570101454360050504825249909503161673795412448516621962569000123192182861955528503541040067830525054") - PrecomputedLines[1][34] = emulated.ValueOf[BaseField]("4494982168085199701292806408185286692801752874423548008688924102595293266188792567032936624939523382062636324480917794944337731206576837066847574356728903291949351878926970103254919020595781292363245971532897673992090860126702369") - // i = 33 j = 0 - PrecomputedLines[0][33] = emulated.ValueOf[BaseField]("4369399103458313145656091760726423066162809996158810942119411369347168469388517928848081249440078394350933082794925208252565075936062188001383128598970827204559006905350310028359496169149633766918948630158683088828171365354841158") - PrecomputedLines[1][33] = emulated.ValueOf[BaseField]("2836043989963268489265367048075271632950100267112285454252249322774245764330267772073010634431547940389182825464390146593630054274866401588089959215419663648196282197240743898943526789692085504083282842684412950862097306893801599") - // i = 32 j = 0 - PrecomputedLines[0][32] = emulated.ValueOf[BaseField]("3161593094746195465078500452987750093476067375325753560737558405536356806261984517162664827224212982791699115483519562494689316083005486820021595184605498108610292650087193437653864612092819356371768033919819822231437319340885818") - PrecomputedLines[1][32] = emulated.ValueOf[BaseField]("3819644466956975667540265504039562915781357246138129664042550004125848703662511727184229838152701048608638539116167218942926958298935218078169210956945303241453470842592034811786186043813389041735902241531389493661689183192201314") - // i = 31 j = 0 - PrecomputedLines[0][31] = emulated.ValueOf[BaseField]("2392062469462140923741025287719046671043506623791654187355906507999444953112425089053401530697483613645070888237426395063497315567081124795079610087638568678421297497052700149306919191659789394545701135340977814109862320695165568") - PrecomputedLines[1][31] = emulated.ValueOf[BaseField]("4832734711312326287607356828166645428191493014408322512729086123056982141909670178885145013471528991848522869327843883017611143777932437309043998670383657756265882429166098447206115408339702334049715325324660913143518801609993303") - // i = 30 j = 0 - PrecomputedLines[0][30] = emulated.ValueOf[BaseField]("1477192912994877076584299443047904339823768878392720469166065838890013031033549366840136627511260130996211450274999164360986943039558119431141104532916419870109971379707260906139507809969364754825798030720845059282506581319339014") - PrecomputedLines[1][30] = emulated.ValueOf[BaseField]("4848580278471725966778152640625454583315272135939414014193260350786313591179868891886266751431003335469607271916394805253759620275236580688976609102137853719201345285969924928810598190847426584959246874917721341230807553992359714") - // i = 29 j = 0 - PrecomputedLines[0][29] = emulated.ValueOf[BaseField]("4612548657730367186580082714976803926576026636075855117464342397130243372418284273429514705085325850879471479551060605745051440773485204605835344072407837553391635924303211107514927355596277812147946061939813370285122706400351567") - PrecomputedLines[1][29] = emulated.ValueOf[BaseField]("3008760023968267493067473651579101210329508467951113202776757502253763787362685970341712629429191134564062267116595653720696704870511446188226366583198831759752337733919632784312043665011553157853074013972697508251271557897622116") - // i = 28 j = 0 - PrecomputedLines[0][28] = emulated.ValueOf[BaseField]("389611075583305447184379239616257601802679758494373323193694192448587463258095924560882091875803061182347014161474858927897859287672456186458075155526027559450439890855840286219699926277529927908082352293235902086001952356050806") - PrecomputedLines[1][28] = emulated.ValueOf[BaseField]("5233051879124279727841750931002413127344266604685137080535552109067249081614590411077745857610971661785764119168546299127950916764399413545456303778964651840043599767943011212201541649077025031848271498549479500822460404193902059") - // i = 27 j = 0 - PrecomputedLines[0][27] = emulated.ValueOf[BaseField]("2051301240417715203541474847440511788275661712622367960004326252954683168118911315500500243454295796557207383513952291223465916233842646702105985061178036318276199181260966664406697541077931483773674540551675446385720134709377958") - PrecomputedLines[1][27] = emulated.ValueOf[BaseField]("5992530410566193246175858444555670259253173691580655391949633577253373894334340401965049824695681254882694373651839548752052832871651221221812084861753932936474756435842548719584127897656636378524589912899548493768584550162322026") - // i = 26 j = 0 - PrecomputedLines[0][26] = emulated.ValueOf[BaseField]("503203931329244869313993274825431763771286678085922857991598333658068092455874867591344068855550890716224607734741433955654810857307893638961108425713685811873615289262937183421557667697024010944533996098418759629130851637575061") - PrecomputedLines[1][26] = emulated.ValueOf[BaseField]("536831931203209005383817884414882142673174308352835930285382972591114428623647610993209440256536563763832989938629068274445183810773409133208605690434866892161798632072112140226565160045865984238975881552054351099184102165059436") - // i = 25 j = 0 - PrecomputedLines[0][25] = emulated.ValueOf[BaseField]("6463430776614704091043359647080337102302641202721165935467039486666890211843177302823757119636439288705089663618847623612548484578512254481774726375701260571814452623968715666812055458971750746812300447755820525065477082096459844") - PrecomputedLines[1][25] = emulated.ValueOf[BaseField]("5902012351077562723668140155016090312343270371330172213810546725833050020604407548694284789195431375873831632478747356230690076169624436201213110122483265871607190241540211077771119739664258665822909426121943576686432308367091097") - // i = 24 j = 0 - PrecomputedLines[0][24] = emulated.ValueOf[BaseField]("1209702480415440437280489808669256969507660822534277955404713353804298133175875997191147737012533706181789004010533635994123995990432083493750059042395030464593576198103569451570698867736371126667175609011467744130522758870853541") - PrecomputedLines[1][24] = emulated.ValueOf[BaseField]("5845837029777750013459224043580536350325856602315686949865177782686518032836923907289639741918375475746894480686951269100539861615728782101044640290022570112468403517712710278153623346554615057772599871299926382057138771273059968") - // i = 23 j = 0 - PrecomputedLines[0][23] = emulated.ValueOf[BaseField]("3669387921716642077111586784755843238178249266660604244928408338075745917801994751512648659830513119488679504346125606638021820335690130566721813481244030389132982533363253276690643464035331736992004545492718069275288785687228650") - PrecomputedLines[1][23] = emulated.ValueOf[BaseField]("3369368532599196794572924381408197965372261616436988602166850446579339042019774376973479635755731937177394762130890209583682974918000358029127015486759788882988281657019114821541855861455914246754318200512618966432747665826090334") - // i = 22 j = 0 - PrecomputedLines[0][22] = emulated.ValueOf[BaseField]("32137541075810451210446631093663209561764748864766127373571218650766496266539912695937374318328906120216942929280088227478321482057801830310739684316581870072030933254887610177835453963146235372951835561368946061826869054994273") - PrecomputedLines[1][22] = emulated.ValueOf[BaseField]("2839372605182823507158689651507665403454475643571309601972684294775968522205529181272037381032573635287150715729752526401082948508959773316413692414263445724674361578902109659588751006031022891518347158904500276267507223131882814") - // i = 21 j = 0 - PrecomputedLines[0][21] = emulated.ValueOf[BaseField]("879823418448820628913406122843694317479068503824026559023059280487219225830568787775707080393802920806947189116423374891425653917985305390655018604269987777967653564492499222855808235485800357626429555167604348700507317738364124") - PrecomputedLines[1][21] = emulated.ValueOf[BaseField]("2019956656507533513044304804620987498029973043800218793681083360349414431549401110624447096623879229407017520219447735283040387709926060527484378025503775835133246120572603569300328786465231048952510222155243444173812217480165304") - // i = 20 j = 0 - PrecomputedLines[0][20] = emulated.ValueOf[BaseField]("3281290454511032928255125679760136566984128957779591366529207528731731533134600793218349205877224552035737108314702343961052787202471730566503327144726244281919972166384619563047210740822691567734907997537667405058497230480289404") - PrecomputedLines[1][20] = emulated.ValueOf[BaseField]("217080071594348728220072331086701386987927732572324377989762242979853186956477828898073406659897247062969966133672899633849635715234824558816960723953080058711086889272221299802755516710526712507948703791745209040706597214332330") - // i = 19 j = 0 - PrecomputedLines[0][19] = emulated.ValueOf[BaseField]("1905514651993040879610862104071383816957968412400965216285472577079609325869467288166983369846807418882918776026807359896903271153547170142288644907690025278163828398651066616389966680857524053164685016151033284702480515801556854") - PrecomputedLines[1][19] = emulated.ValueOf[BaseField]("2816143647967364054193437905594006222302401544874073334309295347924554450783714363828797748288245483156141622680173960026092101940922703363424723805341028843408807897111158221058652334715877973135223266203838528902175225909759962") - // i = 18 j = 0 - PrecomputedLines[0][18] = emulated.ValueOf[BaseField]("3185808100707270488220861346228500651936696674923812981059355392187544269657634677839676505285448730714790787439659560131209743667640836808911335723448482317036276477849802480942477940635945348500165742930167046760547595579852815") - PrecomputedLines[1][18] = emulated.ValueOf[BaseField]("4675202760094531043725176831180663495747953794115218641026912893113692505533433572730388712820529906426007256557488721698280794278442275319560802351096319033340475048755930586257216038466820741811485638189993825149184613794329637") - // i = 17 j = 0 - PrecomputedLines[0][17] = emulated.ValueOf[BaseField]("5635658802467315943564921159563504596167530609164425115569295836814932817517998408089848297249529008411035640913039177309966228255844915487089460291854988530924191714935421333239626728042785267863664613844331879333468065828136587") - PrecomputedLines[1][17] = emulated.ValueOf[BaseField]("720713426151036602883179170721367739928889749190344988870442595628309715631339336820381795599137000774024829673311066906838972976105051292835974314413053140708619118427273632229673686697031873977463153954458230306803727050851428") - // i = 16 j = 0 - PrecomputedLines[0][16] = emulated.ValueOf[BaseField]("1864711373715322185727274146635291781641810573108074514648212957755487300184821907927510708219825618515375569210937185934033739458982263275450097382506867527239195625939073554812307989458145792940160837796399384109722154239294444") - PrecomputedLines[1][16] = emulated.ValueOf[BaseField]("3988928910093052639189864720356237097930818779307457740646973707354026597452250119882899767842529798799120303306317581346856759878215117702725337077786120241471309210981341652385909293913974337040166447032309609692911278481656743") - // i = 15 j = 0 - PrecomputedLines[0][15] = emulated.ValueOf[BaseField]("2111972138277766886255103394204659019008608985884205156966330625852224588149790528146858336924984139926163787488158760744677956554133213334043208795767747352197710008701920443139616096988941724903568076255790986324464909342967443") - PrecomputedLines[1][15] = emulated.ValueOf[BaseField]("5406106584029549219347956561279481223128337834964176867650670161471450936720592598327285296544680137446958348252242981441799765208341620018997343168946611305335188418690624746362103485058997168051562245500340938652938314680722183") - // i = 14 j = 0 - PrecomputedLines[0][14] = emulated.ValueOf[BaseField]("3629209394650575177871518222330833326877272533769509791125750744516401250131698579821377134314239098363156873823213748090243637996097460542124115773096078025667715694475433979863616799378688818851677492251164758634054259820876040") - PrecomputedLines[1][14] = emulated.ValueOf[BaseField]("900520437221008886800548981520464166064858146226480487932023831792015057459315475857825023928512447856980411862732432661615834630191260295728391491807141110984333046029829426377271854520636332926473064932965950054970820564717103") - // i = 13 j = 0 - PrecomputedLines[0][13] = emulated.ValueOf[BaseField]("4734810408896001811214566767480966766041181785201049779275187432208928522103518291617951325971697525128808099150421788098814049436302285080209136174985981442006550818503120059546064823364852550394073259460444805722962320216100180") - PrecomputedLines[1][13] = emulated.ValueOf[BaseField]("5865422391872697062771425723030860241442900546731041779331290548814431425813297913622309171769973340126174074338614151460314530384011864184662712730246129508578512966671421774525444186666845500694876618359233199037734923319542130") - // i = 12 j = 0 - PrecomputedLines[0][12] = emulated.ValueOf[BaseField]("3887760817750950677847894913143049797433989451093334387487644754302973690605338116344551865359585356915941906643556393078331726567201153915719711775804769226746078185240704547266041135408371775007735155408569785634346533933769753") - PrecomputedLines[1][12] = emulated.ValueOf[BaseField]("441119206465350316882549165505604924459590172296413032937959602659532459930471493451092782512822884287867392074500585076321765177451793068061537323654024059980774359938586494921359509928655652059494641269369538241172898663035826") - // i = 11 j = 0 - PrecomputedLines[0][11] = emulated.ValueOf[BaseField]("5404607077394994431251930587789042811217547570736433054557556586640813553286600053424846928225504205015146922567129918850573490092069170627610722116586131146412273453343423884209114457640062111469595924927482095035407809633089661") - PrecomputedLines[1][11] = emulated.ValueOf[BaseField]("4992128273422493973515931677118934188850228139267165517174754416283071528379160023746908453872389870166264699098349225348378962525412348488383512774325517097683340882619777769544551984620309329567701220099486813789650124085796078") - // i = 10 j = 0 - PrecomputedLines[0][10] = emulated.ValueOf[BaseField]("763087849666179695979461625611996769804051713411038929855288244851316550162353575442631464450493032671382048273857185992916619387491118179703485106865943075546997886658458038757728898639967205066970190473160703633384738620148070") - PrecomputedLines[1][10] = emulated.ValueOf[BaseField]("5227577585574071525091789577898879814968696426931472551503701053187708164510382055306306677871415061750278454070694425088294917207001686901252368465737693589876043800563096468947400702841366495844730967898132123037353361003037153") - // i = 9 j = 0 - PrecomputedLines[0][9] = emulated.ValueOf[BaseField]("1781035943207167749034352233955519642504059203171184362796879188386098053396193436351030321164897281134193269966421005829822879973054651990134383036098787832244877022488241951982491796164194311656925620981313650251332551878174568") - PrecomputedLines[1][9] = emulated.ValueOf[BaseField]("5114307858760558505028218493878912344149957944171727828461223441276920205074473499369381914839980338882527506453259283811795570014423568561039994119506118381158174777340851075528982301957519935733692661412135735978386601659268788") - // i = 8 j = 0 - PrecomputedLines[0][8] = emulated.ValueOf[BaseField]("2430911614625980011269596384381272763610223985279525352706093989400397822031992694866243135866708876193081539441025415164907568506854410818419160033732911927209720487744352610460298957595825863662700086358463670994353428472440400") - PrecomputedLines[1][8] = emulated.ValueOf[BaseField]("4335308494558780318705382979642947854233414946868553910346431996037254174896634678952788540674877155437972939636950656367011448361678973639684527046756791677216648694827372273647715817383867045823075818246233445668898931395594767") - // i = 7 j = 0 - PrecomputedLines[0][7] = emulated.ValueOf[BaseField]("2547848118024519988008929564919046377764734130919966703992247478777865133666285581651380910908199249341499527419093291036315824924421071456781798698355988988002895935285715260847170096816249495158282329971766659257600058565068551") - PrecomputedLines[1][7] = emulated.ValueOf[BaseField]("3815466815949541446803214953758427869213605006338708824999472457517728301413792590192240627877768012849217868883227016924672094847656511519302987719666096177580954550515172474878462121442935388043933185441940709007646866467092779") - // i = 6 j = 0 - PrecomputedLines[0][6] = emulated.ValueOf[BaseField]("1167077108768000995083265583371639051810160024459730164220078524025147365405410381409052481083355483954665138347762470353560327129943034303256612708531477178495683237179173891252090025088913287905696936171629029789627847133819510") - PrecomputedLines[1][6] = emulated.ValueOf[BaseField]("406035093196089307103307474615059642877702648396642703148247458824638532132971266746290563977553124594299791531448357641367954689961054917535551770937131785613156413700799861618692902162324871023202201085410049092483775186775952") - // i = 5 j = 0 - PrecomputedLines[0][5] = emulated.ValueOf[BaseField]("5399341071441425470861999462932780848935761306689901676544176243299434057444898651559397277961428534569943877757152043198433156075278927379555113704692063491709798852962308451848477392431046008507089543777328572800164773821369044") - PrecomputedLines[1][5] = emulated.ValueOf[BaseField]("4380995413647501953014022884907895222277727851243307821429762028849533207304346950118872297176501204979430324923154815692850079796456195295072263401006293048513882137313361959316342663746522965665112134206267715375474513680925695") - // i = 4 j = 0 - PrecomputedLines[0][4] = emulated.ValueOf[BaseField]("2355007528001232760618455850480455889878756159911741489782272804065790095521530856067754068562930027102143923048583996593049902939282091755328298564310219091115127704570377575491630759741851478137224714576608472109143163134241888") - PrecomputedLines[1][4] = emulated.ValueOf[BaseField]("4665912899792899455625749301506444981281230867228863943483114163843120887049405431893135842230516235480754063251618399643766179241982200138031389011412159570814247143899438305766243708072447877797562498822515933133270397139433709") - // i = 3 j = 0 - PrecomputedLines[0][3] = emulated.ValueOf[BaseField]("5207187280572824372922051863935983381154066518638866240941664431364801000621438981955438756540826259217505053518567779146110599177398084779430644956972778562746737866546243227275793645030333378961907301442124256757681561601565509") - PrecomputedLines[1][3] = emulated.ValueOf[BaseField]("321949009317111361310696929365446618488074131566023032183338451206958310261692318478202604047493903733315880544029393577274070422541105562622923873179574100613877657615274865330644412569925819105384033887215110851435430212659905") - // i = 2 j = 0 - PrecomputedLines[0][2] = emulated.ValueOf[BaseField]("171604085768836918994906821282906210004863151431034585830650164619711973937327792462246851932953079312423762492731678184930260011996638026853655426999132818363829420786676633528967828111050957233996306406638128544950132334484364") - PrecomputedLines[1][2] = emulated.ValueOf[BaseField]("6792516736168200991229865079892385619624765294352391225236313718501707168858243912006527224359947264023889148380617685904914239210331300865987121974424549842263067180080608154025402396835373163617005222364670324911365935342379026") - // i = 1 j = 1 - PrecomputedLines[0][1] = emulated.ValueOf[BaseField]("944621309521718726195869903203401589998750731769836683468553680511480125984458901894639375146584126764337783845625156474446875926698203520367014172302770224257630091870263675889741986266367203690209222830467843091715825765754640") - PrecomputedLines[1][1] = emulated.ValueOf[BaseField]("151717716188583117580213009248663088871479025716844040691055056011917190000249071366607378973846869587747315850766873926578345476515479690657211936017801049784750197114270922646933630675513004231692030241645441850213408222685097") - PrecomputedLines[2][1] = emulated.ValueOf[BaseField]("28240591223645435153733073361277903317564755913445487767068483539533044479138410276002907219108075484110392505549278277324143093596737443922825188690657065974320811475073328849015404093116839406804166651895001751574250775184455") - PrecomputedLines[3][1] = emulated.ValueOf[BaseField]("4589649554746237140826435156384262430368105502118975572158357768261496043366512718050170319247735279131481525972354418839271370133844112357832425807335185239692216417703857721339378872509221452776525897587323689256311521904146265") - // i = 0 j = -3 - PrecomputedLines[0][0] = emulated.ValueOf[BaseField]("640465197860141616651943019830167468662071649572960866185680631674097967785961934733973617225820045841013082657022103021262545174913240689397685222285103870309492801349613227748170760454313475424456095547502930115483054035772110") - PrecomputedLines[1][0] = emulated.ValueOf[BaseField]("2388999626928869692387267530849694884621760071213154089905933112027488411260288999793599348532958544993763708471553506858810523705218284141900132752266650669434242141637113380204971907782122979495643127445776903903628231219718439") - return PrecomputedLines +func (p *Pairing) precomputeLines(Q *g2AffP) lineEvaluations { + var cLines lineEvaluations + imQ := &g2AffP{ + X: *p.curveF.Mul(&Q.X, &thirdRootOne), + Y: *p.curveF.Neg(&Q.Y), + } + negQ := &g2AffP{ + X: Q.X, + Y: imQ.Y, + } + accQ := &g2AffP{ + X: imQ.X, + Y: imQ.Y, + } + imQneg := &g2AffP{ + X: imQ.X, + Y: *p.curveF.Neg(&imQ.Y), + } + for i := len(loopCounter2) - 2; i > 0; i-- { + switch loopCounter2[i]*3 + loopCounter1[i] { + // cases -4, -2, 2, 4 do not occur, given the static LoopCounters + case -3: + accQ, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(accQ, imQneg) + case -1: + accQ, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(accQ, negQ) + case 0: + accQ, cLines[0][i] = p.doubleStep(accQ) + case 1: + accQ, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(accQ, Q) + case 3: + accQ, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(accQ, imQ) + default: + panic("unknown case for loopCounter") + } + } + cLines[0][0] = p.tangentCompute(accQ) + return cLines } diff --git a/std/algebra/native/fields_bls12377/e12.go b/std/algebra/native/fields_bls12377/e12.go index 3dd9675bd7..742a904106 100644 --- a/std/algebra/native/fields_bls12377/e12.go +++ b/std/algebra/native/fields_bls12377/e12.go @@ -184,10 +184,65 @@ func (e *E12) Square(api frontend.API, x E12) *E12 { return e } +func (e *E12) CyclotomicSquareKarabina12345(api frontend.API, x E12) *E12 { + + var h1, h2, h3, h4, h5, g1g5, g3g2, t E2 + + // h4 = -g4 + 3((g3+g5)(g1+c*g2)-g1g5-c*g3g2) + g1g5.Mul(api, x.C0.B1, x.C1.B2) + g3g2.Mul(api, x.C1.B0, x.C0.B2) + h4.MulByNonResidue(api, x.C0.B2) + h4.Add(api, h4, x.C0.B1) + t.Add(api, x.C1.B0, x.C1.B2) + h4.Mul(api, h4, t) + h4.Sub(api, h4, g1g5) + t.MulByNonResidue(api, g3g2) + h4.Sub(api, h4, t) + h4.MulByFp(api, h4, newInt("3")) + e.C1.B1.Sub(api, h4, x.C1.B1) + + // h3 = 2(g3+3c*g1g5) + h3.MulByNonResidue(api, g1g5) + h3.MulByFp(api, h3, newInt("3")) + h3.Add(api, h3, x.C1.B0) + e.C1.B0.MulByFp(api, h3, newInt("2")) + + // h2 = 3((g1+g5)(g1+c*g5)-c*g1g5-g1g5)-2g2 + t.MulByNonResidue(api, x.C1.B2) + t.Add(api, t, x.C0.B1) + h2.Add(api, x.C1.B2, x.C0.B1) + h2.Mul(api, h2, t) + h2.Sub(api, h2, g1g5) + t.MulByNonResidue(api, g1g5) + h2.Sub(api, h2, t) + h2.MulByFp(api, h2, newInt("3")) + t.MulByFp(api, x.C0.B2, newInt("2")) + e.C0.B2.Sub(api, h2, t) + + // h1 = 3((g3+g2)(g3+c*g2)-c*g3g2-g3g2)-2g1 + t.MulByNonResidue(api, x.C0.B2) + t.Add(api, t, x.C1.B0) + h1.Add(api, x.C0.B2, x.C1.B0) + h1.Mul(api, h1, t) + h1.Sub(api, h1, g3g2) + t.MulByNonResidue(api, g3g2) + h1.Sub(api, h1, t) + h1.MulByFp(api, h1, newInt("3")) + t.MulByFp(api, x.C0.B1, newInt("2")) + e.C0.B1.Sub(api, h1, t) + + // h5 = 2(g5+3g3g2) + h5.MulByFp(api, g3g2, newInt("3")) + h5.Add(api, h5, x.C1.B2) + e.C1.B2.MulByFp(api, h5, newInt("2")) + + return e +} + // Karabina's compressed cyclotomic square // https://eprint.iacr.org/2010/542.pdf // Th. 3.2 with minor modifications to fit our tower -func (e *E12) CyclotomicSquareCompressed(api frontend.API, x E12) *E12 { +func (e *E12) CyclotomicSquareKarabina2345(api frontend.API, x E12) *E12 { var t [7]E2 @@ -260,8 +315,34 @@ func (e *E12) CyclotomicSquareCompressed(api frontend.API, x E12) *E12 { return e } -// Decompress Karabina's cyclotomic square result -func (e *E12) Decompress(api frontend.API, x E12) *E12 { +// DecompressKarabina12345 Karabina's cyclotomic square result SQR12345 +func (e *E12) DecompressKarabina12345(api frontend.API, x E12) *E12 { + + var h0, t0, t1 E2 + + // h0 = (2g4^2 + g3g5 - 3g2g1)*c + 1 + t0.Mul(api, x.C0.B1, x.C0.B2) + t0.MulByFp(api, t0, newInt("3")) + t1.Mul(api, x.C1.B0, x.C1.B2) + h0.Square(api, x.C1.B1) + h0.MulByFp(api, h0, newInt("2")) + h0.Add(api, h0, t1) + h0.Sub(api, h0, t0) + h0.MulByNonResidue(api, h0) + var one E2 + one.SetOne() + e.C0.B0.Add(api, h0, one) + e.C0.B1 = x.C0.B1 + e.C0.B2 = x.C0.B2 + e.C1.B0 = x.C1.B0 + e.C1.B1 = x.C1.B1 + e.C1.B2 = x.C1.B2 + + return e +} + +// DecompressKarabina2345 Karabina's cyclotomic square result SQR2345 +func (e *E12) DecompressKarabina2345(api frontend.API, x E12) *E12 { var t [3]E2 var _t [2]E2 @@ -542,13 +623,6 @@ func (e *E12) Select(api frontend.API, b frontend.Variable, r1, r2 E12) *E12 { return e } -// nSquareCompressed repeated compressed cyclotmic square -func (e *E12) nSquareCompressed(api frontend.API, n int) { - for i := 0; i < n; i++ { - e.CyclotomicSquareCompressed(api, *e) - } -} - // Assign a value to self (witness assignment) func (e *E12) Assign(a *bls12377.E12) { e.C0.Assign(&a.C0) diff --git a/std/algebra/native/fields_bls12377/e12_pairing.go b/std/algebra/native/fields_bls12377/e12_pairing.go index 32efdc3b1b..1f18d3b23e 100644 --- a/std/algebra/native/fields_bls12377/e12_pairing.go +++ b/std/algebra/native/fields_bls12377/e12_pairing.go @@ -2,6 +2,20 @@ package fields_bls12377 import "github.com/consensys/gnark/frontend" +// nSquareKarabina2345 repeated compressed cyclotmic square +func (e *E12) nSquareKarabina2345(api frontend.API, n int) { + for i := 0; i < n; i++ { + e.CyclotomicSquareKarabina2345(api, *e) + } +} + +// nSquareKarabina12345 repeated compressed cyclotmic square +func (e *E12) nSquareKarabina12345(api frontend.API, n int) { + for i := 0; i < n; i++ { + e.CyclotomicSquareKarabina12345(api, *e) + } +} + // Square034 squares a sparse element in Fp12 func (e *E12) Square034(api frontend.API, x E12) *E12 { var c0, c2, c3 E6 @@ -116,20 +130,20 @@ func (e *E12) Expt(api frontend.API, e1 E12, exponent uint64) *E12 { res := e1 - res.nSquareCompressed(api, 5) - res.Decompress(api, res) + res.nSquareKarabina2345(api, 5) + res.DecompressKarabina2345(api, res) res.Mul(api, res, e1) x33 := res - res.nSquareCompressed(api, 7) - res.Decompress(api, res) + res.nSquareKarabina2345(api, 7) + res.DecompressKarabina2345(api, res) res.Mul(api, res, x33) - res.nSquareCompressed(api, 4) - res.Decompress(api, res) + res.nSquareKarabina2345(api, 4) + res.DecompressKarabina2345(api, res) res.Mul(api, res, e1) res.CyclotomicSquare(api, res) res.Mul(api, res, e1) - res.nSquareCompressed(api, 46) - res.Decompress(api, res) + res.nSquareKarabina2345(api, 46) + res.DecompressKarabina2345(api, res) res.Mul(api, res, e1) *e = res diff --git a/std/algebra/native/fields_bls12377/e12_test.go b/std/algebra/native/fields_bls12377/e12_test.go index 9c1eb32f33..b5429c9459 100644 --- a/std/algebra/native/fields_bls12377/e12_test.go +++ b/std/algebra/native/fields_bls12377/e12_test.go @@ -198,25 +198,25 @@ func TestFp12CyclotomicSquare(t *testing.T) { } -type fp12CycloSquareCompressed struct { +type fp12CycloSquareKarabina2345 struct { A E12 B E12 `gnark:",public"` } -func (circuit *fp12CycloSquareCompressed) Define(api frontend.API) error { +func (circuit *fp12CycloSquareKarabina2345) Define(api frontend.API) error { var u, v E12 u.Square(api, circuit.A) - v.CyclotomicSquareCompressed(api, circuit.A) - v.Decompress(api, v) + v.CyclotomicSquareKarabina2345(api, circuit.A) + v.DecompressKarabina2345(api, v) u.AssertIsEqual(api, v) u.AssertIsEqual(api, circuit.B) return nil } -func TestFp12CyclotomicSquareCompressed(t *testing.T) { +func TestFp12CyclotomicSquareKarabina2345(t *testing.T) { - var circuit, witness fp12CycloSquareCompressed + var circuit, witness fp12CycloSquareKarabina2345 // witness values var a, b bls12377.E12 diff --git a/std/algebra/native/fields_bls24315/e24.go b/std/algebra/native/fields_bls24315/e24.go index 171ae164c7..e396ba78a0 100644 --- a/std/algebra/native/fields_bls24315/e24.go +++ b/std/algebra/native/fields_bls24315/e24.go @@ -185,7 +185,7 @@ func (e *E24) Square(api frontend.API, x E24) *E24 { // Karabina's compressed cyclotomic square // https://eprint.iacr.org/2010/542.pdf -func (e *E24) CyclotomicSquareCompressed(api frontend.API, x E24) *E24 { +func (e *E24) CyclotomicSquareKarabina2345(api frontend.API, x E24) *E24 { var t [7]E4 // t0 = g1² @@ -257,8 +257,8 @@ func (e *E24) CyclotomicSquareCompressed(api frontend.API, x E24) *E24 { return e } -// Decompress Karabina's cyclotomic square result -func (e *E24) Decompress(api frontend.API, x E24) *E24 { +// DecompressKarabina2345 Karabina's cyclotomic square result +func (e *E24) DecompressKarabina2345(api frontend.API, x E24) *E24 { var t [3]E4 var _t [2]E4 @@ -549,10 +549,10 @@ func (e *E24) DivUnchecked(api frontend.API, e1, e2 E24) *E24 { return e } -// nSquareCompressed repeated compressed cyclotmic square -func (e *E24) nSquareCompressed(api frontend.API, n int) { +// nSquareKarabina2345 repeated compressed cyclotmic square +func (e *E24) nSquareKarabina2345(api frontend.API, n int) { for i := 0; i < n; i++ { - e.CyclotomicSquareCompressed(api, *e) + e.CyclotomicSquareKarabina2345(api, *e) } } diff --git a/std/algebra/native/fields_bls24315/e24_pairing.go b/std/algebra/native/fields_bls24315/e24_pairing.go index 1a43c8df85..f17bcf46c8 100644 --- a/std/algebra/native/fields_bls24315/e24_pairing.go +++ b/std/algebra/native/fields_bls24315/e24_pairing.go @@ -78,13 +78,13 @@ func (e *E24) Expt(api frontend.API, x E24, exponent uint64) *E24 { res.nSquare(api, 2) res.Mul(api, res, xInv) - res.nSquareCompressed(api, 8) - res.Decompress(api, res) + res.nSquareKarabina2345(api, 8) + res.DecompressKarabina2345(api, res) res.Mul(api, res, xInv) res.nSquare(api, 2) res.Mul(api, res, x) - res.nSquareCompressed(api, 20) - res.Decompress(api, res) + res.nSquareKarabina2345(api, 20) + res.DecompressKarabina2345(api, res) res.Mul(api, res, xInv) res.Conjugate(api, res) diff --git a/std/algebra/native/fields_bls24315/e24_test.go b/std/algebra/native/fields_bls24315/e24_test.go index 75adedf6ad..9201188bc0 100644 --- a/std/algebra/native/fields_bls24315/e24_test.go +++ b/std/algebra/native/fields_bls24315/e24_test.go @@ -194,25 +194,25 @@ func TestFp24CyclotomicSquare(t *testing.T) { } -type fp24CycloSquareCompressed struct { +type fp24CycloSquareKarabina2345 struct { A E24 B E24 `gnark:",public"` } -func (circuit *fp24CycloSquareCompressed) Define(api frontend.API) error { +func (circuit *fp24CycloSquareKarabina2345) Define(api frontend.API) error { var u, v E24 u.Square(api, circuit.A) - v.CyclotomicSquareCompressed(api, circuit.A) - v.Decompress(api, v) + v.CyclotomicSquareKarabina2345(api, circuit.A) + v.DecompressKarabina2345(api, v) u.AssertIsEqual(api, v) u.AssertIsEqual(api, circuit.B) return nil } -func TestFp24CyclotomicSquareCompressed(t *testing.T) { +func TestFp24CyclotomicSquareKarabina2345(t *testing.T) { - var circuit, witness fp24CycloSquareCompressed + var circuit, witness fp24CycloSquareKarabina2345 // witness values var a, b bls24315.E24 @@ -225,7 +225,7 @@ func TestFp24CyclotomicSquareCompressed(t *testing.T) { tmp.Mul(&tmp, &a) a.FrobeniusQuad(&tmp).Mul(&a, &tmp) - b.CyclotomicSquare(&a) + b.CyclotomicSquareCompressed(&a) b.DecompressKarabina(&b) witness.A.Assign(&a) witness.B.Assign(&b) diff --git a/std/commitments/kzg/verifier.go b/std/commitments/kzg/verifier.go index 434cb42151..b4d86705c1 100644 --- a/std/commitments/kzg/verifier.go +++ b/std/commitments/kzg/verifier.go @@ -257,6 +257,52 @@ type VerifyingKey[G1El algebra.G1ElementT, G2El algebra.G2ElementT] struct { G1 G1El } +// PlaceholderVerifyingKey returns a placeholder value for the verifying key for +// compiling if the witness is going to be in precomputed form using [ValueOfVerifyingKeyFixed]. +func PlaceholderVerifyingKey[G1El algebra.G1ElementT, G2El algebra.G2ElementT]() VerifyingKey[G1El, G2El] { + var ret VerifyingKey[G1El, G2El] + switch s := any(&ret).(type) { + // case *VerifyingKey[sw_bn254.G1Affine, sw_bn254.G2Affine]: + // tVk, ok := vk.(kzg_bn254.VerifyingKey) + // if !ok { + // return ret, fmt.Errorf("mismatching types %T %T", ret, vk) + // } + // s.G1 = sw_bn254.NewG1Affine(tVk.G1) + // s.G2[0] = sw_bn254.NewG2Affine(tVk.G2[0]) + // s.G2[1] = sw_bn254.NewG2Affine(tVk.G2[1]) + // case *VerifyingKey[sw_bls12377.G1Affine, sw_bls12377.G2Affine]: + // tVk, ok := vk.(kzg_bls12377.VerifyingKey) + // if !ok { + // return ret, fmt.Errorf("mismatching types %T %T", ret, vk) + // } + // s.G1 = sw_bls12377.NewG1Affine(tVk.G1) + // s.G2[0] = sw_bls12377.NewG2Affine(tVk.G2[0]) + // s.G2[1] = sw_bls12377.NewG2Affine(tVk.G2[1]) + // case *VerifyingKey[sw_bls12381.G1Affine, sw_bls12381.G2Affine]: + // tVk, ok := vk.(kzg_bls12381.VerifyingKey) + // if !ok { + // return ret, fmt.Errorf("mismatching types %T %T", ret, vk) + // } + // s.G1 = sw_bls12381.NewG1Affine(tVk.G1) + // s.G2[0] = sw_bls12381.NewG2Affine(tVk.G2[0]) + // s.G2[1] = sw_bls12381.NewG2Affine(tVk.G2[1]) + case *VerifyingKey[sw_bw6761.G1Affine, sw_bw6761.G2Affine]: + s.G2[0] = sw_bw6761.NewG2AffineFixedPlaceholder() + s.G2[1] = sw_bw6761.NewG2AffineFixedPlaceholder() + // case *VerifyingKey[sw_bls24315.G1Affine, sw_bls24315.G2Affine]: + // tVk, ok := vk.(kzg_bls24315.VerifyingKey) + // if !ok { + // return ret, fmt.Errorf("mismatching types %T %T", ret, vk) + // } + // s.G1 = sw_bls24315.NewG1Affine(tVk.G1) + // s.G2[0] = sw_bls24315.NewG2Affine(tVk.G2[0]) + // s.G2[1] = sw_bls24315.NewG2Affine(tVk.G2[1]) + default: + panic("not supported") + } + return ret +} + // ValueOfVerifyingKey initializes verifying key witness from the native // verifying key. It returns an error if there is a mismatch between the type // parameters and the provided verifying key type. @@ -309,6 +355,61 @@ func ValueOfVerifyingKey[G1El algebra.G1ElementT, G2El algebra.G2ElementT](vk an return ret, nil } +// ValueOfVerifyingKeyFixed initializes verifying key witness from the native +// verifying key and perform pre-computations for G2 elements. It returns an +// error if there is a mismatch between the type parameters and the provided +// verifying key type. Such witness is significantly larger than without +// precomputations. If witness size is important, then use [ValueOfVerifyingKey] +// instead. +func ValueOfVerifyingKeyFixed[G1El algebra.G1ElementT, G2El algebra.G2ElementT](vk any) (VerifyingKey[G1El, G2El], error) { + var ret VerifyingKey[G1El, G2El] + switch s := any(&ret).(type) { + // case *VerifyingKey[sw_bn254.G1Affine, sw_bn254.G2Affine]: + // tVk, ok := vk.(kzg_bn254.VerifyingKey) + // if !ok { + // return ret, fmt.Errorf("mismatching types %T %T", ret, vk) + // } + // s.G1 = sw_bn254.NewG1Affine(tVk.G1) + // s.G2[0] = sw_bn254.NewG2Affine(tVk.G2[0]) + // s.G2[1] = sw_bn254.NewG2Affine(tVk.G2[1]) + // case *VerifyingKey[sw_bls12377.G1Affine, sw_bls12377.G2Affine]: + // tVk, ok := vk.(kzg_bls12377.VerifyingKey) + // if !ok { + // return ret, fmt.Errorf("mismatching types %T %T", ret, vk) + // } + // s.G1 = sw_bls12377.NewG1Affine(tVk.G1) + // s.G2[0] = sw_bls12377.NewG2Affine(tVk.G2[0]) + // s.G2[1] = sw_bls12377.NewG2Affine(tVk.G2[1]) + // case *VerifyingKey[sw_bls12381.G1Affine, sw_bls12381.G2Affine]: + // tVk, ok := vk.(kzg_bls12381.VerifyingKey) + // if !ok { + // return ret, fmt.Errorf("mismatching types %T %T", ret, vk) + // } + // s.G1 = sw_bls12381.NewG1Affine(tVk.G1) + // s.G2[0] = sw_bls12381.NewG2Affine(tVk.G2[0]) + // s.G2[1] = sw_bls12381.NewG2Affine(tVk.G2[1]) + case *VerifyingKey[sw_bw6761.G1Affine, sw_bw6761.G2Affine]: + tVk, ok := vk.(kzg_bw6761.VerifyingKey) + if !ok { + return ret, fmt.Errorf("mismatching types %T %T", ret, vk) + } + s.G1 = sw_bw6761.NewG1Affine(tVk.G1) + s.G2[0] = sw_bw6761.NewG2AffineFixed(tVk.G2[0]) + s.G2[1] = sw_bw6761.NewG2AffineFixed(tVk.G2[1]) + // case *VerifyingKey[sw_bls24315.G1Affine, sw_bls24315.G2Affine]: + // tVk, ok := vk.(kzg_bls24315.VerifyingKey) + // if !ok { + // return ret, fmt.Errorf("mismatching types %T %T", ret, vk) + // } + // s.G1 = sw_bls24315.NewG1Affine(tVk.G1) + // s.G2[0] = sw_bls24315.NewG2Affine(tVk.G2[0]) + // s.G2[1] = sw_bls24315.NewG2Affine(tVk.G2[1]) + default: + return ret, fmt.Errorf("precomputation not supported") + } + return ret, nil +} + // Verifier allows verifying KZG opening proofs. type Verifier[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.G2ElementT] struct { api frontend.API diff --git a/std/commitments/kzg/verifier_test.go b/std/commitments/kzg/verifier_test.go index 9d57b62b4f..d0fba5a5e2 100644 --- a/std/commitments/kzg/verifier_test.go +++ b/std/commitments/kzg/verifier_test.go @@ -694,3 +694,112 @@ func TestBatchVerifyMultiPoints(t *testing.T) { assert.CheckCircuit(&circuit, test.WithValidAssignment(&assignment), test.WithCurves(ecc.BLS12_381), test.WithBackends(backend.PLONK)) } + +type KZGVerificationConstantVkCircuit[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GTEl algebra.GtElementT] struct { + vk VerifyingKey[G1El, G2El] `gnark:"-"` // override visibility for sub-definitions + Commitment[G1El] + OpeningProof[FR, G1El] + Point emulated.Element[FR] +} + +func (c *KZGVerificationConstantVkCircuit[FR, G1El, G2El, GTEl]) Define(api frontend.API) error { + verifier, err := NewVerifier[FR, G1El, G2El, GTEl](api) + if err != nil { + return fmt.Errorf("new verifier: %w", err) + } + if err := verifier.CheckOpeningProof(c.Commitment, c.OpeningProof, c.Point, c.vk); err != nil { + return fmt.Errorf("assert proof: %w", err) + } + return nil +} + +func TestKZGVerificationEmulated3ConstantVk(t *testing.T) { + assert := test.NewAssert(t) + + alpha, err := rand.Int(rand.Reader, ecc.BW6_761.ScalarField()) + assert.NoError(err) + srs, err := kzg_bw6761.NewSRS(kzgSize, alpha) + assert.NoError(err) + + f := make([]fr_bw6761.Element, polynomialSize) + for i := range f { + f[i].SetRandom() + } + + com, err := kzg_bw6761.Commit(f, srs.Pk) + assert.NoError(err) + + var point fr_bw6761.Element + point.SetRandom() + proof, err := kzg_bw6761.Open(f, point, srs.Pk) + assert.NoError(err) + + if err = kzg_bw6761.Verify(&com, &proof, point, srs.Vk); err != nil { + t.Fatal("verify proof", err) + } + + wCmt, err := ValueOfCommitment[sw_bw6761.G1Affine](com) + assert.NoError(err) + wProof, err := ValueOfOpeningProof[sw_bw6761.ScalarField, sw_bw6761.G1Affine](proof) + assert.NoError(err) + wVk, err := ValueOfVerifyingKeyFixed[sw_bw6761.G1Affine, sw_bw6761.G2Affine](srs.Vk) + assert.NoError(err) + wPt, err := ValueOfScalar[sw_bw6761.ScalarField](point) + assert.NoError(err) + + assignment := KZGVerificationConstantVkCircuit[sw_bw6761.ScalarField, sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]{ + Commitment: wCmt, + OpeningProof: wProof, + Point: wPt, + } + circuit := KZGVerificationConstantVkCircuit[sw_bw6761.ScalarField, sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]{ + vk: wVk, + } + assert.CheckCircuit(&circuit, test.WithValidAssignment(&assignment), test.WithCurves(ecc.BN254)) +} + +func TestKZGVerificationEmulated3Precomputed(t *testing.T) { + assert := test.NewAssert(t) + + alpha, err := rand.Int(rand.Reader, ecc.BW6_761.ScalarField()) + assert.NoError(err) + srs, err := kzg_bw6761.NewSRS(kzgSize, alpha) + assert.NoError(err) + + f := make([]fr_bw6761.Element, polynomialSize) + for i := range f { + f[i].SetRandom() + } + + com, err := kzg_bw6761.Commit(f, srs.Pk) + assert.NoError(err) + + var point fr_bw6761.Element + point.SetRandom() + proof, err := kzg_bw6761.Open(f, point, srs.Pk) + assert.NoError(err) + + if err = kzg_bw6761.Verify(&com, &proof, point, srs.Vk); err != nil { + t.Fatal("verify proof", err) + } + + wCmt, err := ValueOfCommitment[sw_bw6761.G1Affine](com) + assert.NoError(err) + wProof, err := ValueOfOpeningProof[sw_bw6761.ScalarField, sw_bw6761.G1Affine](proof) + assert.NoError(err) + wVk, err := ValueOfVerifyingKeyFixed[sw_bw6761.G1Affine, sw_bw6761.G2Affine](srs.Vk) + assert.NoError(err) + wPt, err := ValueOfScalar[sw_bw6761.ScalarField](point) + assert.NoError(err) + + assignment := KZGVerificationCircuit[sw_bw6761.ScalarField, sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]{ + VerifyingKey: wVk, + Commitment: wCmt, + OpeningProof: wProof, + Point: wPt, + } + circuit := KZGVerificationCircuit[sw_bw6761.ScalarField, sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]{ + VerifyingKey: PlaceholderVerifyingKey[sw_bw6761.G1Affine, sw_bw6761.G2Affine](), + } + assert.CheckCircuit(&circuit, test.WithValidAssignment(&assignment), test.WithCurves(ecc.BN254)) +} diff --git a/std/compress/lzss/compress.go b/std/compress/lzss/compress.go index 81cdb1bb6d..eb7c3fa4cb 100644 --- a/std/compress/lzss/compress.go +++ b/std/compress/lzss/compress.go @@ -50,7 +50,10 @@ func NewCompressor(dict []byte, level Level) (*Compressor, error) { dictData: dict, } c.buf.Grow(maxInputSize) - c.dictIndex = suffixarray.New(c.dictData, c.dictSa[:len(c.dictData)]) + if level != NoCompression { + // if we don't compress we don't need the dict. + c.dictIndex = suffixarray.New(c.dictData, c.dictSa[:len(c.dictData)]) + } c.level = level return c, nil } diff --git a/std/recursion/groth16/verifier.go b/std/recursion/groth16/verifier.go index 9a8f33cea1..b762d9a322 100644 --- a/std/recursion/groth16/verifier.go +++ b/std/recursion/groth16/verifier.go @@ -11,16 +11,20 @@ import ( fr_bls24315 "github.com/consensys/gnark-crypto/ecc/bls24-315/fr" "github.com/consensys/gnark-crypto/ecc/bn254" fr_bn254 "github.com/consensys/gnark-crypto/ecc/bn254/fr" + bw6761 "github.com/consensys/gnark-crypto/ecc/bw6-761" + fr_bw6761 "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" "github.com/consensys/gnark/backend/groth16" groth16backend_bls12377 "github.com/consensys/gnark/backend/groth16/bls12-377" groth16backend_bls12381 "github.com/consensys/gnark/backend/groth16/bls12-381" groth16backend_bls24315 "github.com/consensys/gnark/backend/groth16/bls24-315" groth16backend_bn254 "github.com/consensys/gnark/backend/groth16/bn254" + groth16backend_bw6761 "github.com/consensys/gnark/backend/groth16/bw6-761" "github.com/consensys/gnark/backend/witness" "github.com/consensys/gnark/constraint" "github.com/consensys/gnark/std/algebra" "github.com/consensys/gnark/std/algebra/emulated/sw_bls12381" "github.com/consensys/gnark/std/algebra/emulated/sw_bn254" + "github.com/consensys/gnark/std/algebra/emulated/sw_bw6761" "github.com/consensys/gnark/std/algebra/native/sw_bls12377" "github.com/consensys/gnark/std/algebra/native/sw_bls24315" "github.com/consensys/gnark/std/math/emulated" @@ -72,6 +76,14 @@ func ValueOfProof[G1El algebra.G1ElementT, G2El algebra.G2ElementT](proof groth1 ar.Ar = sw_bls24315.NewG1Affine(tProof.Ar) ar.Krs = sw_bls24315.NewG1Affine(tProof.Krs) ar.Bs = sw_bls24315.NewG2Affine(tProof.Bs) + case *Proof[sw_bw6761.G1Affine, sw_bw6761.G2Affine]: + tProof, ok := proof.(*groth16backend_bw6761.Proof) + if !ok { + return ret, fmt.Errorf("expected bls24315.Proof, got %T", proof) + } + ar.Ar = sw_bw6761.NewG1Affine(tProof.Ar) + ar.Krs = sw_bw6761.NewG1Affine(tProof.Krs) + ar.Bs = sw_bw6761.NewG2Affine(tProof.Bs) default: return ret, fmt.Errorf("unknown parametric type combination") } @@ -99,6 +111,27 @@ func PlaceholderVerifyingKey[G1El algebra.G1ElementT, G2El algebra.G2ElementT, G } } +func PlaceholderVerifyingKeyFixed[G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](ccs constraint.ConstraintSystem) VerifyingKey[G1El, G2El, GtEl] { + vk := VerifyingKey[G1El, G2El, GtEl]{ + G1: struct{ K []G1El }{ + K: make([]G1El, ccs.GetNbPublicVariables()), + }, + } + switch s := any(&vk).(type) { + case *VerifyingKey[sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]: + s.G2 = struct { + GammaNeg sw_bw6761.G2Affine + DeltaNeg sw_bw6761.G2Affine + }{ + GammaNeg: sw_bw6761.NewG2AffineFixedPlaceholder(), + DeltaNeg: sw_bw6761.NewG2AffineFixedPlaceholder(), + } + default: + panic("precomputation not supported") + } + return vk +} + // ValueOfVerifyingKey initializes witness from the given Groth16 verifying key. // It returns an error if there is a mismatch between the type parameters and // the provided native verifying key. @@ -185,6 +218,138 @@ func ValueOfVerifyingKey[G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl gammaNeg.Neg(&tVk.G2.Gamma) s.G2.DeltaNeg = sw_bls24315.NewG2Affine(deltaNeg) s.G2.GammaNeg = sw_bls24315.NewG2Affine(gammaNeg) + case *VerifyingKey[sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]: + tVk, ok := vk.(*groth16backend_bw6761.VerifyingKey) + if !ok { + return ret, fmt.Errorf("expected bw6761.VerifyingKey, got %T", vk) + } + // compute E + e, err := bw6761.Pair([]bw6761.G1Affine{tVk.G1.Alpha}, []bw6761.G2Affine{tVk.G2.Beta}) + if err != nil { + return ret, fmt.Errorf("precompute pairing: %w", err) + } + s.E = sw_bw6761.NewGTEl(e) + s.G1.K = make([]sw_bw6761.G1Affine, len(tVk.G1.K)) + for i := range s.G1.K { + s.G1.K[i] = sw_bw6761.NewG1Affine(tVk.G1.K[i]) + } + var deltaNeg, gammaNeg bw6761.G2Affine + deltaNeg.Neg(&tVk.G2.Delta) + gammaNeg.Neg(&tVk.G2.Gamma) + s.G2.DeltaNeg = sw_bw6761.NewG2Affine(deltaNeg) + s.G2.GammaNeg = sw_bw6761.NewG2Affine(gammaNeg) + default: + return ret, fmt.Errorf("unknown parametric type combination") + } + return ret, nil +} + +// ValueOfVerifyingKey initializes witness from the given Groth16 verifying key. +// It returns an error if there is a mismatch between the type parameters and +// the provided native verifying key. +func ValueOfVerifyingKeyFixed[G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT](vk groth16.VerifyingKey) (VerifyingKey[G1El, G2El, GtEl], error) { + var ret VerifyingKey[G1El, G2El, GtEl] + switch s := any(&ret).(type) { + // case *VerifyingKey[sw_bn254.G1Affine, sw_bn254.G2Affine, sw_bn254.GTEl]: + // tVk, ok := vk.(*groth16backend_bn254.VerifyingKey) + // if !ok { + // return ret, fmt.Errorf("expected bn254.VerifyingKey, got %T", vk) + // } + // // compute E + // e, err := bn254.Pair([]bn254.G1Affine{tVk.G1.Alpha}, []bn254.G2Affine{tVk.G2.Beta}) + // if err != nil { + // return ret, fmt.Errorf("precompute pairing: %w", err) + // } + // s.E = sw_bn254.NewGTEl(e) + // s.G1.K = make([]sw_bn254.G1Affine, len(tVk.G1.K)) + // for i := range s.G1.K { + // s.G1.K[i] = sw_bn254.NewG1Affine(tVk.G1.K[i]) + // } + // var deltaNeg, gammaNeg bn254.G2Affine + // deltaNeg.Neg(&tVk.G2.Delta) + // gammaNeg.Neg(&tVk.G2.Gamma) + // s.G2.DeltaNeg = sw_bn254.NewG2Affine(deltaNeg) + // s.G2.GammaNeg = sw_bn254.NewG2Affine(gammaNeg) + // case *VerifyingKey[sw_bls12377.G1Affine, sw_bls12377.G2Affine, sw_bls12377.GT]: + // tVk, ok := vk.(*groth16backend_bls12377.VerifyingKey) + // if !ok { + // return ret, fmt.Errorf("expected bn254.VerifyingKey, got %T", vk) + // } + // // compute E + // e, err := bls12377.Pair([]bls12377.G1Affine{tVk.G1.Alpha}, []bls12377.G2Affine{tVk.G2.Beta}) + // if err != nil { + // return ret, fmt.Errorf("precompute pairing: %w", err) + // } + // s.E = sw_bls12377.NewGTEl(e) + // s.G1.K = make([]sw_bls12377.G1Affine, len(tVk.G1.K)) + // for i := range s.G1.K { + // s.G1.K[i] = sw_bls12377.NewG1Affine(tVk.G1.K[i]) + // } + // var deltaNeg, gammaNeg bls12377.G2Affine + // deltaNeg.Neg(&tVk.G2.Delta) + // gammaNeg.Neg(&tVk.G2.Gamma) + // s.G2.DeltaNeg = sw_bls12377.NewG2Affine(deltaNeg) + // s.G2.GammaNeg = sw_bls12377.NewG2Affine(gammaNeg) + // case *VerifyingKey[sw_bls12381.G1Affine, sw_bls12381.G2Affine, sw_bls12381.GTEl]: + // tVk, ok := vk.(*groth16backend_bls12381.VerifyingKey) + // if !ok { + // return ret, fmt.Errorf("expected bls12381.VerifyingKey, got %T", vk) + // } + // // compute E + // e, err := bls12381.Pair([]bls12381.G1Affine{tVk.G1.Alpha}, []bls12381.G2Affine{tVk.G2.Beta}) + // if err != nil { + // return ret, fmt.Errorf("precompute pairing: %w", err) + // } + // s.E = sw_bls12381.NewGTEl(e) + // s.G1.K = make([]sw_bls12381.G1Affine, len(tVk.G1.K)) + // for i := range s.G1.K { + // s.G1.K[i] = sw_bls12381.NewG1Affine(tVk.G1.K[i]) + // } + // var deltaNeg, gammaNeg bls12381.G2Affine + // deltaNeg.Neg(&tVk.G2.Delta) + // gammaNeg.Neg(&tVk.G2.Gamma) + // s.G2.DeltaNeg = sw_bls12381.NewG2Affine(deltaNeg) + // s.G2.GammaNeg = sw_bls12381.NewG2Affine(gammaNeg) + // case *VerifyingKey[sw_bls24315.G1Affine, sw_bls24315.G2Affine, sw_bls24315.GT]: + // tVk, ok := vk.(*groth16backend_bls24315.VerifyingKey) + // if !ok { + // return ret, fmt.Errorf("expected bls12381.VerifyingKey, got %T", vk) + // } + // // compute E + // e, err := bls24315.Pair([]bls24315.G1Affine{tVk.G1.Alpha}, []bls24315.G2Affine{tVk.G2.Beta}) + // if err != nil { + // return ret, fmt.Errorf("precompute pairing: %w", err) + // } + // s.E = sw_bls24315.NewGTEl(e) + // s.G1.K = make([]sw_bls24315.G1Affine, len(tVk.G1.K)) + // for i := range s.G1.K { + // s.G1.K[i] = sw_bls24315.NewG1Affine(tVk.G1.K[i]) + // } + // var deltaNeg, gammaNeg bls24315.G2Affine + // deltaNeg.Neg(&tVk.G2.Delta) + // gammaNeg.Neg(&tVk.G2.Gamma) + // s.G2.DeltaNeg = sw_bls24315.NewG2Affine(deltaNeg) + // s.G2.GammaNeg = sw_bls24315.NewG2Affine(gammaNeg) + case *VerifyingKey[sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]: + tVk, ok := vk.(*groth16backend_bw6761.VerifyingKey) + if !ok { + return ret, fmt.Errorf("expected bw6761.VerifyingKey, got %T", vk) + } + // compute E + e, err := bw6761.Pair([]bw6761.G1Affine{tVk.G1.Alpha}, []bw6761.G2Affine{tVk.G2.Beta}) + if err != nil { + return ret, fmt.Errorf("precompute pairing: %w", err) + } + s.E = sw_bw6761.NewGTEl(e) + s.G1.K = make([]sw_bw6761.G1Affine, len(tVk.G1.K)) + for i := range s.G1.K { + s.G1.K[i] = sw_bw6761.NewG1Affine(tVk.G1.K[i]) + } + var deltaNeg, gammaNeg bw6761.G2Affine + deltaNeg.Neg(&tVk.G2.Delta) + gammaNeg.Neg(&tVk.G2.Gamma) + s.G2.DeltaNeg = sw_bw6761.NewG2AffineFixed(deltaNeg) + s.G2.GammaNeg = sw_bw6761.NewG2AffineFixed(gammaNeg) default: return ret, fmt.Errorf("unknown parametric type combination") } @@ -253,6 +418,14 @@ func ValueOfWitness[FR emulated.FieldParams](w witness.Witness) (Witness[FR], er for i := range vect { s.Public = append(s.Public, sw_bls24315.NewScalar(vect[i])) } + case *Witness[sw_bw6761.ScalarField]: + vect, ok := vec.(fr_bw6761.Vector) + if !ok { + return ret, fmt.Errorf("expected fr_bls24315.Vector, got %T", vec) + } + for i := range vect { + s.Public = append(s.Public, sw_bw6761.NewScalar(vect[i])) + } default: return ret, fmt.Errorf("unknown parametric type combination") } diff --git a/std/recursion/groth16/verifier_test.go b/std/recursion/groth16/verifier_test.go index 442cd4de8b..5ad6390558 100644 --- a/std/recursion/groth16/verifier_test.go +++ b/std/recursion/groth16/verifier_test.go @@ -22,6 +22,7 @@ import ( "github.com/consensys/gnark/std/algebra" "github.com/consensys/gnark/std/algebra/emulated/sw_bls12381" "github.com/consensys/gnark/std/algebra/emulated/sw_bn254" + "github.com/consensys/gnark/std/algebra/emulated/sw_bw6761" "github.com/consensys/gnark/std/algebra/native/sw_bls12377" "github.com/consensys/gnark/std/algebra/native/sw_bls24315" "github.com/consensys/gnark/std/hash/sha2" @@ -302,3 +303,94 @@ func TestValueOfVerifyingKey(t *testing.T) { _ = vvk }, "bls24315") } + +func TestBW6InBN254(t *testing.T) { + assert := test.NewAssert(t) + innerCcs, innerVK, innerWitness, innerProof := getInner(assert, ecc.BW6_761.ScalarField()) + + // outer proof + circuitVk, err := ValueOfVerifyingKey[sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl](innerVK) + assert.NoError(err) + circuitWitness, err := ValueOfWitness[sw_bw6761.ScalarField](innerWitness) + assert.NoError(err) + circuitProof, err := ValueOfProof[sw_bw6761.G1Affine, sw_bw6761.G2Affine](innerProof) + assert.NoError(err) + + outerCircuit := &OuterCircuit[sw_bw6761.ScalarField, sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]{ + InnerWitness: PlaceholderWitness[sw_bw6761.ScalarField](innerCcs), + VerifyingKey: PlaceholderVerifyingKey[sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl](innerCcs), + } + outerAssignment := &OuterCircuit[sw_bw6761.ScalarField, sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]{ + InnerWitness: circuitWitness, + Proof: circuitProof, + VerifyingKey: circuitVk, + } + assert.CheckCircuit(outerCircuit, test.WithValidAssignment(outerAssignment), test.WithCurves(ecc.BN254)) +} + +func TestBW6InBN254Precomputed(t *testing.T) { + assert := test.NewAssert(t) + innerCcs, innerVK, innerWitness, innerProof := getInner(assert, ecc.BW6_761.ScalarField()) + + // outer proof + circuitVk, err := ValueOfVerifyingKeyFixed[sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl](innerVK) + assert.NoError(err) + circuitWitness, err := ValueOfWitness[sw_bw6761.ScalarField](innerWitness) + assert.NoError(err) + circuitProof, err := ValueOfProof[sw_bw6761.G1Affine, sw_bw6761.G2Affine](innerProof) + assert.NoError(err) + + outerCircuit := &OuterCircuit[sw_bw6761.ScalarField, sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]{ + InnerWitness: PlaceholderWitness[sw_bw6761.ScalarField](innerCcs), + VerifyingKey: PlaceholderVerifyingKeyFixed[sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl](innerCcs), + } + outerAssignment := &OuterCircuit[sw_bw6761.ScalarField, sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]{ + InnerWitness: circuitWitness, + Proof: circuitProof, + VerifyingKey: circuitVk, + } + assert.CheckCircuit(outerCircuit, test.WithValidAssignment(outerAssignment), test.WithCurves(ecc.BN254)) +} + +type OuterCircuitConstant[FR emulated.FieldParams, G1El algebra.G1ElementT, G2El algebra.G2ElementT, GtEl algebra.GtElementT] struct { + Proof Proof[G1El, G2El] + vk VerifyingKey[G1El, G2El, GtEl] `gnark:"-"` + InnerWitness Witness[FR] +} + +func (c *OuterCircuitConstant[FR, G1El, G2El, GtEl]) Define(api frontend.API) error { + curve, err := algebra.GetCurve[FR, G1El](api) + if err != nil { + return fmt.Errorf("new curve: %w", err) + } + pairing, err := algebra.GetPairing[G1El, G2El, GtEl](api) + if err != nil { + return fmt.Errorf("get pairing: %w", err) + } + verifier := NewVerifier(curve, pairing) + err = verifier.AssertProof(c.vk, c.Proof, c.InnerWitness) + return err +} + +func TestBW6InBN254Constant(t *testing.T) { + assert := test.NewAssert(t) + innerCcs, innerVK, innerWitness, innerProof := getInner(assert, ecc.BW6_761.ScalarField()) + + // outer proof + circuitVk, err := ValueOfVerifyingKeyFixed[sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl](innerVK) + assert.NoError(err) + circuitWitness, err := ValueOfWitness[sw_bw6761.ScalarField](innerWitness) + assert.NoError(err) + circuitProof, err := ValueOfProof[sw_bw6761.G1Affine, sw_bw6761.G2Affine](innerProof) + assert.NoError(err) + + outerCircuit := &OuterCircuitConstant[sw_bw6761.ScalarField, sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]{ + InnerWitness: PlaceholderWitness[sw_bw6761.ScalarField](innerCcs), + vk: circuitVk, + } + outerAssignment := &OuterCircuitConstant[sw_bw6761.ScalarField, sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]{ + InnerWitness: circuitWitness, + Proof: circuitProof, + } + assert.CheckCircuit(outerCircuit, test.WithValidAssignment(outerAssignment), test.WithCurves(ecc.BN254)) +}