From a009e22320f812d381d4705a0a013c949e50c7da Mon Sep 17 00:00:00 2001 From: Hussein Ait Lahcen Date: Thu, 11 Jan 2024 20:05:43 +0100 Subject: [PATCH] feat(galois): more tests and optimized cofactor clearing --- evm/contracts/clients/Verifier.sol | 52 +-- evm/tests/src/Verifier.t.sol | 8 +- galoisd/cmd/galoisd/cmd/example_prove.go | 29 +- galoisd/go.mod | 4 +- galoisd/go.sum | 8 +- galoisd/grpc/api/v1/server.go | 15 + galoisd/pkg/emulated/g2.go | 424 ++++++++++-------- galoisd/pkg/emulated/g2_test.go | 133 ++++++ galoisd/pkg/lightclient/adjacent/circuit.go | 6 +- .../pkg/lightclient/nonadjacent/circuit.go | 6 +- .../lightclient/nonadjacent/circuit_test.go | 227 ---------- galoisd/pkg/proto/api_test.go | 2 +- .../cometbft/cometbft/crypto/bn254/bn254.go | 24 +- galoisd/vendor/modules.txt | 13 +- lib/cometbls-groth16-verifier/src/lib.rs | 67 +-- uniond/go.mod | 6 +- uniond/go.sum | 8 +- .../cometbft/cometbft/crypto/bn254/bn254.go | 24 +- uniond/vendor/modules.txt | 8 +- 19 files changed, 516 insertions(+), 548 deletions(-) create mode 100644 galoisd/pkg/emulated/g2_test.go delete mode 100644 galoisd/pkg/lightclient/nonadjacent/circuit_test.go diff --git a/evm/contracts/clients/Verifier.sol b/evm/contracts/clients/Verifier.sol index 328f5b30be..6718b1b3ae 100644 --- a/evm/contracts/clients/Verifier.sol +++ b/evm/contracts/clients/Verifier.sol @@ -47,65 +47,65 @@ contract Verifier is IZKVerifierV2 { // Groth16 alpha point in G1 uint256 constant ALPHA_X = - 4545497642472568342690310908405747139240036052727362141781732401147427278332; + 19681918582342826141927615585844819827950494091197079841581098590160509489088; uint256 constant ALPHA_Y = - 21657279939237288836606942458710668831714385968774740438494149333436465843139; + 18976290249472753264792873488771466812990993964894861063003977176791880491271; // Groth16 beta point in G2 in powers of i uint256 constant BETA_NEG_X_0 = - 13700154589878825236434612482502516805936642904411498786936854624077294311682; + 17542740552152507448113209307107151415915067720344615090625491194497459342657; uint256 constant BETA_NEG_X_1 = - 7497643146587701237207141457042187540104153076302400103164161194096334760677; + 7391419840357209888406550113304609596117324320456425532340186750677647200951; uint256 constant BETA_NEG_Y_0 = - 12061640834087756293066688745856043387269947926655334556036641601689450213892; + 19792144694189938307894275195643141100067567927017820917795773938883367365412; uint256 constant BETA_NEG_Y_1 = - 21393283571400157993861538207686485746031497872415111298623015303717243066096; + 17211163405892785765064384698545439693511041026525583483293852246253094999960; // Groth16 gamma point in G2 in powers of i uint256 constant GAMMA_NEG_X_0 = - 20107534645331006032402749367045367765170696291609897560802407293332329737698; + 18606218405301761142065379515313210013062685838824185304765852768028043703753; uint256 constant GAMMA_NEG_X_1 = - 6135886662735635672007238208825068442340242201492563368708252608220727995665; + 14540190418613230568675456016157166803361906410442369269514923787931816842661; uint256 constant GAMMA_NEG_Y_0 = - 21304025422358833441536274892652379608221995762381190373024977840945920102186; + 8951288781929330311740771353182492599878185290969923949343519917796557268219; uint256 constant GAMMA_NEG_Y_1 = - 4753268754089710768567929407828664634165004523165700048765343123172353157016; + 8812741715039891617796654796990655544152364726104502685064434338923152748332; // Groth16 delta point in G2 in powers of i uint256 constant DELTA_NEG_X_0 = - 7466991077765871589299219136524534381311757366195842209075383099119159267653; + 4060446808760699692477462845230990229944734548192291022910719993807902355759; uint256 constant DELTA_NEG_X_1 = - 3993057849766236546786517975621342624904647686274232418256214891442175004595; + 17803970575871171031178686612122420011629668206026599803865929512658387807614; uint256 constant DELTA_NEG_Y_0 = - 4828611495163838268492412020246640239075991252847184258785137740314670688312; + 17124643930680839105590130418783735638684807807530957846654257326870483890070; uint256 constant DELTA_NEG_Y_1 = - 7912615802333993426639034373142603363982203530625133012030570299570446825498; + 7629814864078422326695261874116750521593226108645261491403040533513921542483; // Constant and public input points uint256 constant CONSTANT_X = - 12730996440491230341898748596203954698739716661771354666644872057102948394726; + 18676861125246766292059080199576268981667767278300819763274799276376054409743; uint256 constant CONSTANT_Y = - 18188119481706424113895919492547204030227563509791341513627568384483237465563; + 5269797328666185490526867808814966151140271775451395274640052553630677159076; uint256 constant PUB_0_X = - 8627654005047498327557788753897980447566216968617518507065934795873759856303; + 3010349418202885908760025883515590778403141726894708222433169071368055690912; uint256 constant PUB_0_Y = - 7258461021217822820323520100501249447378191264854934186351306877513723742793; + 20724571387755619214201948546999886629454427058875835531981815961969686023639; uint256 constant PUB_1_X = - 10867392565326439682947570558412590838055450106691458097719409041212951853401; + 1718980496599153571806495443921791801530740535933073284474040850386158191735; uint256 constant PUB_1_Y = - 3124325152732842906431467328196929469314595151752342394843391644384931489602; + 3288376032837046783397899352143814445169932711782482341330476711768756263890; uint256 constant PUB_2_X = - 6627862564104432829412837659942319893523740327889349003623985834967392523238; + 9266521894078168597926726825960443668976816125222306871429246198851182099011; uint256 constant PUB_2_Y = - 11980409132042083280769458186828234442115366931894286356450034429211995205398; + 9416966066664703605394453818829209487654794520205974695819389893969431707374; uint256 constant PUB_3_X = - 8352580944529539453233628007042528490297057973561012318225452772905637057834; + 13194582768609510874189454527180276310818912484460263820189470814556014162264; uint256 constant PUB_3_Y = - 16521805616951802411915576898364661283847250025318378340431083135006258712933; + 15983647339013447433771242507224193645257463334651420839328305715367829062538; uint256 constant PUB_4_X = - 12071952363228031783312741175393664539881674330807724365734090335572247236031; + 13160686484300787492313686811371534896624215839999346591796239441200125629208; uint256 constant PUB_4_Y = - 15697249904809157640137081638559691717147113859496833342722786814178099529209; + 11709584278193617231017776985640196897412209200566866495381859539145549732339; /// Compute the public input linear combination. /// @notice Reverts with PublicInputNotInField if the input is not in the field. diff --git a/evm/tests/src/Verifier.t.sol b/evm/tests/src/Verifier.t.sol index 3ad9df300d..bf379101c7 100644 --- a/evm/tests/src/Verifier.t.sol +++ b/evm/tests/src/Verifier.t.sol @@ -7,10 +7,10 @@ contract VerifierTests { function testVerifier_ok() public { new Verifier().verifyZKP( - 0x219BEFB142BED271ACC41A52BA3F412BD1418AED36474A76AEFBFAD12CC6B592, - 0x219BEFB142BED271ACC41A52BA3F412BD1418AED36474A76AEFBFAD12CC6B592, - hex"650802113E0200000000000022480A207022627E60ED78120D2FE8DC7ACDB58A2321B0304F8912D2DFB86CE038E23CA812240801122041B8793236EE0980E2EAF1A2FAD268C4A3D8979A0C432F06E284EEC5E74DD69C320E756E696F6E2D6465766E65742D31", - hex"170904B6B6F8E61E6E2D357436C7C3671E0ADE5ECF97E7A7A644F4B9F4DCC865138AAB8106303EFD304171C3B1E5181E4772AE47A050E19D9074BFD59072EE971FAC59DE603A8E7A677C4B55BD96FB62566CABD242D787687A86820E7ECD270407748CFCC9A3C646DD773D06AF98AB4ACBDF0FD76069212ABFF40C73C1FE0017073337A045A075449995D9B64417D017B670950E6C4F0BE8D8DA1AAFC41C3F4F0DCC256FD3B003EC5FC4A1A8BF7638FE2F703322DD418CC05E2EABC2A5801EA70CBC6020CA6DE288936436764093B0B18F815382DCDD75CEDC5B9D2B366478681C3B99E0A7F21D90D856C8AA59693A800A144D730737C3FD3E21B5DEBD1FC2B228516CBE9584853821FAE64F1C903936C07392529A5FB430007B3EB94C7EEB2F26A8A6B5E8474E4C283A2FD7A9DAD63A78230696F6D882D654725E28198653902B1CECF46DC9C200AEB9DB432A8ACA40EECD8CBA27C32975F1B338B7EFFC2CBA" + 0x0472116C575F0FECF44ED4F91C34E9E7B67CE8C911FC67F304C2B804330B61F0, + 0x0472116C575F0FECF44ED4F91C34E9E7B67CE8C911FC67F304C2B804330B61F0, + hex"650802113E0200000000000022480A20DFAD1A5E2BB2B94BD7ED5F4F85199E0DDD95FB4687CFBF19B36865845BD16E20122408011220E32B1FA520CE4F9D0C1A2C80D51FB1F09B9C241101BE70D5CE0DC0F11B009863320E756E696F6E2D6465766E65742D31", + hex"19EB187C4EA70DA41CE1C2E9C81D7F4ACC9B8CD85A98AD59A64BD9D820A1D4E41DA150358EC5AFCBA7407D66AFABD59B1B92095D6A797572FAE6FE9C9A500E7C284C0AF8310181C072C1002961BE007DFC68DFDBD9CCF930410153829DA0E00D20ECDCE1DF5674D69A70BFB0891CE61888AADC6B362E27C6E4C9D1905ED327402EEE2EB635235068CBCBAB909D9A14A8992E74DE17D69269FC60CC448A832F8E1BCA6C3426A79029508AEE21DBB718F016FEC33A0A500EA14A05E3E19548634F04011075515FF876980559B120DC247A190BF699C2BA19ECDA92220AADAF3F5A1D502B8552BCC4BBDBA3C53EA39FAA5D6A7D23E06AE8F52AEECCED971D7D353613F7C750995DDD6BCCBB3E3185CF5B53EADAA6FA412665A0910FF709E49CFDFB0530B479EE5F0774588EE7397F7E050A9F4C87DB7989E2557E76353BF98CF7B922EB5DBE6D66AEA64C33AF7D6469BF3EFD5ACA10936CED35DAE692D489AAF8C2" ); } } diff --git a/galoisd/cmd/galoisd/cmd/example_prove.go b/galoisd/cmd/galoisd/cmd/example_prove.go index 16763920df..421c2f0931 100644 --- a/galoisd/cmd/galoisd/cmd/example_prove.go +++ b/galoisd/cmd/galoisd/cmd/example_prove.go @@ -2,11 +2,10 @@ package cmd import ( "context" - "encoding/hex" + "crypto/rand" "fmt" provergrpc "galois/grpc/api/v1" "math/big" - "math/rand" "strconv" "cosmossdk.io/math" @@ -37,18 +36,24 @@ func ExampleProveCmd() *cobra.Command { if err != nil { return &types.SimpleValidator{}, err } + power, err := rand.Int(rand.Reader, big.NewInt(9223372036854775807/8)) + if err != nil { + return &types.SimpleValidator{}, err + } return &types.SimpleValidator{ PubKey: &protoPK, - VotingPower: sdk.TokensToConsensusPower(math.NewInt(rand.Int63n(9223372036854775807/8)), sdk.DefaultPowerReduction), + VotingPower: sdk.TokensToConsensusPower(math.NewInt(power.Int64()), sdk.DefaultPowerReduction), }, nil } - blockHash, err := hex.DecodeString("7022627E60ED78120D2FE8DC7ACDB58A2321B0304F8912D2DFB86CE038E23CA8") + blockHash := make([]byte, 32) + _, err = rand.Read(blockHash) if err != nil { return err } - partSetHeaderHash, err := hex.DecodeString("41B8793236EE0980E2EAF1A2FAD268C4A3D8979A0C432F06E284EEC5E74DD69C") + partSetHeaderHash := make([]byte, 32) + _, err = rand.Read(partSetHeaderHash) if err != nil { return err } @@ -93,11 +98,15 @@ func ExampleProveCmd() *cobra.Command { if votingPower >= int(totalPower)/3*2 { break } - index := rand.Int31n(int32(nbOfValidators)) - if bitmap.Bit(int(index)) == 0 { - votingPower += int(validators[index].VotingPower) - bitmap.SetBit(&bitmap, int(index), 1) - sig, err := privKeys[index].Sign(signedBytes) + index, err := rand.Int(rand.Reader, big.NewInt(int64(nbOfValidators))) + if err != nil { + return err + } + i := index.Int64() + if bitmap.Bit(int(i)) == 0 { + votingPower += int(validators[i].VotingPower) + bitmap.SetBit(&bitmap, int(i), 1) + sig, err := privKeys[i].Sign(signedBytes) if err != nil { return err } diff --git a/galoisd/go.mod b/galoisd/go.mod index 7064e06b28..e9ad599a63 100644 --- a/galoisd/go.mod +++ b/galoisd/go.mod @@ -111,10 +111,10 @@ require ( ) replace ( - github.com/cometbft/cometbft => github.com/unionlabs/cometbls v0.0.0-20240108104619-5ed53d0e59b9 + github.com/cometbft/cometbft => github.com/unionlabs/cometbls v0.0.0-20240111183309-e159e964fa07 github.com/consensys/gnark => github.com/consensys/gnark v0.9.1-0.20231013131835-4ebcccd9c0a8 // Fork of gnark crypto until https://github.com/ConsenSys/gnark-crypto/pull/314 is merged github.com/consensys/gnark-crypto => github.com/unionlabs/gnark-crypto v0.0.0-20231016072529-15c0507b6578 - github.com/cosmos/cosmos-sdk => github.com/unionlabs/cosmos-sdk v0.0.0-20240108104904-d7de88f54965 + github.com/cosmos/cosmos-sdk => github.com/unionlabs/cosmos-sdk v0.0.0-20240111183419-b58f90f260ce github.com/cosmos/gogoproto => github.com/cosmos/gogoproto v1.4.11 ) diff --git a/galoisd/go.sum b/galoisd/go.sum index ca4ae15941..0099c382c8 100644 --- a/galoisd/go.sum +++ b/galoisd/go.sum @@ -423,10 +423,10 @@ github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/unionlabs/cometbls v0.0.0-20240108104619-5ed53d0e59b9 h1:geQswI0cfu5sD3wprwn8SkIfnNkAmRoDyuEt7JU7p/4= -github.com/unionlabs/cometbls v0.0.0-20240108104619-5ed53d0e59b9/go.mod h1:3H1gcLEVOQZbPwdH8gyv4UzwHtEawNgcnytglkCQVOQ= -github.com/unionlabs/cosmos-sdk v0.0.0-20240108104904-d7de88f54965 h1:pwK3MTnhxialeoEMpU632IjzY8gu53dFoDHya6sY3A8= -github.com/unionlabs/cosmos-sdk v0.0.0-20240108104904-d7de88f54965/go.mod h1:9QHZ3nex7R4cnZuGd/jmzk5nzsQ+7zxblS5MwshytQw= +github.com/unionlabs/cometbls v0.0.0-20240111183309-e159e964fa07 h1:y2q9sWscXNgo0w/iDdnRID3Fd2s4Mbdcn4poDwwSfpI= +github.com/unionlabs/cometbls v0.0.0-20240111183309-e159e964fa07/go.mod h1:3H1gcLEVOQZbPwdH8gyv4UzwHtEawNgcnytglkCQVOQ= +github.com/unionlabs/cosmos-sdk v0.0.0-20240111183419-b58f90f260ce h1:XsA/6QgQixsGW6CBOFYaK6D/viGcRBXF4THJhhBP2LM= +github.com/unionlabs/cosmos-sdk v0.0.0-20240111183419-b58f90f260ce/go.mod h1:l6W0x49uOfoq2JVMJGE6OqmYtBcUssRCNXlPXEzp3cY= github.com/unionlabs/gnark-crypto v0.0.0-20231016072529-15c0507b6578 h1:Owzup0XvshGNHgS1s0xUI/mZM+fPvTT7dLg7P0cT2vQ= github.com/unionlabs/gnark-crypto v0.0.0-20231016072529-15c0507b6578/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= diff --git a/galoisd/grpc/api/v1/server.go b/galoisd/grpc/api/v1/server.go index 986df87bdb..0596b3831e 100644 --- a/galoisd/grpc/api/v1/server.go +++ b/galoisd/grpc/api/v1/server.go @@ -510,6 +510,21 @@ func loadOrCreate(r1csPath string, pkPath string, vkPath string) (cs_bn254.R1CS, return cs, pk, vk, err } + log.Printf("VK Alpha X: %v", vk.G1.Alpha.X.String()) + log.Printf("VK Alpha Y: %v", vk.G1.Alpha.Y.String()) + log.Printf("VK Beta X0: %v", vk.G2.Beta.X.A0.String()) + log.Printf("VK Beta X1: %v", vk.G2.Beta.X.A1.String()) + log.Printf("VK Beta Y0: %v", vk.G2.Beta.Y.A0.String()) + log.Printf("VK Beta Y1: %v", vk.G2.Beta.Y.A1.String()) + log.Printf("VK Gamma X0: %v", vk.G2.Gamma.X.A0.String()) + log.Printf("VK Gamma X1: %v", vk.G2.Gamma.X.A1.String()) + log.Printf("VK Gamma Y0: %v", vk.G2.Gamma.Y.A0.String()) + log.Printf("VK Gamma Y1: %v", vk.G2.Gamma.Y.A1.String()) + log.Printf("VK Delta X0: %v", vk.G2.Delta.X.A0.String()) + log.Printf("VK Delta X1: %v", vk.G2.Delta.X.A1.String()) + log.Printf("VK Delta Y0: %v", vk.G2.Delta.Y.A0.String()) + log.Printf("VK Delta Y1: %v", vk.G2.Delta.Y.A1.String()) + return cs, pk, vk, nil } } diff --git a/galoisd/pkg/emulated/g2.go b/galoisd/pkg/emulated/g2.go index 4db51dee8c..4ee88d2e78 100644 --- a/galoisd/pkg/emulated/g2.go +++ b/galoisd/pkg/emulated/g2.go @@ -1,7 +1,6 @@ package g2 import ( - "fmt" "math/big" "github.com/consensys/gnark-crypto/ecc/bn254" @@ -34,7 +33,7 @@ func init() { solver.RegisterHint(hintSqrt) solver.RegisterHint(hintLegendre) - solver.RegisterHint(hintDebug) + } // Caller must ensure the root exists by calling legendre @@ -76,18 +75,46 @@ func hintLegendre(nativeMod *big.Int, nativeInputs, nativeOutputs []*big.Int) er }) } -func hintDebug(nativeMod *big.Int, nativeInputs, nativeOutputs []*big.Int) error { - return emulated.UnwrapHint(nativeInputs, nativeOutputs, - func(mod *big.Int, inputs, outputs []*big.Int) error { - var a bn254.E2 - - a.A0.SetBigInt(inputs[0]) - a.A1.SetBigInt(inputs[1]) +type EmulatedAPI struct { + api frontend.API + field *emulated.Field[emulated.BN254Fp] + fieldR *emulated.Field[emulated.BN254Fr] + ext2 *fields_bn254.Ext2 + u, v *fields_bn254.E2 +} - fmt.Println("P = ", a) +func NewEmulatedAPI(api frontend.API) (*EmulatedAPI, error) { + field, err := emulated.NewField[emulated.BN254Fp](api) + if err != nil { + return nil, err + } + fieldR, err := emulated.NewField[emulated.BN254Fr](api) + if err != nil { + return nil, err + } + u := fields_bn254.E2{ + A0: emulated.ValueOf[emulated.BN254Fp]("21575463638280843010398324269430826099269044274347216827212613867836435027261"), + A1: emulated.ValueOf[emulated.BN254Fp]("10307601595873709700152284273816112264069230130616436755625194854815875713954"), + } + v := fields_bn254.E2{ + A0: emulated.ValueOf[emulated.BN254Fp]("2821565182194536844548159561693502659359617185244120367078079554186484126554"), + A1: emulated.ValueOf[emulated.BN254Fp]("3505843767911556378687030309984248845540243509899259641013678093033130930403"), + } + ext2 := fields_bn254.NewExt2(api) + return &EmulatedAPI{ + api: api, + field: field, + fieldR: fieldR, + ext2: ext2, + u: &u, + v: &v, + }, nil +} - return nil - }) +// AssertIsEqual asserts that p and q are the same point. +func (e *EmulatedAPI) AssertIsEqual(p, q *gadget.G2Affine) { + e.ext2.AssertIsEqual(&p.X, &q.X) + e.ext2.AssertIsEqual(&p.Y, &q.Y) } // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function @@ -102,38 +129,26 @@ func hintDebug(nativeMod *big.Int, nativeInputs, nativeOutputs []*big.Int) error // 3. sign_1 = x_1 mod 2 // 4. s = sign_0 OR (zero_0 AND sign_1) # Avoid short-circuit logic ops // 5. return s -func g2Sgn0Circuit(api frontend.API, z *fields_bn254.E2) frontend.Variable { - field, err := emulated.NewField[emulated.BN254Fp](api) - if err != nil { - panic(err) - } - - a0b := field.ToBits(&z.A0) +func (e *EmulatedAPI) g2Sgn0Circuit(z *fields_bn254.E2) frontend.Variable { + a0b := e.field.ToBits(&z.A0) sign_0 := a0b[0] - zero_0 := field.IsZero(&z.A0) + zero_0 := e.field.IsZero(&z.A0) - a1b := field.ToBits(&z.A1) + a1b := e.field.ToBits(&z.A1) sign_1 := a1b[0] - sign := api.Or(sign_0, api.And(zero_0, sign_1)) + sign := e.api.Or(sign_0, e.api.And(zero_0, sign_1)) return sign } // Shallue-van de Woestijne method // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-shallue-van-de-woestijne-met -func MapToCurve(api frontend.API, u *fields_bn254.E2) *gadget.G2Affine { - field, err := emulated.NewField[emulated.BN254Fp](api) - if err != nil { - panic(err) - } - - e := fields_bn254.NewExt2(api) - +func (e *EmulatedAPI) MapToCurve(u *fields_bn254.E2) *gadget.G2Affine { // Legendre must be called before calling sqrt sqrt := func(x *fields_bn254.E2) *fields_bn254.E2 { - roots, err := field.NewHint(hintSqrt, 2, &x.A0, &x.A1) + roots, err := e.field.NewHint(hintSqrt, 2, &x.A0, &x.A1) if err != nil { panic(err) } @@ -142,17 +157,17 @@ func MapToCurve(api frontend.API, u *fields_bn254.E2) *gadget.G2Affine { A1: *roots[1], } // Ensure valid root - e.AssertIsEqual(x, e.Square(root)) + e.ext2.AssertIsEqual(x, e.ext2.Square(root)) return root } legendre := func(x *fields_bn254.E2) (frontend.Variable, *fields_bn254.E2) { - legendres, err := field.NewHint(hintLegendre, 1, &x.A0, &x.A1) + legendres, err := e.field.NewHint(hintLegendre, 1, &x.A0, &x.A1) if err != nil { panic(err) } legendre := legendres[0].Limbs[0] - roots, err := field.NewHint(hintSqrt, 2, &x.A0, &x.A1) + roots, err := e.field.NewHint(hintSqrt, 2, &x.A0, &x.A1) if err != nil { panic(err) } @@ -161,9 +176,9 @@ func MapToCurve(api frontend.API, u *fields_bn254.E2) *gadget.G2Affine { A1: *roots[1], } // Ensure valid legendre - api.AssertIsBoolean(legendre) + e.api.AssertIsBoolean(legendre) // Ensure valid branch - e.AssertIsEqual(x, e.Select(legendre, e.Square(root), x)) + e.ext2.AssertIsEqual(x, e.ext2.Select(legendre, e.ext2.Square(root), x)) // TODO assert root^2 != x if legendre == 0 return legendre, root } @@ -199,99 +214,121 @@ func MapToCurve(api frontend.API, u *fields_bn254.E2) *gadget.G2Affine { A1: fp.Element{11163104453509316115, 7271947710149976975, 4894807947557820282, 3366254582553786647}, }) - one = e.One() + one = e.ext2.One() // 1. tv1 = u^2 - tv1 = e.Square(u) + tv1 = e.ext2.Square(u) // 2. tv1 = tv1 * c1 - tv1 = e.Mul(tv1, &c1) + tv1 = e.ext2.Mul(tv1, &c1) // 3. tv2 = 1 + tv1 - tv2 = e.Add(one, tv1) + tv2 = e.ext2.Add(one, tv1) // 4. tv1 = 1 - tv1 - tv1 = e.Sub(one, tv1) + tv1 = e.ext2.Sub(one, tv1) // 5. tv3 = tv1 * tv2 - tv3 = e.Mul(tv1, tv2) + tv3 = e.ext2.Mul(tv1, tv2) // 6. tv3 = inv0(tv3) - tv3 = e.Inverse(tv3) + tv3 = e.ext2.Inverse(tv3) // 7. tv4 = u * tv1 - tv4 = e.Mul(u, tv1) + tv4 = e.ext2.Mul(u, tv1) // 8. tv4 = tv4 * tv3 - tv4 = e.Mul(tv4, tv3) + tv4 = e.ext2.Mul(tv4, tv3) // 9. tv4 = tv4 * c3 - tv4 = e.Mul(tv4, &c3) + tv4 = e.ext2.Mul(tv4, &c3) // 10. x1 = c2 - tv4 - x1 = e.Sub(&c2, tv4) + x1 = e.ext2.Sub(&c2, tv4) // 11. gx1 = x1^2 - gx1 = e.Square(x1) + gx1 = e.ext2.Square(x1) // 12. gx1 = gx1 + A // !!! NOOP !!! // 13. gx1 = gx1 * x1 - gx1 = e.Mul(gx1, x1) + gx1 = e.ext2.Mul(gx1, x1) // 14. gx1 = gx1 + B - gx1 = e.Add(gx1, &B) + gx1 = e.ext2.Add(gx1, &B) // 15. e1 = is_square(gx1) e1, _ := legendre(gx1) // 16. x2 = c2 + tv4 - x2 = e.Add(&c2, tv4) + x2 = e.ext2.Add(&c2, tv4) // 17. gx2 = x2^2 - gx2 = e.Square(x2) + gx2 = e.ext2.Square(x2) // 18. gx2 = gx2 + A // !!! NOOP !!! // 19. gx2 = gx2 * x2 - gx2 = e.Mul(gx2, x2) + gx2 = e.ext2.Mul(gx2, x2) // 20. gx2 = gx2 + B - gx2 = e.Add(gx2, &B) + gx2 = e.ext2.Add(gx2, &B) // 21. e2 = is_square(gx2) AND NOT e1 # Avoid short-circuit logic ops gx2Square, _ := legendre(gx2) - e2 := api.And(gx2Square, api.Select(e1, 0, 1)) + e2 := e.api.And(gx2Square, e.api.Select(e1, 0, 1)) // 22. x3 = tv2^2 - x3 = e.Square(tv2) + x3 = e.ext2.Square(tv2) // 23. x3 = x3 * tv3 - x3 = e.Mul(x3, tv3) + x3 = e.ext2.Mul(x3, tv3) // 24. x3 = x3^2 - x3 = e.Square(x3) + x3 = e.ext2.Square(x3) // 25. x3 = x3 * c4 - x3 = e.Mul(x3, &c4) + x3 = e.ext2.Mul(x3, &c4) // 26. x3 = x3 + Z - x3 = e.Add(x3, &Z) + x3 = e.ext2.Add(x3, &Z) // 27. x = CMOV(x3, x1, e1) # x = x1 if gx1 is square, else x = x3 - x = e.Select(e1, x1, x3) + x = e.ext2.Select(e1, x1, x3) // 28. x = CMOV(x, x2, e2) # x = x2 if gx2 is square and gx1 is not - x = e.Select(e2, x2, x) + x = e.ext2.Select(e2, x2, x) // 29. gx = x^2 - gx = e.Square(x) + gx = e.ext2.Square(x) // 30. gx = gx + A // !!! NOOP !!! // 31. gx = gx * x - gx = e.Mul(gx, x) + gx = e.ext2.Mul(gx, x) // 32. gx = gx + B - gx = e.Add(gx, &B) + gx = e.ext2.Add(gx, &B) // 33. y = sqrt(gx) y = sqrt(gx) // 34. e3 = sgn0(u) == sgn0(y) - e3 := api.IsZero(api.Xor(g2Sgn0Circuit(api, u), g2Sgn0Circuit(api, y))) + e3 := e.api.IsZero(e.api.Xor(e.g2Sgn0Circuit(u), e.g2Sgn0Circuit(y))) // 35. y = CMOV(-y, y, e3) # Select correct sign of y - y = e.Select(e3, y, e.Neg(y)) + y = e.ext2.Select(e3, y, e.ext2.Neg(y)) // 36. return (x, y) return &gadget.G2Affine{X: *x, Y: *y} } -func Neg(ba *fields_bn254.Ext2, p *gadget.G2Affine) *gadget.G2Affine { +func (e *EmulatedAPI) Neg(p *gadget.G2Affine) *gadget.G2Affine { return &gadget.G2Affine{ X: p.X, - Y: *ba.Neg(&p.Y), + Y: *e.ext2.Neg(&p.Y), } } -func Select(ba *fields_bn254.Ext2, b frontend.Variable, p, q *gadget.G2Affine) *gadget.G2Affine { - x := ba.Select(b, &p.X, &q.X) - y := ba.Select(b, &p.Y, &q.Y) +func (e *EmulatedAPI) Select(b frontend.Variable, p, q *gadget.G2Affine) *gadget.G2Affine { + x := e.ext2.Select(b, &p.X, &q.X) + y := e.ext2.Select(b, &p.Y, &q.Y) return &gadget.G2Affine{ X: *x, Y: *y, } } +func (e *EmulatedAPI) Add(p, q *gadget.G2Affine) *gadget.G2Affine { + // compute λ = (q.y-p.y)/(q.x-p.x) + qypy := e.ext2.Sub(&q.Y, &p.Y) + qxpx := e.ext2.Sub(&q.X, &p.X) + λ := e.ext2.DivUnchecked(qypy, qxpx) + + // xr = λ²-p.x-q.x + λλ := e.ext2.Square(λ) + qxpx = e.ext2.Add(&p.X, &q.X) + xr := e.ext2.Sub(λλ, qxpx) + + // p.y = λ(p.x-r.x) - p.y + pxrx := e.ext2.Sub(&p.X, xr) + λpxrx := e.ext2.Mul(λ, pxrx) + yr := e.ext2.Sub(λpxrx, &p.Y) + + return &gadget.G2Affine{ + X: *xr, + Y: *yr, + } +} + // AddUnified adds p and q and returns it. It doesn't modify p nor q. // // ✅ p can be equal to q, and either or both can be (0,0). @@ -302,49 +339,51 @@ func Select(ba *fields_bn254.Ext2, b frontend.Variable, p, q *gadget.G2Affine) * // // [BriJoy02]: https://link.springer.com/content/pdf/10.1007/3-540-45664-3_24.pdf // [EVM]: https://ethereum.github.io/yellowpaper/paper.pdf -func AddUnified(api frontend.API, ba *fields_bn254.Ext2, p, q *gadget.G2Affine) *gadget.G2Affine { +func (e *EmulatedAPI) AddUnified(p, q *gadget.G2Affine) *gadget.G2Affine { // selector1 = 1 when p is (0,0) and 0 otherwise - selector1 := api.And(ba.IsZero(&p.X), ba.IsZero(&p.Y)) + selector1 := e.api.And(e.ext2.IsZero(&p.X), e.ext2.IsZero(&p.Y)) // selector2 = 1 when q is (0,0) and 0 otherwise - selector2 := api.And(ba.IsZero(&q.X), ba.IsZero(&q.Y)) + selector2 := e.api.And(e.ext2.IsZero(&q.X), e.ext2.IsZero(&q.Y)) // λ = ((p.x+q.x)² - p.x*q.x + a)/(p.y + q.y) - pxqx := ba.Mul(&p.X, &q.X) - pxplusqx := ba.Add(&p.X, &q.X) - num := ba.Mul(pxplusqx, pxplusqx) - num = ba.Sub(num, pxqx) + pxqx := e.ext2.Mul(&p.X, &q.X) + pxplusqx := e.ext2.Add(&p.X, &q.X) + num := e.ext2.Mul(pxplusqx, pxplusqx) + num = e.ext2.Sub(num, pxqx) + // BN254 specialization // if c.addA { - // num = ba.Add(num, &c.a) + // num = e.ext2.Add(num, &c.a) // } - denum := ba.Add(&p.Y, &q.Y) + + denum := e.ext2.Add(&p.Y, &q.Y) // if p.y + q.y = 0, assign dummy 1 to denum and continue - selector3 := ba.IsZero(denum) - denum = ba.Select(selector3, ba.One(), denum) - λ := ba.DivUnchecked(num, denum) + selector3 := e.ext2.IsZero(denum) + denum = e.ext2.Select(selector3, e.ext2.One(), denum) + λ := e.ext2.DivUnchecked(num, denum) // x = λ^2 - p.x - q.x - xr := ba.Mul(λ, λ) - xr = ba.Sub(xr, pxplusqx) + xr := e.ext2.Mul(λ, λ) + xr = e.ext2.Sub(xr, pxplusqx) // y = λ(p.x - xr) - p.y - yr := ba.Sub(&p.X, xr) - yr = ba.Mul(yr, λ) - yr = ba.Sub(yr, &p.Y) + yr := e.ext2.Sub(&p.X, xr) + yr = e.ext2.Mul(yr, λ) + yr = e.ext2.Sub(yr, &p.Y) result := gadget.G2Affine{ X: *xr, Y: *yr, } - zero := ba.Zero() + zero := e.ext2.Zero() infinity := gadget.G2Affine{X: *zero, Y: *zero} // if p=(0,0) - result = *Select(ba, selector1, q, &result) + result = *e.Select(selector1, q, &result) // if q=(0,0) return p - result = *Select(ba, selector2, p, &result) + result = *e.Select(selector2, p, &result) // if p.y + q.y = 0, return (0, 0) - result = *Select(ba, selector3, &infinity, &result) + result = *e.Select(selector3, &infinity, &result) return &result } @@ -358,35 +397,35 @@ func AddUnified(api frontend.API, ba *fields_bn254.Ext2, p, q *gadget.G2Affine) // instead. It doesn't modify p nor q. // // [ELM03]: https://arxiv.org/pdf/math/0208038.pdf -func DoubleAndAdd(ba *fields_bn254.Ext2, p, q *gadget.G2Affine) *gadget.G2Affine { +func (e *EmulatedAPI) DoubleAndAdd(p, q *gadget.G2Affine) *gadget.G2Affine { // compute λ1 = (q.y-p.y)/(q.x-p.x) - yqyp := ba.Sub(&q.Y, &p.Y) - xqxp := ba.Sub(&q.X, &p.X) - λ1 := ba.DivUnchecked(yqyp, xqxp) + yqyp := e.ext2.Sub(&q.Y, &p.Y) + xqxp := e.ext2.Sub(&q.X, &p.X) + λ1 := e.ext2.DivUnchecked(yqyp, xqxp) // compute x2 = λ1²-p.x-q.x - λ1λ1 := ba.Square(λ1) - xqxp = ba.Add(&p.X, &q.X) - x2 := ba.Sub(λ1λ1, xqxp) + λ1λ1 := e.ext2.Square(λ1) + xqxp = e.ext2.Add(&p.X, &q.X) + x2 := e.ext2.Sub(λ1λ1, xqxp) // omit y2 computation // compute λ2 = -λ1-2*p.y/(x2-p.x) - ypyp := ba.Double(&p.Y) - x2xp := ba.Sub(x2, &p.X) - λ2 := ba.DivUnchecked(ypyp, x2xp) - λ2 = ba.Add(λ1, λ2) - λ2 = ba.Neg(λ2) + ypyp := e.ext2.Double(&p.Y) + x2xp := e.ext2.Sub(x2, &p.X) + λ2 := e.ext2.DivUnchecked(ypyp, x2xp) + λ2 = e.ext2.Add(λ1, λ2) + λ2 = e.ext2.Neg(λ2) // compute x3 =λ2²-p.x-x3 - λ2λ2 := ba.Square(λ2) - x3 := ba.Sub(λ2λ2, &p.X) - x3 = ba.Sub(x3, x2) + λ2λ2 := e.ext2.Square(λ2) + x3 := e.ext2.Sub(λ2λ2, &p.X) + x3 = e.ext2.Sub(x3, x2) // compute y3 = λ2*(p.x - x3)-p.y - y3 := ba.Sub(&p.X, x3) - y3 = ba.Mul(λ2, y3) - y3 = ba.Sub(y3, &p.Y) + y3 := e.ext2.Sub(&p.X, x3) + y3 = e.ext2.Mul(λ2, y3) + y3 = e.ext2.Sub(y3, &p.Y) return &gadget.G2Affine{ X: *x3, @@ -397,22 +436,22 @@ func DoubleAndAdd(ba *fields_bn254.Ext2, p, q *gadget.G2Affine) *gadget.G2Affine // Double doubles p and return it. It doesn't modify p. // It uses affine coordinates. -func Double(ba *fields_bn254.Ext2, p *gadget.G2Affine) *gadget.G2Affine { +func (e *EmulatedAPI) Double(p *gadget.G2Affine) *gadget.G2Affine { // compute λ = (3p.x²+a)/2*p.y, here we assume a=0 (j invariant 0 curve) - xx3a := ba.Square(&p.X) - xx3a = ba.MulByConstElement(xx3a, big.NewInt(3)) - y2 := ba.MulByConstElement(&p.Y, big.NewInt(2)) - λ := ba.DivUnchecked(xx3a, y2) + xx3a := e.ext2.Square(&p.X) + xx3a = e.ext2.MulByConstElement(xx3a, big.NewInt(3)) + y2 := e.ext2.MulByConstElement(&p.Y, big.NewInt(2)) + λ := e.ext2.DivUnchecked(xx3a, y2) // xr = λ²-2p.x - x2 := ba.MulByConstElement(&p.X, big.NewInt(2)) - λλ := ba.Square(λ) - xr := ba.Sub(λλ, x2) + x2 := e.ext2.MulByConstElement(&p.X, big.NewInt(2)) + λλ := e.ext2.Square(λ) + xr := e.ext2.Sub(λλ, x2) // yr = λ(p-xr) - p.y - pxrx := ba.Sub(&p.X, xr) - λpxrx := ba.Mul(λ, pxrx) - yr := ba.Sub(λpxrx, &p.Y) + pxrx := e.ext2.Sub(&p.X, xr) + λpxrx := e.ext2.Mul(λ, pxrx) + yr := e.ext2.Sub(λpxrx, &p.Y) return &gadget.G2Affine{ X: *xr, @@ -420,34 +459,34 @@ func Double(ba *fields_bn254.Ext2, p *gadget.G2Affine) *gadget.G2Affine { } } -func Triple(ba *fields_bn254.Ext2, p *gadget.G2Affine) *gadget.G2Affine { +func (e *EmulatedAPI) Triple(p *gadget.G2Affine) *gadget.G2Affine { // compute λ1 = (3p.x²+a)/2p.y, here we assume a=0 (j invariant 0 curve) - xx := ba.Square(&p.X) - xx = ba.MulByConstElement(xx, big.NewInt(3)) - y2 := ba.Double(&p.Y) - λ1 := ba.DivUnchecked(xx, y2) + xx := e.ext2.Square(&p.X) + xx = e.ext2.MulByConstElement(xx, big.NewInt(3)) + y2 := e.ext2.Double(&p.Y) + λ1 := e.ext2.DivUnchecked(xx, y2) // xr = λ1²-2p.x - x2 := ba.Double(&p.X) - λ1λ1 := ba.Mul(λ1, λ1) - x2 = ba.Sub(λ1λ1, x2) + x2 := e.ext2.Double(&p.X) + λ1λ1 := e.ext2.Mul(λ1, λ1) + x2 = e.ext2.Sub(λ1λ1, x2) // omit y2 computation, and // compute λ2 = 2p.y/(x2 − p.x) − λ1. - x1x2 := ba.Sub(&p.X, x2) - λ2 := ba.DivUnchecked(y2, x1x2) - λ2 = ba.Sub(λ2, λ1) + x1x2 := e.ext2.Sub(&p.X, x2) + λ2 := e.ext2.DivUnchecked(y2, x1x2) + λ2 = e.ext2.Sub(λ2, λ1) // xr = λ²-p.x-x2 - λ2λ2 := ba.Mul(λ2, λ2) - qxrx := ba.Add(x2, &p.X) - xr := ba.Sub(λ2λ2, qxrx) + λ2λ2 := e.ext2.Mul(λ2, λ2) + qxrx := e.ext2.Add(x2, &p.X) + xr := e.ext2.Sub(λ2λ2, qxrx) // yr = λ(p.x-xr) - p.y - pxrx := ba.Sub(&p.X, xr) - λ2pxrx := ba.Mul(λ2, pxrx) - yr := ba.Sub(λ2pxrx, &p.Y) + pxrx := e.ext2.Sub(&p.X, xr) + λ2pxrx := e.ext2.Mul(λ2, pxrx) + yr := e.ext2.Sub(λ2pxrx, &p.Y) return &gadget.G2Affine{ X: *xr, @@ -455,65 +494,68 @@ func Triple(ba *fields_bn254.Ext2, p *gadget.G2Affine) *gadget.G2Affine { } } -func ScalarMul(api frontend.API, sa *emulated.Field[emulated.BN254Fr], ba *fields_bn254.Ext2, p *gadget.G2Affine, s *emulated.Element[emulated.BN254Fr]) *gadget.G2Affine { - var st emulated.BN254Fr - sr := sa.Reduce(s) - sBits := sa.ToBits(sr) - n := st.Modulus().BitLen() - - // i = 1 - tmp := Triple(ba, p) - res := Select(ba, sBits[1], tmp, p) - acc := AddUnified(api, ba, tmp, p) - - for i := 2; i <= n-3; i++ { - tmp := AddUnified(api, ba, res, acc) - res = Select(ba, sBits[i], tmp, res) - acc = Double(ba, acc) +func (e *EmulatedAPI) DoubleN(p *gadget.G2Affine, n int) *gadget.G2Affine { + pn := p + for s := 0; s < n; s++ { + pn = e.Double(pn) } - - // i = n-2 - tmp = AddUnified(api, ba, res, acc) - res = Select(ba, sBits[n-2], tmp, res) - - // i = n-1 - tmp = DoubleAndAdd(ba, acc, res) - res = Select(ba, sBits[n-1], tmp, res) - - // i = 0 - tmp = AddUnified(api, ba, res, Neg(ba, p)) - res = Select(ba, sBits[0], res, tmp) - - return res + return pn } -func ClearCofactor(api frontend.API, p *gadget.G2Affine) *gadget.G2Affine { - ba := fields_bn254.NewExt2(api) - sa, err := emulated.NewField[emulated.BN254Fr](api) - if err != nil { - panic(err) +func (e *EmulatedAPI) Psi(q *gadget.G2Affine) *gadget.G2Affine { + x := e.ext2.Conjugate(&q.X) + x = e.ext2.Mul(x, e.u) + y := e.ext2.Conjugate(&q.Y) + y = e.ext2.Mul(y, e.v) + return &gadget.G2Affine{ + X: *x, + Y: *y, } - // BN254 G2 Cofactor, too big to fit in a single element - bigH, _ := new(big.Int).SetString("30644e72e131a029b85045b68181585e06ceecda572a2489345f2299c0f9fa8d", 16) - leftH := new(big.Int).Div(bigH, big.NewInt(2)) - rightH := new(big.Int).Sub(bigH, leftH) - - lh := emulated.ValueOf[emulated.BN254Fr](leftH) - rh := emulated.ValueOf[emulated.BN254Fr](rightH) - - // Please find a way to optimize - l := ScalarMul(api, sa, ba, p, &lh) - r := ScalarMul(api, sa, ba, p, &rh) - return AddUnified(api, ba, l, r) +} +func (e *EmulatedAPI) ScalarMulBySeed(q *gadget.G2Affine) *gadget.G2Affine { + z := e.Double(q) + t0 := e.Add(q, z) + t2 := e.Add(q, t0) + t1 := e.Add(z, t2) + z = e.DoubleAndAdd(t1, t0) + t0 = e.Add(t0, z) + t2 = e.Add(t2, t0) + t1 = e.Add(t1, t2) + t0 = e.Add(t0, t1) + t1 = e.Add(t1, t0) + t0 = e.Add(t0, t1) + t2 = e.Add(t2, t0) + t1 = e.DoubleAndAdd(t2, t1) + t2 = e.Add(t2, t1) + z = e.Add(z, t2) + t2 = e.Add(t2, z) + z = e.DoubleAndAdd(t2, z) + t0 = e.Add(t0, z) + t1 = e.Add(t1, t0) + t3 := e.Double(t1) + t3 = e.DoubleAndAdd(t3, t1) + t2 = e.Add(t2, t3) + t1 = e.Add(t1, t2) + t2 = e.Add(t2, t1) + t2 = e.DoubleN(t2, 16) + t1 = e.DoubleAndAdd(t2, t1) + t1 = e.DoubleN(t1, 13) + t0 = e.DoubleAndAdd(t1, t0) + t0 = e.DoubleN(t0, 15) + z = e.DoubleAndAdd(t0, z) + + return z } -// AssertIsEqual asserts that p and q are the same point. -func AssertIsEqual(ba *fields_bn254.Ext2, p, q *gadget.G2Affine) { - ba.AssertIsEqual(&p.X, &q.X) - ba.AssertIsEqual(&p.Y, &q.Y) +func (e *EmulatedAPI) ClearCofactor(p *gadget.G2Affine) *gadget.G2Affine { + p0 := e.ScalarMulBySeed(p) + p1 := e.Psi(e.Add(e.Double(p0), p0)) + p2 := e.Psi(e.Psi(p0)) + p3 := e.Psi(e.Psi(e.Psi(p))) + return e.Add(e.Add(e.Add(p0, p1), p2), p3) } -func MapToG2(api frontend.API, u *fields_bn254.E2) *gadget.G2Affine { - return ClearCofactor(api, MapToCurve(api, u)) +func (e *EmulatedAPI) HashToG2(u *fields_bn254.E2) *gadget.G2Affine { + return e.ClearCofactor(e.MapToCurve(u)) } diff --git a/galoisd/pkg/emulated/g2_test.go b/galoisd/pkg/emulated/g2_test.go new file mode 100644 index 0000000000..45e5e0adca --- /dev/null +++ b/galoisd/pkg/emulated/g2_test.go @@ -0,0 +1,133 @@ +package g2 + +import ( + "crypto/rand" + cometbft_bn254 "github.com/cometbft/cometbft/crypto/bn254" + "github.com/consensys/gnark-crypto/ecc" + curve "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/consensys/gnark/backend" + "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/std/algebra/emulated/fields_bn254" + gadget "github.com/consensys/gnark/std/algebra/emulated/sw_bn254" + "github.com/consensys/gnark/test" + "github.com/stretchr/testify/assert" + "math/big" + "testing" +) + +type Add struct { + X gadget.G2Affine + Y gadget.G2Affine + Z gadget.G2Affine +} + +func (c *Add) Define(api frontend.API) error { + emulated, err := NewEmulatedAPI(api) + if err != nil { + return err + } + emulated.AssertIsEqual(&c.Z, emulated.AddUnified(&c.X, &c.Y)) + return nil +} + +func FuzzAdd(f *testing.F) { + f.Fuzz(func(t *testing.T, in []byte) { + t.Parallel() + x, err := curve.HashToG2(in, []byte{0x01}) + assert.NoError(t, err) + y, err := curve.HashToG2(in, []byte{0x02}) + assert.NoError(t, err) + var z curve.G2Affine + z.Add(&x, &y) + var circuit Add + assignment := Add{ + X: gadget.NewG2Affine(x), + Y: gadget.NewG2Affine(y), + Z: gadget.NewG2Affine(z), + } + test.NewAssert(t).ProverSucceeded( + &circuit, + &assignment, + test.WithCurves(ecc.BN254), + test.NoFuzzing(), + test.WithCurves(ecc.BN254), + test.WithBackends(backend.GROTH16), + ) + }) +} + +type MapToCurve struct { + Preimage fields_bn254.E2 + Image gadget.G2Affine +} + +func (c *MapToCurve) Define(api frontend.API) error { + emulated, err := NewEmulatedAPI(api) + if err != nil { + return err + } + emulated.AssertIsEqual(&c.Image, emulated.MapToCurve(&c.Preimage)) + return nil +} + +func FuzzMapToCurve(f *testing.F) { + f.Fuzz(func(t *testing.T, message []byte) { + t.Parallel() + messageX, messageY := cometbft_bn254.HashToField2(message) + var messagePoint curve.E2 + messagePoint.A0.SetBigInt(messageX.BigInt(new(big.Int))) + messagePoint.A1.SetBigInt(messageY.BigInt(new(big.Int))) + mapped := curve.MapToCurve2(&messagePoint) + var circuit MapToCurve + assignment := MapToCurve{ + Preimage: fields_bn254.FromE2(&messagePoint), + Image: gadget.NewG2Affine(mapped), + } + test.NewAssert(t).ProverSucceeded( + &circuit, + &assignment, + test.WithCurves(ecc.BN254), + test.NoFuzzing(), + test.WithCurves(ecc.BN254), + test.WithBackends(backend.GROTH16), + ) + }) +} + +type HashToG2 struct { + Preimage fields_bn254.E2 + Image gadget.G2Affine +} + +func (c *HashToG2) Define(api frontend.API) error { + emulated, err := NewEmulatedAPI(api) + if err != nil { + return err + } + emulated.AssertIsEqual(&c.Image, emulated.HashToG2(&c.Preimage)) + return nil +} + +func TestHashToG2(t *testing.T) { + t.Parallel() + var message [32]byte + rand.Read(message[:]) + messageX, messageY := cometbft_bn254.HashToField2(message[:]) + var messagePoint curve.E2 + messagePoint.A0.SetBigInt(messageX.BigInt(new(big.Int))) + messagePoint.A1.SetBigInt(messageY.BigInt(new(big.Int))) + mapped := curve.MapToG2(messagePoint) + var circuit HashToG2 + assignment := HashToG2{ + Preimage: fields_bn254.FromE2(&messagePoint), + Image: gadget.NewG2Affine(mapped), + } + test.NewAssert(t).ProverSucceeded( + &circuit, + &assignment, + test.WithCurves(ecc.BN254), + test.NoFuzzing(), + test.WithCurves(ecc.BN254), + test.WithBackends(backend.GROTH16), + ) +} diff --git a/galoisd/pkg/lightclient/adjacent/circuit.go b/galoisd/pkg/lightclient/adjacent/circuit.go index b956eb71eb..cfbd4bf0b6 100644 --- a/galoisd/pkg/lightclient/adjacent/circuit.go +++ b/galoisd/pkg/lightclient/adjacent/circuit.go @@ -14,10 +14,14 @@ type Circuit struct { } func (circuit *Circuit) Define(api frontend.API) error { + emulatedAPI, err := g2.NewEmulatedAPI(api) + if err != nil { + return err + } var message fields_bn254.E2 message.A0.Limbs = lightclient.Unpack(api, circuit.Message[0], 256, 64) message.A1.Limbs = lightclient.Unpack(api, circuit.Message[1], 256, 64) - messagePoint := g2.MapToG2(api, &message) + messagePoint := emulatedAPI.HashToG2(&message) lc := lightclient.NewTendermintLightClientAPI(api, &circuit.Input) return lc.Verify(messagePoint, circuit.ExpectedValRoot, 2, 3) } diff --git a/galoisd/pkg/lightclient/nonadjacent/circuit.go b/galoisd/pkg/lightclient/nonadjacent/circuit.go index 8dfcc0054e..ea34c2931f 100644 --- a/galoisd/pkg/lightclient/nonadjacent/circuit.go +++ b/galoisd/pkg/lightclient/nonadjacent/circuit.go @@ -34,10 +34,14 @@ type Circuit struct { } func (circuit *Circuit) Define(api frontend.API) error { + emulatedAPI, err := g2.NewEmulatedAPI(api) + if err != nil { + return err + } var message fields_bn254.E2 message.A0.Limbs = lightclient.Unpack(api, circuit.Message[0], 256, 64) message.A1.Limbs = lightclient.Unpack(api, circuit.Message[1], 256, 64) - messagePoint := g2.MapToG2(api, &message) + messagePoint := emulatedAPI.HashToG2(&message) lc := lightclient.NewTendermintLightClientAPI(api, &lightclient.TendermintLightClientInput{ Sig: circuit.TrustedInput.Sig, Validators: circuit.TrustedInput.Validators, diff --git a/galoisd/pkg/lightclient/nonadjacent/circuit_test.go b/galoisd/pkg/lightclient/nonadjacent/circuit_test.go deleted file mode 100644 index 3c6b6e6b78..0000000000 --- a/galoisd/pkg/lightclient/nonadjacent/circuit_test.go +++ /dev/null @@ -1,227 +0,0 @@ -package nonadjacent - -import ( - "encoding/base64" - "galois/pkg/lightclient" - "log" - "math/big" - - cometbn254 "github.com/cometbft/cometbft/crypto/bn254" - "github.com/cometbft/cometbft/proto/tendermint/types" - "github.com/consensys/gnark/frontend" - sdk "github.com/cosmos/cosmos-sdk/types" - - cometbft_bn254 "github.com/cometbft/cometbft/crypto/bn254" - ce "github.com/cometbft/cometbft/crypto/encoding" - "github.com/cometbft/cometbft/crypto/merkle" - "github.com/cometbft/cometbft/libs/protoio" - "github.com/consensys/gnark-crypto/ecc" - curve "github.com/consensys/gnark-crypto/ecc/bn254" - back "github.com/consensys/gnark/backend" - - gadget "github.com/consensys/gnark/std/algebra/emulated/sw_bn254" - - "testing" - - "github.com/consensys/gnark/test" -) - -func TestRegression3(t *testing.T) { - decodeB64 := func(s string) []byte { - bz, err := base64.StdEncoding.DecodeString(s) - if err != nil { - log.Fatal(err) - } - return bz - } - - toValidator := func(pubKey []byte, tokens *big.Int) *types.SimpleValidator { - protoPK, err := ce.PubKeyToProto(cometbn254.PubKey(pubKey)) - if err != nil { - log.Fatal(err) - } - return &types.SimpleValidator{ - PubKey: &protoPK, - VotingPower: sdk.TokensToConsensusPower(sdk.NewIntFromBigInt(tokens), sdk.DefaultPowerReduction), - } - } - - blockHash := decodeB64("z0wraQ1vIYTfIcKanrafANKkdwHBli4K13PC+kF5l7w=") - - partSetHeaderHash := decodeB64("ouHUWDwUcLJah07NEaMSiov595XLyJiPgyVQVflQ+d4=") - - vote := types.CanonicalVote{ - Type: types.PrecommitType, - Height: 516458, - Round: 0, - BlockID: &types.CanonicalBlockID{ - Hash: blockHash, - PartSetHeader: types.CanonicalPartSetHeader{ - Total: 1, - Hash: partSetHeaderHash, - }, - }, - ChainID: "union-testnet-3", - } - - validators := []*types.SimpleValidator{ - toValidator(decodeB64("ncDNFj9SxNcXjtejrrDaN2TJ5AQJw4Hdbxu2/XJEdw4="), new(big.Int).SetUint64(1900000000000)), // cspell:disable-line - toValidator(decodeB64("rwamLUSY+Ax3JsVtdqEO+yLwV//n9OfE2TNf9BHZRLk="), new(big.Int).SetUint64(1221870086811)), // cspell:disable-line - toValidator(decodeB64("5lRQKoQ1z1wyCmyKFvhZnYxA54HnxdDWKnxksMw9K1Q="), new(big.Int).SetUint64(1200000000000)), // cspell:disable-line - toValidator(decodeB64("z0wjC1SIYJ1QeZSVpcKnU7qLCSbpWlPNikV5/4WroDw="), new(big.Int).SetUint64(1001001000000)), // cspell:disable-line - toValidator(decodeB64("5D/CuxUTxns90VZeANkLE9ZGdVChWb76xCGjikQW6Ig="), new(big.Int).SetUint64(1000000000000)), // cspell:disable-line - } - - trustedValidators := validators - untrustedValidators := validators - - signatures := [][]byte{ - decodeB64("xBhStL04DUCyQkHdnpghEk+V/16n0kOHdEQvoVWbo1cZp18vivnaiG0UvQVA0MJs3e3vNRcU0fqFQIDA6nfbEg=="), - decodeB64("3SRDK+hVb7R0fqdRgXaITEApcujA1e/saiXgcocadvcStCZjudZr4i8arIJ5Um7zVNw79qz6yedPWFMAr/EPbg=="), - decodeB64("rzFtlxtF8/+ElW1kyCxnpNOzbh/I17WRNby+ksNssqsoonVPynolYoCrfWYWqI6/si45AnlR/j0SyFZoZuFJcQ=="), - decodeB64("hbKdcJt9znP03LtTdkG8yq4cCbCtxLkH3CmbDzySNbwAvvDDDc+1tuVVIZPE8oUS3DJDZXhqyWcyf4PLzGX1Iw=="), - decodeB64("2ducQq7TuxbBjNArdVpvNfYnzpYQFHKwkPBR26K9HDssoPzvyq49q2n16rx/3BkOW3uwE7qexbRGQx8Pqdv7Fw=="), - } - - trustedSignatures := signatures - untrustedSignatures := signatures - - var bitmap big.Int - bitmap.SetBit(&bitmap, 0, 1) - bitmap.SetBit(&bitmap, 1, 1) - bitmap.SetBit(&bitmap, 2, 1) - bitmap.SetBit(&bitmap, 3, 1) - bitmap.SetBit(&bitmap, 4, 1) - - t.Log("Bitmap: ", bitmap) - - trustedBitmap := bitmap - untrustedBitmap := bitmap - - reverseBytes := func(numbers []byte) []byte { - newNumbers := make([]byte, 0, len(numbers)) - for i := len(numbers) - 1; i >= 0; i-- { - newNumbers = append(newNumbers, numbers[i]) - } - return newNumbers - } - - marshalValidators := func(validators []*types.SimpleValidator) ([lightclient.MaxVal][4]frontend.Variable, []byte, error) { - validatorsProto := [lightclient.MaxVal][4]frontend.Variable{} - // Make sure we zero initialize - for i := 0; i < lightclient.MaxVal; i++ { - validatorsProto[i][0] = 0 - validatorsProto[i][1] = 0 - validatorsProto[i][2] = 0 - validatorsProto[i][3] = 0 - } - merkleTree := make([][]byte, len(validators)) - for i, val := range validators { - protoEncoding, err := val.Marshal() - if err != nil { - return validatorsProto, nil, err - } - - merkleTree[i] = protoEncoding - - tmPK, err := ce.PubKeyFromProto(*val.PubKey) - if err != nil { - return validatorsProto, nil, err - } - - compressedPK := tmPK.Bytes() - - var PK curve.G1Affine - _, err = PK.SetBytes(compressedPK) - if err != nil { - return validatorsProto, nil, err - } - - PKX := PK.X.Bytes() - PKY := PK.Y.Bytes() - // Need to reverse to simplify circuit computation - power := reverseBytes(protoEncoding[lightclient.ValProtoPower:]) - mask := compressedPK[0] >> 6 - validatorsProto[i][0] = PKX[:] - validatorsProto[i][1] = PKY[:] - validatorsProto[i][2] = power - validatorsProto[i][3] = mask - } - log.Print(len(merkleTree)) - return validatorsProto, merkle.HashFromByteSlices(merkleTree), nil - } - - aggregateSignatures := func(signatures [][]byte) (curve.G2Affine, error) { - var aggregatedSignature curve.G2Affine - var decompressedSignature curve.G2Affine - for _, signature := range signatures { - _, err := decompressedSignature.SetBytes(signature) - if err != nil { - return curve.G2Affine{}, err - } - aggregatedSignature.Add(&aggregatedSignature, &decompressedSignature) - } - return aggregatedSignature, nil - } - - trustedValidatorsProto, trustedValidatorsRoot, err := marshalValidators(trustedValidators) - if err != nil { - log.Fatal(err) - } - trustedAggregatedSignature, err := aggregateSignatures(trustedSignatures) - if err != nil { - log.Fatal(err) - } - - untrustedValidatorsProto, untrustedValidatorsRoot, err := marshalValidators(untrustedValidators) - if err != nil { - log.Fatal(err) - } - untrustedAggregatedSignature, err := aggregateSignatures(untrustedSignatures) - if err != nil { - log.Fatal(err) - } - - trustedInput := TendermintNonAdjacentLightClientInput{ - Sig: gadget.NewG2Affine(trustedAggregatedSignature), - ProtoValidators: trustedValidatorsProto, - NbOfVal: len(trustedValidators), - NbOfSignature: len(trustedSignatures), - Bitmap: trustedBitmap, - } - - untrustedInput := TendermintNonAdjacentLightClientInput{ - Sig: gadget.NewG2Affine(untrustedAggregatedSignature), - ProtoValidators: untrustedValidatorsProto, - NbOfVal: len(untrustedValidators), - NbOfSignature: len(untrustedSignatures), - Bitmap: untrustedBitmap, - } - - signedBytes, err := protoio.MarshalDelimited(&vote) - if err != nil { - log.Fatal(err) - } - - hmX, hmY := cometbft_bn254.HashToField2(signedBytes) - - witness := Circuit{ - TrustedInput: trustedInput, - UntrustedInput: untrustedInput, - ExpectedTrustedValRoot: [2]frontend.Variable{ - trustedValidatorsRoot[0:16], - trustedValidatorsRoot[16:32], - }, - ExpectedUntrustedValRoot: [2]frontend.Variable{ - untrustedValidatorsRoot[0:16], - untrustedValidatorsRoot[16:32], - }, - Message: [2]frontend.Variable{hmX, hmY}, - } - - assert := test.NewAssert(t) - - var circuit Circuit - - assert.ProverSucceeded(&circuit, &witness, test.WithCurves(ecc.BN254), test.WithBackends(back.GROTH16), test.NoSerialization(), test.NoFuzzing()) -} diff --git a/galoisd/pkg/proto/api_test.go b/galoisd/pkg/proto/api_test.go index 066645ff04..b5062970bd 100644 --- a/galoisd/pkg/proto/api_test.go +++ b/galoisd/pkg/proto/api_test.go @@ -1,9 +1,9 @@ package proto import ( + "crypto/rand" "fmt" "math/big" - "math/rand" "testing" "github.com/consensys/gnark-crypto/ecc" diff --git a/galoisd/vendor/github.com/cometbft/cometbft/crypto/bn254/bn254.go b/galoisd/vendor/github.com/cometbft/cometbft/crypto/bn254/bn254.go index f50e135d5d..1f641e7efe 100644 --- a/galoisd/vendor/github.com/cometbft/cometbft/crypto/bn254/bn254.go +++ b/galoisd/vendor/github.com/cometbft/cometbft/crypto/bn254/bn254.go @@ -100,7 +100,7 @@ var _ crypto.PubKey = PubKey{} type PubKey []byte -func(pubKey PubKey) EnsureValid() error { +func (pubKey PubKey) EnsureValid() error { var public bn254.G1Affine _, err := public.SetBytes(pubKey) if err != nil { @@ -224,17 +224,11 @@ func HashToField2(msg []byte) (fr.Element, fr.Element) { // TODO: link union whitepaper 4.1.1, M func HashToG2(msg []byte) bn254.G2Affine { x, y := HashToField2(msg) - point := nativeNaiveScalarMul(bn254.MapToCurve2(&bn254.E2{ + point := bn254.MapToG2(bn254.E2{ A0: *new(fp.Element).SetBigInt(x.BigInt(new(big.Int))), A1: *new(fp.Element).SetBigInt(y.BigInt(new(big.Int))), - }), &G2Cofactor) - // Any of the following case are impossible and should break consensus - if !point.IsOnCurve() { - panic("Point is not on the curve") - } - if !point.IsInSubGroup() { - panic("Point is not in subgroup") - } + }) + // Must not be zero if point.IsInfinity() { panic("Point is zero") } @@ -283,29 +277,29 @@ func (l MerkleLeaf) Hash() ([]byte, error) { frYBytes := l.ShiftedY.Bytes() mimc := mimc.NewMiMC() _, err := mimc.Write(frXBytes[:]) - if(err != nil) { + if err != nil { return nil, err } _, err = mimc.Write(frYBytes[:]) - if(err != nil) { + if err != nil { return nil, err } var padded [32]byte big.NewInt(int64(l.MsbX)).FillBytes(padded[:]) _, err = mimc.Write(padded[:]) - if(err != nil) { + if err != nil { return nil, err } big.NewInt(int64(l.MsbY)).FillBytes(padded[:]) _, err = mimc.Write(padded[:]) - if(err != nil) { + if err != nil { return nil, err } var powerBytes big.Int powerBytes.SetUint64(uint64(l.VotingPower)) powerBytes.FillBytes(padded[:]) _, err = mimc.Write(padded[:]) - if(err != nil) { + if err != nil { return nil, err } return mimc.Sum(nil), nil diff --git a/galoisd/vendor/modules.txt b/galoisd/vendor/modules.txt index 446ef8249a..48c896c26c 100644 --- a/galoisd/vendor/modules.txt +++ b/galoisd/vendor/modules.txt @@ -155,7 +155,7 @@ github.com/cockroachdb/redact/internal/rfmt/fmtsort # github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 ## explicit; go 1.19 github.com/cockroachdb/tokenbucket -# github.com/cometbft/cometbft v0.38.2 => github.com/unionlabs/cometbls v0.0.0-20240108104619-5ed53d0e59b9 +# github.com/cometbft/cometbft v0.38.2 => github.com/unionlabs/cometbls v0.0.0-20240111183309-e159e964fa07 ## explicit; go 1.21 github.com/cometbft/cometbft/abci/types github.com/cometbft/cometbft/config @@ -265,19 +265,14 @@ github.com/consensys/gnark/profile github.com/consensys/gnark/profile/internal/graph github.com/consensys/gnark/profile/internal/measurement github.com/consensys/gnark/profile/internal/report -github.com/consensys/gnark/std/accumulator/merkle github.com/consensys/gnark/std/algebra/emulated/fields_bn254 github.com/consensys/gnark/std/algebra/emulated/sw_bn254 github.com/consensys/gnark/std/algebra/emulated/sw_emulated -github.com/consensys/gnark/std/hash github.com/consensys/gnark/std/hash/mimc github.com/consensys/gnark/std/internal/logderivarg -github.com/consensys/gnark/std/internal/logderivprecomp github.com/consensys/gnark/std/math/bits -github.com/consensys/gnark/std/math/bitslice github.com/consensys/gnark/std/math/emulated github.com/consensys/gnark/std/math/emulated/emparams -github.com/consensys/gnark/std/math/uints github.com/consensys/gnark/std/multicommit github.com/consensys/gnark/std/rangecheck github.com/consensys/gnark/std/utils/algo_utils @@ -413,7 +408,7 @@ github.com/cosmos/cosmos-db github.com/cosmos/cosmos-proto github.com/cosmos/cosmos-proto/anyutil github.com/cosmos/cosmos-proto/runtime -# github.com/cosmos/cosmos-sdk v0.50.2 => github.com/unionlabs/cosmos-sdk v0.0.0-20240108104904-d7de88f54965 +# github.com/cosmos/cosmos-sdk v0.50.2 => github.com/unionlabs/cosmos-sdk v0.0.0-20240111183419-b58f90f260ce ## explicit; go 1.21 github.com/cosmos/cosmos-sdk/codec github.com/cosmos/cosmos-sdk/codec/types @@ -855,8 +850,8 @@ rsc.io/tmplfunc/internal/parse # sigs.k8s.io/yaml v1.3.0 ## explicit; go 1.12 sigs.k8s.io/yaml -# github.com/cometbft/cometbft => github.com/unionlabs/cometbls v0.0.0-20240108104619-5ed53d0e59b9 +# github.com/cometbft/cometbft => github.com/unionlabs/cometbls v0.0.0-20240111183309-e159e964fa07 # github.com/consensys/gnark => github.com/consensys/gnark v0.9.1-0.20231013131835-4ebcccd9c0a8 # github.com/consensys/gnark-crypto => github.com/unionlabs/gnark-crypto v0.0.0-20231016072529-15c0507b6578 -# github.com/cosmos/cosmos-sdk => github.com/unionlabs/cosmos-sdk v0.0.0-20240108104904-d7de88f54965 +# github.com/cosmos/cosmos-sdk => github.com/unionlabs/cosmos-sdk v0.0.0-20240111183419-b58f90f260ce # github.com/cosmos/gogoproto => github.com/cosmos/gogoproto v1.4.11 diff --git a/lib/cometbls-groth16-verifier/src/lib.rs b/lib/cometbls-groth16-verifier/src/lib.rs index c4da77c4de..c91b66b7e0 100644 --- a/lib/cometbls-groth16-verifier/src/lib.rs +++ b/lib/cometbls-groth16-verifier/src/lib.rs @@ -44,86 +44,92 @@ fn make_g2(x0: BigInt<4>, x1: BigInt<4>, y0: BigInt<4>, y1: BigInt<4>) -> ark_bn pub fn universal_vk() -> VerifyingKey { VerifyingKey:: { alpha_g1: make_g1( - BigInt!("4545497642472568342690310908405747139240036052727362141781732401147427278332"), BigInt!( - "21657279939237288836606942458710668831714385968774740438494149333436465843139" + "19681918582342826141927615585844819827950494091197079841581098590160509489088" + ), + BigInt!( + "18976290249472753264792873488771466812990993964894861063003977176791880491271" ), ), beta_g2: make_g2( BigInt!( - "13700154589878825236434612482502516805936642904411498786936854624077294311682" + "17542740552152507448113209307107151415915067720344615090625491194497459342657" ), - BigInt!("7497643146587701237207141457042187540104153076302400103164161194096334760677"), - BigInt!("9826602037751518929179716999401231701426363230642489106652396292955775994691"), - BigInt!("494959300439117228384867537570789342664813284882712364066022590927983142487"), + BigInt!("7391419840357209888406550113304609596117324320456425532340186750677647200951"), + BigInt!("2096098177649336914352130549614133988628743230280002744893263955761858843171"), + BigInt!("4677079465946489457182021046711835395185270130772240179395185648392131208623"), ), gamma_g2: make_g2( BigInt!( - "20107534645331006032402749367045367765170696291609897560802407293332329737698" + "18606218405301761142065379515313210013062685838824185304765852768028043703753" + ), + BigInt!( + "14540190418613230568675456016157166803361906410442369269514923787931816842661" ), - BigInt!("6135886662735635672007238208825068442340242201492563368708252608220727995665"), - BigInt!("584217449480441780710130852604895480474315394916633289664060053699306106397"), BigInt!( - "17134974117749564453678476337428610454531306634132123613923694771472873051567" + "12936954089909944910505634392074782488818125866327899713345517976848668940364" + ), + BigInt!( + "13075501156799383604449750948266619544543946431193320977624603555722073460251" ), ), delta_g2: make_g2( - BigInt!("7466991077765871589299219136524534381311757366195842209075383099119159267653"), - BigInt!("3993057849766236546786517975621342624904647686274232418256214891442175004595"), + BigInt!("4060446808760699692477462845230990229944734548192291022910719993807902355759"), BigInt!( - "17059631376675436953753993725010634849620319904450639403903900154330555520271" + "17803970575871171031178686612122420011629668206026599803865929512658387807614" ), + BigInt!("4763598941158436116656275326473539450011503349766865816034780567774742318513"), BigInt!( - "13975627069505281795607371372114671724714107626672690650658467595074779383085" + "14258428007760852895551143871140524567103085048652562171285997361131304666100" ), ), gamma_abc_g1: vec![ make_g1( BigInt!( - "12730996440491230341898748596203954698739716661771354666644872057102948394726" + "18676861125246766292059080199576268981667767278300819763274799276376054409743" ), BigInt!( - "18188119481706424113895919492547204030227563509791341513627568384483237465563" + "5269797328666185490526867808814966151140271775451395274640052553630677159076" ), ), make_g1( BigInt!( - "8627654005047498327557788753897980447566216968617518507065934795873759856303" + "3010349418202885908760025883515590778403141726894708222433169071368055690912" ), BigInt!( - "7258461021217822820323520100501249447378191264854934186351306877513723742793" + "20724571387755619214201948546999886629454427058875835531981815961969686023639" ), ), make_g1( BigInt!( - "10867392565326439682947570558412590838055450106691458097719409041212951853401" + "1718980496599153571806495443921791801530740535933073284474040850386158191735" ), BigInt!( - "3124325152732842906431467328196929469314595151752342394843391644384931489602" + "3288376032837046783397899352143814445169932711782482341330476711768756263890" ), ), make_g1( BigInt!( - "6627862564104432829412837659942319893523740327889349003623985834967392523238" + "9266521894078168597926726825960443668976816125222306871429246198851182099011" ), BigInt!( - "11980409132042083280769458186828234442115366931894286356450034429211995205398" + "9416966066664703605394453818829209487654794520205974695819389893969431707374" ), ), make_g1( BigInt!( - "8352580944529539453233628007042528490297057973561012318225452772905637057834" + "13194582768609510874189454527180276310818912484460263820189470814556014162264" ), BigInt!( - "16521805616951802411915576898364661283847250025318378340431083135006258712933" + "15983647339013447433771242507224193645257463334651420839328305715367829062538" ), ), make_g1( BigInt!( - "12071952363228031783312741175393664539881674330807724365734090335572247236031" + "13160686484300787492313686811371534896624215839999346591796239441200125629208" ), BigInt!( - "15697249904809157640137081638559691717147113859496833342722786814178099529209" + "11709584278193617231017776985640196897412209200566866495381859539145549732339" ), ), ], @@ -376,12 +382,11 @@ mod tests { fn test() { assert_eq!( verify_zkp( - U256::from_str("0x219BEFB142BED271ACC41A52BA3F412BD1418AED36474A76AEFBFAD12CC6B592").unwrap(), - U256::from_str("0x219BEFB142BED271ACC41A52BA3F412BD1418AED36474A76AEFBFAD12CC6B592").unwrap(), - &hex!("650802113E0200000000000022480A207022627E60ED78120D2FE8DC7ACDB58A2321B0304F8912D2DFB86CE038E23CA812240801122041B8793236EE0980E2EAF1A2FAD268C4A3D8979A0C432F06E284EEC5E74DD69C320E756E696F6E2D6465766E65742D31"), - hex!("170904B6B6F8E61E6E2D357436C7C3671E0ADE5ECF97E7A7A644F4B9F4DCC865138AAB8106303EFD304171C3B1E5181E4772AE47A050E19D9074BFD59072EE971FAC59DE603A8E7A677C4B55BD96FB62566CABD242D787687A86820E7ECD270407748CFCC9A3C646DD773D06AF98AB4ACBDF0FD76069212ABFF40C73C1FE0017073337A045A075449995D9B64417D017B670950E6C4F0BE8D8DA1AAFC41C3F4F0DCC256FD3B003EC5FC4A1A8BF7638FE2F703322DD418CC05E2EABC2A5801EA70CBC6020CA6DE288936436764093B0B18F815382DCDD75CEDC5B9D2B366478681C3B99E0A7F21D90D856C8AA59693A800A144D730737C3FD3E21B5DEBD1FC2B228516CBE9584853821FAE64F1C903936C07392529A5FB430007B3EB94C7EEB2F26A8A6B5E8474E4C283A2FD7A9DAD63A78230696F6D882D654725E28198653902B1CECF46DC9C200AEB9DB432A8ACA40EECD8CBA27C32975F1B338B7EFFC2CBA") + U256::from_str("0x0472116C575F0FECF44ED4F91C34E9E7B67CE8C911FC67F304C2B804330B61F0").unwrap(), + U256::from_str("0x0472116C575F0FECF44ED4F91C34E9E7B67CE8C911FC67F304C2B804330B61F0").unwrap(), + &hex!("650802113E0200000000000022480A20DFAD1A5E2BB2B94BD7ED5F4F85199E0DDD95FB4687CFBF19B36865845BD16E20122408011220E32B1FA520CE4F9D0C1A2C80D51FB1F09B9C241101BE70D5CE0DC0F11B009863320E756E696F6E2D6465766E65742D31"), + hex!("19EB187C4EA70DA41CE1C2E9C81D7F4ACC9B8CD85A98AD59A64BD9D820A1D4E41DA150358EC5AFCBA7407D66AFABD59B1B92095D6A797572FAE6FE9C9A500E7C284C0AF8310181C072C1002961BE007DFC68DFDBD9CCF930410153829DA0E00D20ECDCE1DF5674D69A70BFB0891CE61888AADC6B362E27C6E4C9D1905ED327402EEE2EB635235068CBCBAB909D9A14A8992E74DE17D69269FC60CC448A832F8E1BCA6C3426A79029508AEE21DBB718F016FEC33A0A500EA14A05E3E19548634F04011075515FF876980559B120DC247A190BF699C2BA19ECDA92220AADAF3F5A1D502B8552BCC4BBDBA3C53EA39FAA5D6A7D23E06AE8F52AEECCED971D7D353613F7C750995DDD6BCCBB3E3185CF5B53EADAA6FA412665A0910FF709E49CFDFB0530B479EE5F0774588EE7397F7E050A9F4C87DB7989E2557E76353BF98CF7B922EB5DBE6D66AEA64C33AF7D6469BF3EFD5ACA10936CED35DAE692D489AAF8C2") ), Ok(()) ); } -} diff --git a/uniond/go.mod b/uniond/go.mod index eb64574051..af03618075 100644 --- a/uniond/go.mod +++ b/uniond/go.mod @@ -36,7 +36,6 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 - gopkg.in/yaml.v2 v2.4.0 ) require ( @@ -209,6 +208,7 @@ require ( google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect nhooyr.io/websocket v1.8.7 // indirect @@ -218,12 +218,12 @@ require ( ) replace ( - github.com/cometbft/cometbft => github.com/unionlabs/cometbls v0.0.0-20240108104619-5ed53d0e59b9 + github.com/cometbft/cometbft => github.com/unionlabs/cometbls v0.0.0-20240111183309-e159e964fa07 github.com/consensys/gnark => github.com/consensys/gnark v0.9.1-0.20231013131835-4ebcccd9c0a8 // Fork of gnark crypto until https://github.com/ConsenSys/gnark-crypto/pull/314 is merged github.com/consensys/gnark-crypto => github.com/unionlabs/gnark-crypto v0.0.0-20231016072529-15c0507b6578 - github.com/cosmos/cosmos-sdk => github.com/unionlabs/cosmos-sdk v0.0.0-20240108104904-d7de88f54965 + github.com/cosmos/cosmos-sdk => github.com/unionlabs/cosmos-sdk v0.0.0-20240111183419-b58f90f260ce github.com/cosmos/ibc-go/modules/light-clients/08-wasm => github.com/unionlabs/ibc-go/modules/light-clients/08-wasm v0.0.0-20231219091832-0947f2e3d1aa github.com/cosmos/ibc-go/v8 => github.com/unionlabs/ibc-go/v8 v8.0.0-20231219091832-0947f2e3d1aa diff --git a/uniond/go.sum b/uniond/go.sum index 65dbff4425..fb28ee07ae 100644 --- a/uniond/go.sum +++ b/uniond/go.sum @@ -1079,10 +1079,10 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/unionlabs/cometbls v0.0.0-20240108104619-5ed53d0e59b9 h1:geQswI0cfu5sD3wprwn8SkIfnNkAmRoDyuEt7JU7p/4= -github.com/unionlabs/cometbls v0.0.0-20240108104619-5ed53d0e59b9/go.mod h1:3H1gcLEVOQZbPwdH8gyv4UzwHtEawNgcnytglkCQVOQ= -github.com/unionlabs/cosmos-sdk v0.0.0-20240108104904-d7de88f54965 h1:pwK3MTnhxialeoEMpU632IjzY8gu53dFoDHya6sY3A8= -github.com/unionlabs/cosmos-sdk v0.0.0-20240108104904-d7de88f54965/go.mod h1:9QHZ3nex7R4cnZuGd/jmzk5nzsQ+7zxblS5MwshytQw= +github.com/unionlabs/cometbls v0.0.0-20240111183309-e159e964fa07 h1:y2q9sWscXNgo0w/iDdnRID3Fd2s4Mbdcn4poDwwSfpI= +github.com/unionlabs/cometbls v0.0.0-20240111183309-e159e964fa07/go.mod h1:3H1gcLEVOQZbPwdH8gyv4UzwHtEawNgcnytglkCQVOQ= +github.com/unionlabs/cosmos-sdk v0.0.0-20240111183419-b58f90f260ce h1:XsA/6QgQixsGW6CBOFYaK6D/viGcRBXF4THJhhBP2LM= +github.com/unionlabs/cosmos-sdk v0.0.0-20240111183419-b58f90f260ce/go.mod h1:l6W0x49uOfoq2JVMJGE6OqmYtBcUssRCNXlPXEzp3cY= github.com/unionlabs/gnark-crypto v0.0.0-20231016072529-15c0507b6578 h1:Owzup0XvshGNHgS1s0xUI/mZM+fPvTT7dLg7P0cT2vQ= github.com/unionlabs/gnark-crypto v0.0.0-20231016072529-15c0507b6578/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/unionlabs/ibc-go/modules/light-clients/08-wasm v0.0.0-20231219091832-0947f2e3d1aa h1:pzXp42whoLAzvNkdJHPnWPzWAN2iDtqAFoN/BksxmAE= diff --git a/uniond/vendor/github.com/cometbft/cometbft/crypto/bn254/bn254.go b/uniond/vendor/github.com/cometbft/cometbft/crypto/bn254/bn254.go index f50e135d5d..1f641e7efe 100644 --- a/uniond/vendor/github.com/cometbft/cometbft/crypto/bn254/bn254.go +++ b/uniond/vendor/github.com/cometbft/cometbft/crypto/bn254/bn254.go @@ -100,7 +100,7 @@ var _ crypto.PubKey = PubKey{} type PubKey []byte -func(pubKey PubKey) EnsureValid() error { +func (pubKey PubKey) EnsureValid() error { var public bn254.G1Affine _, err := public.SetBytes(pubKey) if err != nil { @@ -224,17 +224,11 @@ func HashToField2(msg []byte) (fr.Element, fr.Element) { // TODO: link union whitepaper 4.1.1, M func HashToG2(msg []byte) bn254.G2Affine { x, y := HashToField2(msg) - point := nativeNaiveScalarMul(bn254.MapToCurve2(&bn254.E2{ + point := bn254.MapToG2(bn254.E2{ A0: *new(fp.Element).SetBigInt(x.BigInt(new(big.Int))), A1: *new(fp.Element).SetBigInt(y.BigInt(new(big.Int))), - }), &G2Cofactor) - // Any of the following case are impossible and should break consensus - if !point.IsOnCurve() { - panic("Point is not on the curve") - } - if !point.IsInSubGroup() { - panic("Point is not in subgroup") - } + }) + // Must not be zero if point.IsInfinity() { panic("Point is zero") } @@ -283,29 +277,29 @@ func (l MerkleLeaf) Hash() ([]byte, error) { frYBytes := l.ShiftedY.Bytes() mimc := mimc.NewMiMC() _, err := mimc.Write(frXBytes[:]) - if(err != nil) { + if err != nil { return nil, err } _, err = mimc.Write(frYBytes[:]) - if(err != nil) { + if err != nil { return nil, err } var padded [32]byte big.NewInt(int64(l.MsbX)).FillBytes(padded[:]) _, err = mimc.Write(padded[:]) - if(err != nil) { + if err != nil { return nil, err } big.NewInt(int64(l.MsbY)).FillBytes(padded[:]) _, err = mimc.Write(padded[:]) - if(err != nil) { + if err != nil { return nil, err } var powerBytes big.Int powerBytes.SetUint64(uint64(l.VotingPower)) powerBytes.FillBytes(padded[:]) _, err = mimc.Write(padded[:]) - if(err != nil) { + if err != nil { return nil, err } return mimc.Sum(nil), nil diff --git a/uniond/vendor/modules.txt b/uniond/vendor/modules.txt index b89f00ce18..ef772359df 100644 --- a/uniond/vendor/modules.txt +++ b/uniond/vendor/modules.txt @@ -381,7 +381,7 @@ github.com/cockroachdb/redact/internal/rfmt/fmtsort # github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 ## explicit; go 1.19 github.com/cockroachdb/tokenbucket -# github.com/cometbft/cometbft v0.38.2 => github.com/unionlabs/cometbls v0.0.0-20240108104619-5ed53d0e59b9 +# github.com/cometbft/cometbft v0.38.2 => github.com/unionlabs/cometbls v0.0.0-20240111183309-e159e964fa07 ## explicit; go 1.21 github.com/cometbft/cometbft/abci/client github.com/cometbft/cometbft/abci/example/kvstore @@ -516,7 +516,7 @@ github.com/cosmos/cosmos-db github.com/cosmos/cosmos-proto github.com/cosmos/cosmos-proto/anyutil github.com/cosmos/cosmos-proto/runtime -# github.com/cosmos/cosmos-sdk v0.50.2 => github.com/unionlabs/cosmos-sdk v0.0.0-20240108104904-d7de88f54965 +# github.com/cosmos/cosmos-sdk v0.50.2 => github.com/unionlabs/cosmos-sdk v0.0.0-20240111183419-b58f90f260ce ## explicit; go 1.21 github.com/cosmos/cosmos-sdk/baseapp github.com/cosmos/cosmos-sdk/baseapp/internal/protocompat @@ -1746,10 +1746,10 @@ rsc.io/tmplfunc/internal/parse ## explicit; go 1.12 sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 -# github.com/cometbft/cometbft => github.com/unionlabs/cometbls v0.0.0-20240108104619-5ed53d0e59b9 +# github.com/cometbft/cometbft => github.com/unionlabs/cometbls v0.0.0-20240111183309-e159e964fa07 # github.com/consensys/gnark => github.com/consensys/gnark v0.9.1-0.20231013131835-4ebcccd9c0a8 # github.com/consensys/gnark-crypto => github.com/unionlabs/gnark-crypto v0.0.0-20231016072529-15c0507b6578 -# github.com/cosmos/cosmos-sdk => github.com/unionlabs/cosmos-sdk v0.0.0-20240108104904-d7de88f54965 +# github.com/cosmos/cosmos-sdk => github.com/unionlabs/cosmos-sdk v0.0.0-20240111183419-b58f90f260ce # github.com/cosmos/ibc-go/modules/light-clients/08-wasm => github.com/unionlabs/ibc-go/modules/light-clients/08-wasm v0.0.0-20231219091832-0947f2e3d1aa # github.com/cosmos/ibc-go/v8 => github.com/unionlabs/ibc-go/v8 v8.0.0-20231219091832-0947f2e3d1aa # github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7