diff --git a/_input/circuit/emulated/input_1.json b/_input/circuit/emulated/input_1.json new file mode 100644 index 00000000..1845bc17 --- /dev/null +++ b/_input/circuit/emulated/input_1.json @@ -0,0 +1,5 @@ +{ + "X": "26959946673427741531515197488526605382048662297355296634326893985793", + "Y": "53919893346855483063030394977053210764097324594710593268653787971586", + "Res": "485279052387156144224396168012515269674445015885648619762653195154800" +} diff --git a/_input/circuit/expo/input_1.json b/_input/circuit/expo/input_1.json deleted file mode 100644 index 0912e1dc..00000000 --- a/_input/circuit/expo/input_1.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "X": "2", - "Y": "4", - "N": "2" -} \ No newline at end of file diff --git a/_input/config/gnark/config_all_toy.json b/_input/config/gnark/config_all_toy.json index ee6b13da..4e7d8ef9 100644 --- a/_input/config/gnark/config_all_toy.json +++ b/_input/config/gnark/config_all_toy.json @@ -18,8 +18,8 @@ "cubic": { "input_path": "_input/circuit/cubic" }, - "expo": { - "input_path": "_input/circuit/expo" + "emulate": { + "input_path": "_input/circuit/emulated" }, "exponentiate": { "input_path": "_input/circuit/exponentiate" diff --git a/gnark/Makefile b/gnark/Makefile index 12184a52..88cbff0d 100644 --- a/gnark/Makefile +++ b/gnark/Makefile @@ -8,8 +8,8 @@ all: test-toy test-prf test-toy: go test $(directory)/circuits/toy/cubic - go test $(directory)/circuits/toy/expo go test $(directory)/circuits/toy/exponentiate + go test $(directory)/circuits/toy/emulate test-prf: go test $(directory)/circuits/prf/mimc diff --git a/gnark/circuits/circuits.go b/gnark/circuits/circuits.go index 586005f1..d1bbddec 100644 --- a/gnark/circuits/circuits.go +++ b/gnark/circuits/circuits.go @@ -7,17 +7,17 @@ import ( bls12377fr "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" "github.com/consensys/gnark-crypto/hash" - bls12381fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" bls24315fr "github.com/consensys/gnark-crypto/ecc/bls24-315/fr" bn254fr "github.com/consensys/gnark-crypto/ecc/bn254/fr" bw6633fr "github.com/consensys/gnark-crypto/ecc/bw6-633/fr" bw6761fr "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" "github.com/consensys/gnark/backend/witness" "github.com/consensys/gnark/frontend" + emulated "github.com/consensys/gnark/std/math/emulated" "github.com/tumberger/zk-compilers/gnark/circuits/prf/mimc" sha256 "github.com/tumberger/zk-compilers/gnark/circuits/prf/sha256" "github.com/tumberger/zk-compilers/gnark/circuits/toy/cubic" - "github.com/tumberger/zk-compilers/gnark/circuits/toy/expo" + emulate "github.com/tumberger/zk-compilers/gnark/circuits/toy/emulate" "github.com/tumberger/zk-compilers/gnark/circuits/toy/exponentiate" "github.com/tumberger/zk-compilers/gnark/util" ) @@ -34,74 +34,14 @@ func init() { // Toy Circuits BenchCircuits["cubic"] = &defaultCircuit{} - BenchCircuits["expo"] = &defaultCircuit{} BenchCircuits["exponentiate"] = &defaultCircuit{} + BenchCircuits["emulate"] = &defaultCircuit{} // Hashes BenchCircuits["mimc"] = &defaultCircuit{} BenchCircuits["sha256"] = &defaultCircuit{} } -func preCalc(size int, curveID ecc.ID) interface{} { - switch curveID { - case ecc.BN254: - // compute expected Y - var expectedY bn254fr.Element - expectedY.SetInterface(2) - for i := 0; i < size; i++ { - expectedY.Mul(&expectedY, &expectedY) - } - return expectedY - case ecc.BLS12_381: - // compute expected Y - var expectedY bls12381fr.Element - expectedY.SetInterface(2) - for i := 0; i < size; i++ { - expectedY.Mul(&expectedY, &expectedY) - } - - return expectedY - case ecc.BLS12_377: - // compute expected Y - var expectedY bls12377fr.Element - expectedY.SetInterface(2) - for i := 0; i < size; i++ { - expectedY.Mul(&expectedY, &expectedY) - } - - return expectedY - case ecc.BLS24_315: - // compute expected Y - var expectedY bls24315fr.Element - expectedY.SetInterface(2) - for i := 0; i < size; i++ { - expectedY.Mul(&expectedY, &expectedY) - } - - return expectedY - case ecc.BW6_761: - // compute expected Y - var expectedY bw6761fr.Element - expectedY.SetInterface(2) - for i := 0; i < size; i++ { - expectedY.Mul(&expectedY, &expectedY) - } - - return expectedY - case ecc.BW6_633: - // compute expected Y - var expectedY bw6633fr.Element - expectedY.SetInterface(2) - for i := 0; i < size; i++ { - expectedY.Mul(&expectedY, &expectedY) - } - - return expectedY - default: - panic("not implemented") - } -} - func preCalcMIMC(curveID ecc.ID, preImage frontend.Variable) interface{} { switch curveID { @@ -177,10 +117,10 @@ func (d *defaultCircuit) Circuit(size int, name string, path string) frontend.Ci switch name { case "cubic": return &cubic.CubicCircuit{} - case "expo": - return &expo.BenchCircuit{N: size} case "exponentiate": return &exponentiate.ExponentiateCircuit{} + case "emulate": + return &emulate.Circuit{} case "mimc": return &mimc.MimcCircuit{} case "sha256": @@ -210,10 +150,11 @@ func (d *defaultCircuit) Witness(size int, curveID ecc.ID, name string, path str panic(err) } return w - case "expo": - witness := expo.BenchCircuit{N: size} - witness.X = (2) - witness.Y = preCalc(size, curveID) + case "emulate": + witness := emulate.Circuit{} + witness.X = emulated.ValueOf[emulated.Secp256k1Fp](data["X"].(string)) + witness.Y = emulated.ValueOf[emulated.Secp256k1Fp](data["Y"].(string)) + witness.Res = emulated.ValueOf[emulated.Secp256k1Fp](data["Res"].(string)) w, err := frontend.NewWitness(&witness, curveID.ScalarField()) if err != nil { @@ -222,9 +163,9 @@ func (d *defaultCircuit) Witness(size int, curveID ecc.ID, name string, path str return w case "exponentiate": witness := exponentiate.ExponentiateCircuit{} - witness.X = (2) - witness.E = (12) - witness.Y = (4096) + witness.X = (data["X"].(string)) + witness.E = (data["E"].(string)) + witness.Y = (data["Y"].(string)) w, err := frontend.NewWitness(&witness, curveID.ScalarField()) if err != nil { diff --git a/gnark/circuits/toy/emulate/emulate.go b/gnark/circuits/toy/emulate/emulate.go new file mode 100644 index 00000000..6402dd34 --- /dev/null +++ b/gnark/circuits/toy/emulate/emulate.go @@ -0,0 +1,23 @@ +package emulated + +import ( + "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/std/math/emulated" +) + +type Circuit struct { + // Limbs of non-native elements X, Y and Res + X, Y, Res emulated.Element[emulated.Secp256k1Fp] +} + +func (circuit *Circuit) Define(api frontend.API) error { + // wrap API to work in SECP256k1 scalar field + secp256k1, err := emulated.NewField[emulated.Secp256k1Fp](api) + if err != nil { + return err + } + + tmp := secp256k1.Mul(&circuit.X, &circuit.Y) + secp256k1.AssertIsEqual(tmp, &circuit.Res) + return nil +} diff --git a/gnark/circuits/toy/emulate/emulate_test.go b/gnark/circuits/toy/emulate/emulate_test.go new file mode 100644 index 00000000..86a6df79 --- /dev/null +++ b/gnark/circuits/toy/emulate/emulate_test.go @@ -0,0 +1,23 @@ +package emulated + +import ( + "testing" + + "github.com/consensys/gnark/std" + "github.com/consensys/gnark/std/math/emulated" + "github.com/consensys/gnark/test" +) + +func TestEmulatedArithmetic(t *testing.T) { + assert := test.NewAssert(t) + std.RegisterHints() + + var circuit, witness Circuit + + witness.X = emulated.ValueOf[emulated.Secp256k1Fp]("26959946673427741531515197488526605382048662297355296634326893985793") + witness.Y = emulated.ValueOf[emulated.Secp256k1Fp]("53919893346855483063030394977053210764097324594710593268653787971586") + witness.Res = emulated.ValueOf[emulated.Secp256k1Fp]("485279052387156144224396168012515269674445015885648619762653195154800") + + // Test over all curves, takes approx 30s + assert.ProverSucceeded(&circuit, &witness, test.NoSerialization()) +} diff --git a/gnark/circuits/toy/expo/expo.go b/gnark/circuits/toy/expo/expo.go deleted file mode 100644 index f4318e63..00000000 --- a/gnark/circuits/toy/expo/expo.go +++ /dev/null @@ -1,19 +0,0 @@ -package expo - -import "github.com/consensys/gnark/frontend" - -// benchCircuit is a simple circuit that checks X*X*X*X*X... == Y -type BenchCircuit struct { - X frontend.Variable - Y frontend.Variable `gnark:",public"` - N int -} - -// Circuit defines a an exponentiation for a frontend variable with itself -func (circuit *BenchCircuit) Define(api frontend.API) error { - for i := 0; i < circuit.N; i++ { - circuit.X = api.Mul(circuit.X, circuit.X) - } - api.AssertIsEqual(circuit.Y, circuit.X) - return nil -} diff --git a/gnark/circuits/toy/expo/expo_test.go b/gnark/circuits/toy/expo/expo_test.go deleted file mode 100644 index eddf27b1..00000000 --- a/gnark/circuits/toy/expo/expo_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package expo - -import ( - "testing" - - "github.com/consensys/gnark/test" -) - -func TestExpoGroth16(t *testing.T) { - - assert := test.NewAssert(t) - - var benchCircuit BenchCircuit - - assert.ProverFailed(&benchCircuit, &BenchCircuit{ - X: 2, - Y: 5, - N: 2, - }) - - assert.ProverSucceeded(&benchCircuit, &BenchCircuit{ - X: 2, - Y: 4, - N: 2, - }) - -}