From e4a73270b74da56751e5f138c102c543e8b3decb Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Wed, 21 Sep 2022 10:46:15 +0200 Subject: [PATCH 01/11] feat: add go-ethereum dep for ecdsa compatibility --- go.mod | 3 +++ go.sum | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/go.mod b/go.mod index 218f6a1f41..e40c622da3 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/blang/semver/v4 v4.0.0 github.com/consensys/bavard v0.1.13 github.com/consensys/gnark-crypto v0.8.1-0.20221205155504-6b860ba21fbd + github.com/ethereum/go-ethereum v1.10.26 github.com/fxamacker/cbor/v2 v2.2.0 github.com/google/go-cmp v0.5.8 github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1 @@ -16,7 +17,9 @@ require ( ) require ( + github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index 477796b8ba..da0a6700ef 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,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/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= +github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= 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.8.1-0.20221205155504-6b860ba21fbd h1:xpAhzOw3dZvRiQeTWmIO8KemBS5XdBsU+/jLfwibEmc= @@ -9,6 +12,12 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/ethereum/go-ethereum v1.10.26 h1:i/7d9RBBwiXCEuyduBQzJw/mKmnvzsN14jqBmytw72s= +github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= github.com/fxamacker/cbor/v2 v2.2.0 h1:6eXqdDDe588rSYAi1HfZKbx6YYQO4mxQ9eC6xYpU/JQ= github.com/fxamacker/cbor/v2 v2.2.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= From 17443d0b94058a61ef54d3c43939e690beaadc00 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Wed, 21 Sep 2022 10:46:32 +0200 Subject: [PATCH 02/11] feat: add emulated SW EC --- std/algebra/weierstrass/doc.go | 33 +++++ std/algebra/weierstrass/doc_test.go | 84 ++++++++++++ std/algebra/weierstrass/params.go | 71 ++++++++++ std/algebra/weierstrass/point.go | 163 ++++++++++++++++++++++ std/algebra/weierstrass/point_test.go | 186 ++++++++++++++++++++++++++ 5 files changed, 537 insertions(+) create mode 100644 std/algebra/weierstrass/doc.go create mode 100644 std/algebra/weierstrass/doc_test.go create mode 100644 std/algebra/weierstrass/params.go create mode 100644 std/algebra/weierstrass/point.go create mode 100644 std/algebra/weierstrass/point_test.go diff --git a/std/algebra/weierstrass/doc.go b/std/algebra/weierstrass/doc.go new file mode 100644 index 0000000000..72ff229dad --- /dev/null +++ b/std/algebra/weierstrass/doc.go @@ -0,0 +1,33 @@ +/* +Package weierstrass implements elliptic curve group operations in (short) +Weierstrass form. + +The elliptic curve is the set of points (X,Y) satisfying the equation: + + Y² = X³ + aX + b + +over some base field 𝐅p for some constants a, b ∈ 𝐅p. +Additionally, for every curve we also define its generator (base point) G. All +these parameters are stored in the variable of type [CurveParams]. + +The package provides a few curve parameters, see functions [GetSecp256k1Params] +and [GetBN254Params]. + +Unconventionally, this package uses type parameters to define the base field of +the points and variables to define the coefficients of the curve. This is due to +how the emulated elements are constructed by their type parameters. To unify the +different conventions, we provide the method [GetCurveParams] to allow resolving +a particular curve parameter depending on the type parameter defining the base +field. For now, we only have a single curve defined on every base field, but +this may change in the future with the addition of additional curves. + +This package uses field emulation (unlike packages +[github.com/consensys/gnark/std/algebra/sw_bls12377] and +[github.com/consensys/gnark/std/algebra/sw_bls24315], which use 2-chains). This +allows to use any curve over any native (SNARK) field. The drawback of this +approach is the extreme cost of the operations. In R1CS, point addition on +256-bit fields is approximately 3500 constraints and doubling is approximately +4300 constraints. A full scalar multiplication is approximately 2M constraints. +It is several times more in PLONKish aritmetisation. +*/ +package weierstrass diff --git a/std/algebra/weierstrass/doc_test.go b/std/algebra/weierstrass/doc_test.go new file mode 100644 index 0000000000..808652922f --- /dev/null +++ b/std/algebra/weierstrass/doc_test.go @@ -0,0 +1,84 @@ +package weierstrass_test + +import ( + "fmt" + "math/big" + + "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark/backend/groth16" + "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/frontend/cs/r1cs" + "github.com/consensys/gnark/std/algebra/weierstrass" + "github.com/consensys/gnark/std/math/emulated" + "github.com/ethereum/go-ethereum/crypto/secp256k1" +) + +type ExampleCurveCircuit[Base, Scalar emulated.FieldParams] struct { + Res weierstrass.AffinePoint[Base] +} + +func (c *ExampleCurveCircuit[B, S]) Define(api frontend.API) error { + curve, err := weierstrass.New[B, S](api, weierstrass.GetCurveParams[emulated.BN254Fp]()) + if err != nil { + panic("initalize new curve") + } + G := curve.Generator() + scalar4 := emulated.NewElement[S](4) + g4 := curve.ScalarMul(G, &scalar4) // 4*G + scalar5 := emulated.NewElement[S](5) + g5 := curve.ScalarMul(G, &scalar5) // 5*G + g9 := curve.Add(g4, g5) // 9*G + curve.AssertIsEqual(g9, &c.Res) + return nil +} + +func ExampleCurve() { + secpCurve := secp256k1.S256() + s := big.NewInt(9) + sx, sy := secpCurve.ScalarMult(secpCurve.Gx, secpCurve.Gy, s.Bytes()) + fmt.Printf("result (%d, %d)", sx, sy) + + circuit := ExampleCurveCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} + witness := ExampleCurveCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ + Res: weierstrass.AffinePoint[emulated.Secp256k1Fp]{ + X: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gx), + Y: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gy), + }, + } + ccs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) + if err != nil { + panic(err) + } else { + fmt.Println("compiled") + } + pk, vk, err := groth16.Setup(ccs) + if err != nil { + panic(err) + } else { + fmt.Println("setup done") + } + secretWitness, err := frontend.NewWitness(&witness, ecc.BN254.ScalarField()) + if err != nil { + panic(err) + } else { + fmt.Println("secret witness") + } + publicWitness, err := secretWitness.Public() + if err != nil { + panic(err) + } else { + fmt.Println("public witness") + } + proof, err := groth16.Prove(ccs, pk, secretWitness) + if err != nil { + panic(err) + } else { + fmt.Println("proof") + } + err = groth16.Verify(proof, vk, publicWitness) + if err != nil { + panic(err) + } else { + fmt.Println("verify") + } +} diff --git a/std/algebra/weierstrass/params.go b/std/algebra/weierstrass/params.go new file mode 100644 index 0000000000..aadf2bce6a --- /dev/null +++ b/std/algebra/weierstrass/params.go @@ -0,0 +1,71 @@ +package weierstrass + +import ( + "math/big" + + "github.com/consensys/gnark/std/math/emulated" +) + +// CurveParams defines parameters of an elliptic curve in short Weierstrass form +// given by the equation +// +// Y² = X³ + aX + b +// +// The base point is defined by (Gx, Gy). +type CurveParams struct { + A *big.Int // a in curve equation + B *big.Int // b in curve equation + Gx *big.Int // base point x + Gy *big.Int // base point y +} + +// GetSecp256k1Params returns curve parameters for the curve secp256k1. When +// initialising new curve, use the base field [emulated.Secp256k1Fp] and scalar +// field [emulated.Secp256k1Fr]. +func GetSecp256k1Params() CurveParams { + gx, _ := new(big.Int).SetString("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", 16) + gy, _ := new(big.Int).SetString("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", 16) + return CurveParams{ + A: big.NewInt(0), + B: big.NewInt(7), + Gx: gx, + Gy: gy, + } +} + +// GetBN254Params returns the curve parameters for the curve BN254 (alt_bn128). +// When initialising new curve, use the base field [emulated.BN254Fp] and scalar +// field [emulated.BN254Fr]. +func GetBN254Params() CurveParams { + gx := big.NewInt(1) + gy := big.NewInt(2) + return CurveParams{ + A: big.NewInt(0), + B: big.NewInt(3), + Gx: gx, + Gy: gy, + } +} + +// GetCurveParams returns suitable curve parameters given the parametric type Base as base field. +func GetCurveParams[Base emulated.FieldParams]() CurveParams { + var t Base + switch t.Modulus().Text(16) { + case "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f": + return secp256k1Params + case "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47": + return bn254Params + default: + panic("no stored parameters") + } +} + +var ( + secp256k1Params CurveParams + bn254Params CurveParams +) + +func init() { + secp256k1Params = GetSecp256k1Params() + bn254Params = GetBN254Params() +} diff --git a/std/algebra/weierstrass/point.go b/std/algebra/weierstrass/point.go new file mode 100644 index 0000000000..e12677de01 --- /dev/null +++ b/std/algebra/weierstrass/point.go @@ -0,0 +1,163 @@ +package weierstrass + +import ( + "fmt" + "math/big" + + "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/std/math/emulated" +) + +// New returns a new [Curve] instance over the base field Base and scalar field +// Scalars defined by the curve parameters params. It returns an error if +// initialising the field emulation fails (for example, when the native field is +// too small) or when the curve parameters are incompatible with the fields. +func New[Base, Scalars emulated.FieldParams](api frontend.API, params CurveParams) (*Curve[Base, Scalars], error) { + ba, err := emulated.NewField[Base](api) + if err != nil { + return nil, fmt.Errorf("new base api: %w", err) + } + sa, err := emulated.NewField[Scalars](api) + if err != nil { + return nil, fmt.Errorf("new scalar api: %w", err) + } + Gx := emulated.NewElement[Base](params.Gx) + Gy := emulated.NewElement[Base](params.Gy) + return &Curve[Base, Scalars]{ + params: params, + api: api, + baseApi: ba, + scalarApi: sa, + g: AffinePoint[Base]{ + X: Gx, + Y: Gy, + }, + a: emulated.NewElement[Base](params.A), + addA: params.A.Cmp(big.NewInt(0)) != 0, + }, nil +} + +// Curve is an initialised curve which allows performing group operations. +type Curve[Base, Scalars emulated.FieldParams] struct { + // params is the parameters of the curve + params CurveParams + // api is the native api, we construct it ourselves to be sure + api frontend.API + // baseApi is the api for point operations + baseApi *emulated.Field[Base] + // scalarApi is the api for scalar operations + scalarApi *emulated.Field[Scalars] + + // g is the generator (base point) of the curve. + g AffinePoint[Base] + + a emulated.Element[Base] + addA bool +} + +// Generator returns the base point of the curve. The method does not copy and +// modifying the returned element leads to undefined behaviour! +func (c *Curve[B, S]) Generator() *AffinePoint[B] { + return &c.g +} + +// AffinePoint represents a point on the elliptic curve. We do not check that +// the point is actually on the curve. +type AffinePoint[Base emulated.FieldParams] struct { + X, Y emulated.Element[Base] +} + +// Neg returns an inverse of p. It doesn't modify p. +func (c *Curve[B, S]) Neg(p *AffinePoint[B]) *AffinePoint[B] { + return &AffinePoint[B]{ + X: p.X, + Y: *c.baseApi.Neg(&p.Y), + } +} + +// AssertIsEqual asserts that p and q are the same point. +func (c *Curve[B, S]) AssertIsEqual(p, q *AffinePoint[B]) { + c.baseApi.AssertIsEqual(&p.X, &q.X) + c.baseApi.AssertIsEqual(&p.Y, &q.Y) +} + +// Add adds q and r and returns it. +func (c *Curve[B, S]) Add(q, r *AffinePoint[B]) *AffinePoint[B] { + // compute lambda = (p1.y-p.y)/(p1.x-p.x) + p1ypy := c.baseApi.Sub(&r.Y, &q.Y) + p1xpx := c.baseApi.Sub(&r.X, &q.X) + lambda := c.baseApi.Div(p1ypy, p1xpx) + + // xr = lambda**2-p.x-p1.x + lambdaSq := c.baseApi.MulMod(lambda, lambda) + qxrx := c.baseApi.Add(&q.X, &r.X) + xr := c.baseApi.Sub(lambdaSq, qxrx) + + // p.y = lambda(p.x-xr) - p.y + pxxr := c.baseApi.Sub(&q.X, xr) + lpxxr := c.baseApi.MulMod(lambda, pxxr) + py := c.baseApi.Sub(lpxxr, &q.Y) + + return &AffinePoint[B]{ + X: *c.baseApi.Reduce(xr), + Y: *c.baseApi.Reduce(py), + } +} + +// Double doubles p and return it. It doesn't modify p. +func (c *Curve[B, S]) Double(p *AffinePoint[B]) *AffinePoint[B] { + + // compute lambda = (3*p1.x**2+a)/2*p1.y, here we assume a=0 (j invariant 0 curve) + xSq3a := c.baseApi.MulMod(&p.X, &p.X) + xSq3a = c.baseApi.MulConst(xSq3a, big.NewInt(3)) + if c.addA { + xSq3a = c.baseApi.Add(xSq3a, &c.a) + } + y2 := c.baseApi.MulConst(&p.Y, big.NewInt(2)) + lambda := c.baseApi.Div(xSq3a, y2) + + // xr = lambda**2-p1.x-p1.x + x2 := c.baseApi.MulConst(&p.X, big.NewInt(2)) + lambdaSq := c.baseApi.MulMod(lambda, lambda) + xr := c.baseApi.Sub(lambdaSq, x2) + + // p.y = lambda(p.x-xr) - p.y + pxxr := c.baseApi.Sub(&p.X, xr) + lpxxr := c.baseApi.MulMod(lambda, pxxr) + py := c.baseApi.Sub(lpxxr, &p.Y) + + return &AffinePoint[B]{ + X: *c.baseApi.Reduce(xr), + Y: *c.baseApi.Reduce(py), + } +} + +// Select selects between p and q given the selector b. If b == 0, then returns +// p and q otherwise. +func (c *Curve[B, S]) Select(b frontend.Variable, p, q *AffinePoint[B]) *AffinePoint[B] { + x := c.baseApi.Select(b, &p.X, &q.X) + y := c.baseApi.Select(b, &p.Y, &q.Y) + return &AffinePoint[B]{ + X: *x, + Y: *y, + } +} + +// ScalarMul computes s * p and returns it. It doesn't modify p nor s. +func (c *Curve[B, S]) ScalarMul(p *AffinePoint[B], s *emulated.Element[S]) *AffinePoint[B] { + res := p + acc := c.Double(p) + + var st S + sr := c.scalarApi.Reduce(s) + sBits := c.scalarApi.ToBits(sr) + for i := 1; i < st.Modulus().BitLen(); i++ { + tmp := c.Add(res, acc) + res = c.Select(sBits[i], tmp, res) + acc = c.Double(acc) + } + + tmp := c.Add(res, c.Neg(p)) + res = c.Select(sBits[0], res, tmp) + return res +} diff --git a/std/algebra/weierstrass/point_test.go b/std/algebra/weierstrass/point_test.go new file mode 100644 index 0000000000..7b05a998f4 --- /dev/null +++ b/std/algebra/weierstrass/point_test.go @@ -0,0 +1,186 @@ +package weierstrass + +import ( + "math/big" + "testing" + + "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/frontend/cs/r1cs" + "github.com/consensys/gnark/std/math/emulated" + "github.com/consensys/gnark/test" + "github.com/ethereum/go-ethereum/crypto/secp256k1" +) + +var testCurve = ecc.BN254 + +type NegTest[T, S emulated.FieldParams] struct { + P, Q AffinePoint[T] +} + +func (c *NegTest[T, S]) Define(api frontend.API) error { + cr, err := New[T, S](api, GetCurveParams[T]()) + if err != nil { + return err + } + res := cr.Neg(&c.P) + cr.AssertIsEqual(res, &c.Q) + return nil +} + +func TestNeg(t *testing.T) { + assert := test.NewAssert(t) + secpCurve := secp256k1.S256() + yn := new(big.Int).Sub(secpCurve.P, secpCurve.Gy) + circuit := NegTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} + witness := NegTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ + P: AffinePoint[emulated.Secp256k1Fp]{ + X: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gx), + Y: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gy), + }, + Q: AffinePoint[emulated.Secp256k1Fp]{ + X: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gx), + Y: emulated.NewElement[emulated.Secp256k1Fp](yn), + }, + } + err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) + assert.NoError(err) +} + +type AddTest[T, S emulated.FieldParams] struct { + P, Q, R AffinePoint[T] +} + +func (c *AddTest[T, S]) Define(api frontend.API) error { + cr, err := New[T, S](api, GetCurveParams[T]()) + if err != nil { + return err + } + res := cr.Add(&c.P, &c.Q) + cr.AssertIsEqual(res, &c.R) + return nil +} + +func TestAdd(t *testing.T) { + assert := test.NewAssert(t) + secpCurve := secp256k1.S256() + xd, yd := secpCurve.Double(secpCurve.Gx, secpCurve.Gy) + xa, ya := secpCurve.Add(xd, yd, secpCurve.Gx, secpCurve.Gy) + circuit := AddTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} + witness := AddTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ + P: AffinePoint[emulated.Secp256k1Fp]{ + X: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gx), + Y: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gy), + }, + Q: AffinePoint[emulated.Secp256k1Fp]{ + X: emulated.NewElement[emulated.Secp256k1Fp](xd), + Y: emulated.NewElement[emulated.Secp256k1Fp](yd), + }, + R: AffinePoint[emulated.Secp256k1Fp]{ + X: emulated.NewElement[emulated.Secp256k1Fp](xa), + Y: emulated.NewElement[emulated.Secp256k1Fp](ya), + }, + } + err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) + assert.NoError(err) +} + +type DoubleTest[T, S emulated.FieldParams] struct { + P, Q AffinePoint[T] +} + +func (c *DoubleTest[T, S]) Define(api frontend.API) error { + cr, err := New[T, S](api, GetCurveParams[T]()) + if err != nil { + return err + } + res := cr.Double(&c.P) + cr.AssertIsEqual(res, &c.Q) + return nil +} + +func TestDouble(t *testing.T) { + assert := test.NewAssert(t) + secpCurve := secp256k1.S256() + xd, yd := secpCurve.Double(secpCurve.Gx, secpCurve.Gy) + circuit := DoubleTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} + witness := DoubleTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ + P: AffinePoint[emulated.Secp256k1Fp]{ + X: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gx), + Y: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gy), + }, + Q: AffinePoint[emulated.Secp256k1Fp]{ + X: emulated.NewElement[emulated.Secp256k1Fp](xd), + Y: emulated.NewElement[emulated.Secp256k1Fp](yd), + }, + } + err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) + assert.NoError(err) +} + +type ScalarMulTest[T, S emulated.FieldParams] struct { + P, Q AffinePoint[T] + S emulated.Element[S] +} + +func (c *ScalarMulTest[T, S]) Define(api frontend.API) error { + cr, err := New[T, S](api, GetCurveParams[T]()) + if err != nil { + return err + } + res := cr.ScalarMul(&c.P, &c.S) + cr.AssertIsEqual(res, &c.Q) + return nil +} + +func TestScalarMul(t *testing.T) { + assert := test.NewAssert(t) + secpCurve := secp256k1.S256() + s, ok := new(big.Int).SetString("44693544921776318736021182399461740191514036429448770306966433218654680512345", 10) + assert.True(ok) + sx, sy := secpCurve.ScalarMult(secpCurve.Gx, secpCurve.Gy, s.Bytes()) + + circuit := ScalarMulTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} + witness := ScalarMulTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ + S: emulated.NewElement[emulated.Secp256k1Fr](s), + P: AffinePoint[emulated.Secp256k1Fp]{ + X: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gx), + Y: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gy), + }, + Q: AffinePoint[emulated.Secp256k1Fp]{ + X: emulated.NewElement[emulated.Secp256k1Fp](sx), + Y: emulated.NewElement[emulated.Secp256k1Fp](sy), + }, + } + err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) + assert.NoError(err) + _, err = frontend.Compile(testCurve.ScalarField(), r1cs.NewBuilder, &circuit) + assert.NoError(err) +} + +func TestScalarMul2(t *testing.T) { + assert := test.NewAssert(t) + s, ok := new(big.Int).SetString("14108069686105661647148607545884343550368786660735262576656400957535521042679", 10) + assert.True(ok) + var res bn254.G1Affine + _, _, gen, _ := bn254.Generators() + res.ScalarMultiplication(&gen, s) + + circuit := ScalarMulTest[emulated.BN254Fp, emulated.BN254Fr]{} + witness := ScalarMulTest[emulated.BN254Fp, emulated.BN254Fr]{ + S: emulated.NewElement[emulated.BN254Fr](s), + P: AffinePoint[emulated.BN254Fp]{ + X: emulated.NewElement[emulated.BN254Fp](gen.X.ToBigIntRegular(new(big.Int))), + Y: emulated.NewElement[emulated.BN254Fp](gen.Y.ToBigIntRegular(new(big.Int))), + }, + Q: AffinePoint[emulated.BN254Fp]{ + X: emulated.NewElement[emulated.BN254Fp](res.X.ToBigIntRegular(new(big.Int))), + Y: emulated.NewElement[emulated.BN254Fp](res.Y.ToBigIntRegular(new(big.Int))), + }, + } + err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) + assert.NoError(err) + _, err = frontend.Compile(testCurve.ScalarField(), r1cs.NewBuilder, &circuit) + assert.NoError(err) +} From dbebbd257fb65527f7aaa87c930197759e3f32d6 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Thu, 10 Nov 2022 14:51:53 +0100 Subject: [PATCH 03/11] feat: add ECDSA using emulated SW --- std/signature/ecdsa/ecdsa.go | 65 +++++++++++++++ std/signature/ecdsa/ecdsa_test.go | 131 ++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 std/signature/ecdsa/ecdsa.go create mode 100644 std/signature/ecdsa/ecdsa_test.go diff --git a/std/signature/ecdsa/ecdsa.go b/std/signature/ecdsa/ecdsa.go new file mode 100644 index 0000000000..5279f69930 --- /dev/null +++ b/std/signature/ecdsa/ecdsa.go @@ -0,0 +1,65 @@ +/* +Package ecdsa implements ECDSA signature verification over any elliptic curve. + +The package depends on the [weierstrass] package for elliptic curve group +operations using non-native arithmetic. Thus we can verify ECDSA signatures over +any curve. The cost for a single secp256k1 signature verification is +approximately 4M constraints in R1CS and 10M constraints in PLONKish. + +See [ECDSA] for the signature verification algorithm. + +[ECDSA]: +https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm +*/ +package ecdsa + +import ( + "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/std/algebra/weierstrass" + "github.com/consensys/gnark/std/math/emulated" +) + +// Signature represents the signature for some message. +type Signature[Scalar emulated.FieldParams] struct { + R, S emulated.Element[Scalar] +} + +// PublicKey represents the public key to verify the signature for. +type PublicKey[Base, Scalar emulated.FieldParams] weierstrass.AffinePoint[Base] + +// Verify asserts that the signature sig verifies for the message msg and public +// key pk. The curve parameters params define the elliptic curve. +// +// We assume that the message msg is already hashed to the scalar field. +func (pk PublicKey[T, S]) Verify(api frontend.API, params weierstrass.CurveParams, msg *emulated.Element[S], sig *Signature[S]) { + cr, err := weierstrass.New[T, S](api, params) + if err != nil { + // TODO: softer handling. + panic(err) + } + scalarApi, err := emulated.NewField[S](api) + if err != nil { + panic(err) + } + baseApi, err := emulated.NewField[T](api) + if err != nil { + panic(err) + } + pkpt := weierstrass.AffinePoint[T](pk) + sInv := scalarApi.Inverse(&sig.S) + msInv := scalarApi.MulMod(msg, sInv) + rsInv := scalarApi.MulMod(&sig.R, sInv) + + qa := cr.ScalarMul(cr.Generator(), msInv) + qb := cr.ScalarMul(&pkpt, rsInv) + q := cr.Add(qa, qb) + qx := baseApi.Reduce(&q.X) + qxBits := baseApi.ToBits(qx) + rbits := scalarApi.ToBits(&sig.R) + if len(rbits) != len(qxBits) { + panic("non-equal lengths") + } + for i := range rbits { + api.AssertIsEqual(rbits[i], qxBits[i]) + } +} diff --git a/std/signature/ecdsa/ecdsa_test.go b/std/signature/ecdsa/ecdsa_test.go new file mode 100644 index 0000000000..4f5f8474db --- /dev/null +++ b/std/signature/ecdsa/ecdsa_test.go @@ -0,0 +1,131 @@ +package ecdsa + +import ( + "math/big" + "testing" + + "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/std/algebra/weierstrass" + "github.com/consensys/gnark/std/math/emulated" + "github.com/consensys/gnark/test" + "github.com/ethereum/go-ethereum/crypto" +) + +var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" + +func sign(t *testing.T) ([]byte, []byte, error) { + t.Helper() + key, _ := crypto.HexToECDSA(testPrivHex) + msg := crypto.Keccak256([]byte("foo")) + sig, err := crypto.Sign(msg, key) + if err != nil { + t.Errorf("Sign error: %s", err) + } + return sig, msg, nil +} + +type EcdsaCircuit[T, S emulated.FieldParams] struct { + Sig Signature[S] + Msg emulated.Element[S] + Pub PublicKey[T, S] +} + +func (c *EcdsaCircuit[T, S]) Define(api frontend.API) error { + c.Pub.Verify(api, weierstrass.GetCurveParams[T](), &c.Msg, &c.Sig) + return nil +} + +func TestEcdsa(t *testing.T) { + // generate a valid signature + sig, msg, err := sign(t) + if err != nil { + t.Fatal(err) + } + + // check that the signature is correct + pub, err := crypto.Ecrecover(msg, sig) + if err != nil { + t.Fatal(err) + } + sig = sig[:len(sig)-1] + if !crypto.VerifySignature(pub, msg, sig) { + t.Errorf("can't verify signature with uncompressed key") + } + + r := new(big.Int).SetBytes(sig[:32]) + s := new(big.Int).SetBytes(sig[32:]) + m := new(big.Int).SetBytes(msg) + + _pub, err := crypto.UnmarshalPubkey(pub) + if err != nil { + t.Fatal(err) + } + + circuit := EcdsaCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} + witness := EcdsaCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ + Sig: Signature[emulated.Secp256k1Fr]{ + R: emulated.NewElement[emulated.Secp256k1Fr](r), + S: emulated.NewElement[emulated.Secp256k1Fr](s), + }, + Msg: emulated.NewElement[emulated.Secp256k1Fr](m), + Pub: PublicKey[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ + X: emulated.NewElement[emulated.Secp256k1Fp](_pub.X), + Y: emulated.NewElement[emulated.Secp256k1Fp](_pub.Y), + }, + } + assert := test.NewAssert(t) + err = test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField()) + assert.NoError(err) + // _, err = frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) + // assert.NoError(err) +} + +// Example how to verify the signature inside the circuit. +func ExamplePublicKey_Verify() { + api := frontend.API(nil) // provider by the builder + r, s := 0x01, 0x02 // usually given in the witness + pubx, puby := 0x03, 0x04 // usually given in the witness + m := 0x1337 // usually given in the witness + + // can be done in or out-circuit. + Sig := Signature[emulated.Secp256k1Fr]{ + R: emulated.NewElement[emulated.Secp256k1Fr](r), + S: emulated.NewElement[emulated.Secp256k1Fr](s), + } + Msg := emulated.NewElement[emulated.Secp256k1Fr](m) + Pub := PublicKey[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ + X: emulated.NewElement[emulated.Secp256k1Fp](pubx), + Y: emulated.NewElement[emulated.Secp256k1Fp](puby), + } + // signature verification assertion is done in-circuit + Pub.Verify(api, weierstrass.GetCurveParams[emulated.Secp256k1Fp](), &Msg, &Sig) +} + +// Example how to create a valid signature for secp256k1 +func ExamplePublicKey_Verify_create() { + testPrivHex := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" + key, _ := crypto.HexToECDSA(testPrivHex) + msg := crypto.Keccak256([]byte("foo")) + sig, err := crypto.Sign(msg, key) + if err != nil { + panic("sign") + } + _pub, err := crypto.Ecrecover(msg, sig) + if err != nil { + panic("ecrecover") + } + sig = sig[:len(sig)-1] + + pub, err := crypto.UnmarshalPubkey(_pub) + if err != nil { + panic("unmarshal") + } + r := new(big.Int).SetBytes(sig[:32]) + s := new(big.Int).SetBytes(sig[32:]) + m := new(big.Int).SetBytes(msg) + pubx := pub.X + puby := pub.Y + // can continue in the PublicKey Verify example + _, _, _, _, _ = r, s, m, pubx, puby +} From 652702c2cf55a0620338facfa7c3e030bd925267 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Fri, 20 Jan 2023 12:50:17 +0100 Subject: [PATCH 04/11] refactor: use gnark-crypto instead of geth (secp256k1, ecdsa) --- go.mod | 5 +- go.sum | 13 +--- std/algebra/weierstrass/doc_test.go | 13 ++-- std/algebra/weierstrass/point_test.go | 71 ++++++++++-------- std/signature/ecdsa/ecdsa_test.go | 101 +++++++++----------------- 5 files changed, 87 insertions(+), 116 deletions(-) diff --git a/go.mod b/go.mod index bfff27c8c4..29af06a5ea 100644 --- a/go.mod +++ b/go.mod @@ -5,8 +5,7 @@ go 1.18 require ( github.com/blang/semver/v4 v4.0.0 github.com/consensys/bavard v0.1.13 - github.com/consensys/gnark-crypto v0.8.1-0.20221220191316-4b7364bddab8 - github.com/ethereum/go-ethereum v1.10.26 + github.com/consensys/gnark-crypto v0.9.1-0.20230120112145-92008e9e83c5 github.com/fxamacker/cbor/v2 v2.2.0 github.com/google/go-cmp v0.5.8 github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1 @@ -17,9 +16,7 @@ require ( ) require ( - github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index 5903d61278..63ab5a9afb 100644 --- a/go.sum +++ b/go.sum @@ -1,23 +1,14 @@ 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/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= -github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= 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.8.1-0.20221220191316-4b7364bddab8 h1:Ij6UQpKx4/Ox6L6qFPk8NhEnTsYCEXlILnh+1Hi1grY= -github.com/consensys/gnark-crypto v0.8.1-0.20221220191316-4b7364bddab8/go.mod h1:CkbdF9hbRidRJYMRzmfX8TMOr95I2pYXRHF18MzRrvA= +github.com/consensys/gnark-crypto v0.9.1-0.20230120112145-92008e9e83c5 h1:xTPGpHUcenXqhgaLzN5DGB3Ugj86PZYcjImT+yeeE00= +github.com/consensys/gnark-crypto v0.9.1-0.20230120112145-92008e9e83c5/go.mod h1:CkbdF9hbRidRJYMRzmfX8TMOr95I2pYXRHF18MzRrvA= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/ethereum/go-ethereum v1.10.26 h1:i/7d9RBBwiXCEuyduBQzJw/mKmnvzsN14jqBmytw72s= -github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= github.com/fxamacker/cbor/v2 v2.2.0 h1:6eXqdDDe588rSYAi1HfZKbx6YYQO4mxQ9eC6xYpU/JQ= github.com/fxamacker/cbor/v2 v2.2.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= diff --git a/std/algebra/weierstrass/doc_test.go b/std/algebra/weierstrass/doc_test.go index 808652922f..d8a2831b62 100644 --- a/std/algebra/weierstrass/doc_test.go +++ b/std/algebra/weierstrass/doc_test.go @@ -5,12 +5,12 @@ import ( "math/big" "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark-crypto/ecc/secp256k1" "github.com/consensys/gnark/backend/groth16" "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/frontend/cs/r1cs" "github.com/consensys/gnark/std/algebra/weierstrass" "github.com/consensys/gnark/std/math/emulated" - "github.com/ethereum/go-ethereum/crypto/secp256k1" ) type ExampleCurveCircuit[Base, Scalar emulated.FieldParams] struct { @@ -33,16 +33,17 @@ func (c *ExampleCurveCircuit[B, S]) Define(api frontend.API) error { } func ExampleCurve() { - secpCurve := secp256k1.S256() s := big.NewInt(9) - sx, sy := secpCurve.ScalarMult(secpCurve.Gx, secpCurve.Gy, s.Bytes()) - fmt.Printf("result (%d, %d)", sx, sy) + _, g := secp256k1.Generators() + var Q secp256k1.G1Affine + Q.ScalarMultiplication(&g, s) + fmt.Printf("result (%d, %d)", Q.X, Q.Y) circuit := ExampleCurveCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} witness := ExampleCurveCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ Res: weierstrass.AffinePoint[emulated.Secp256k1Fp]{ - X: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gx), - Y: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gy), + X: emulated.NewElement[emulated.Secp256k1Fp](g.X), + Y: emulated.NewElement[emulated.Secp256k1Fp](g.Y), }, } ccs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) diff --git a/std/algebra/weierstrass/point_test.go b/std/algebra/weierstrass/point_test.go index 7b05a998f4..8c4834eb10 100644 --- a/std/algebra/weierstrass/point_test.go +++ b/std/algebra/weierstrass/point_test.go @@ -6,11 +6,12 @@ import ( "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/consensys/gnark-crypto/ecc/secp256k1" + "github.com/consensys/gnark-crypto/ecc/secp256k1/fp" "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/frontend/cs/r1cs" "github.com/consensys/gnark/std/math/emulated" "github.com/consensys/gnark/test" - "github.com/ethereum/go-ethereum/crypto/secp256k1" ) var testCurve = ecc.BN254 @@ -31,17 +32,18 @@ func (c *NegTest[T, S]) Define(api frontend.API) error { func TestNeg(t *testing.T) { assert := test.NewAssert(t) - secpCurve := secp256k1.S256() - yn := new(big.Int).Sub(secpCurve.P, secpCurve.Gy) + _, g := secp256k1.Generators() + var yn fp.Element + yn.Neg(&g.Y) circuit := NegTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} witness := NegTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ P: AffinePoint[emulated.Secp256k1Fp]{ - X: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gx), - Y: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gy), + X: emulated.NewElement[emulated.Secp256k1Fp](g.X.BigInt(new(big.Int))), + Y: emulated.NewElement[emulated.Secp256k1Fp](g.Y.BigInt(new(big.Int))), }, Q: AffinePoint[emulated.Secp256k1Fp]{ - X: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gx), - Y: emulated.NewElement[emulated.Secp256k1Fp](yn), + X: emulated.NewElement[emulated.Secp256k1Fp](g.X.BigInt(new(big.Int))), + Y: emulated.NewElement[emulated.Secp256k1Fp](yn.BigInt(new(big.Int))), }, } err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) @@ -64,22 +66,27 @@ func (c *AddTest[T, S]) Define(api frontend.API) error { func TestAdd(t *testing.T) { assert := test.NewAssert(t) - secpCurve := secp256k1.S256() - xd, yd := secpCurve.Double(secpCurve.Gx, secpCurve.Gy) - xa, ya := secpCurve.Add(xd, yd, secpCurve.Gx, secpCurve.Gy) + var dJac, aJac secp256k1.G1Jac + g, _ := secp256k1.Generators() + dJac.Double(&g) + aJac.Set(&dJac). + AddAssign(&g) + var dAff, aAff secp256k1.G1Affine + dAff.FromJacobian(&dJac) + aAff.FromJacobian(&aJac) circuit := AddTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} witness := AddTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ P: AffinePoint[emulated.Secp256k1Fp]{ - X: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gx), - Y: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gy), + X: emulated.NewElement[emulated.Secp256k1Fp](g.X.BigInt(new(big.Int))), + Y: emulated.NewElement[emulated.Secp256k1Fp](g.Y.BigInt(new(big.Int))), }, Q: AffinePoint[emulated.Secp256k1Fp]{ - X: emulated.NewElement[emulated.Secp256k1Fp](xd), - Y: emulated.NewElement[emulated.Secp256k1Fp](yd), + X: emulated.NewElement[emulated.Secp256k1Fp](dAff.X.BigInt(new(big.Int))), + Y: emulated.NewElement[emulated.Secp256k1Fp](dAff.Y.BigInt(new(big.Int))), }, R: AffinePoint[emulated.Secp256k1Fp]{ - X: emulated.NewElement[emulated.Secp256k1Fp](xa), - Y: emulated.NewElement[emulated.Secp256k1Fp](ya), + X: emulated.NewElement[emulated.Secp256k1Fp](aAff.X.BigInt(new(big.Int))), + Y: emulated.NewElement[emulated.Secp256k1Fp](aAff.Y.BigInt(new(big.Int))), }, } err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) @@ -102,17 +109,20 @@ func (c *DoubleTest[T, S]) Define(api frontend.API) error { func TestDouble(t *testing.T) { assert := test.NewAssert(t) - secpCurve := secp256k1.S256() - xd, yd := secpCurve.Double(secpCurve.Gx, secpCurve.Gy) + g, _ := secp256k1.Generators() + var dJac secp256k1.G1Jac + dJac.Double(&g) + var dAff secp256k1.G1Affine + dAff.FromJacobian(&dJac) circuit := DoubleTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} witness := DoubleTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ P: AffinePoint[emulated.Secp256k1Fp]{ - X: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gx), - Y: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gy), + X: emulated.NewElement[emulated.Secp256k1Fp](g.X.BigInt(new(big.Int))), + Y: emulated.NewElement[emulated.Secp256k1Fp](g.Y.BigInt(new(big.Int))), }, Q: AffinePoint[emulated.Secp256k1Fp]{ - X: emulated.NewElement[emulated.Secp256k1Fp](xd), - Y: emulated.NewElement[emulated.Secp256k1Fp](yd), + X: emulated.NewElement[emulated.Secp256k1Fp](dAff.X.BigInt(new(big.Int))), + Y: emulated.NewElement[emulated.Secp256k1Fp](dAff.Y.BigInt(new(big.Int))), }, } err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) @@ -136,21 +146,22 @@ func (c *ScalarMulTest[T, S]) Define(api frontend.API) error { func TestScalarMul(t *testing.T) { assert := test.NewAssert(t) - secpCurve := secp256k1.S256() + _, g := secp256k1.Generators() s, ok := new(big.Int).SetString("44693544921776318736021182399461740191514036429448770306966433218654680512345", 10) assert.True(ok) - sx, sy := secpCurve.ScalarMult(secpCurve.Gx, secpCurve.Gy, s.Bytes()) + var S secp256k1.G1Affine + S.ScalarMultiplication(&g, s) circuit := ScalarMulTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} witness := ScalarMulTest[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ S: emulated.NewElement[emulated.Secp256k1Fr](s), P: AffinePoint[emulated.Secp256k1Fp]{ - X: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gx), - Y: emulated.NewElement[emulated.Secp256k1Fp](secpCurve.Gy), + X: emulated.NewElement[emulated.Secp256k1Fp](g.X.BigInt(new(big.Int))), + Y: emulated.NewElement[emulated.Secp256k1Fp](g.Y.BigInt(new(big.Int))), }, Q: AffinePoint[emulated.Secp256k1Fp]{ - X: emulated.NewElement[emulated.Secp256k1Fp](sx), - Y: emulated.NewElement[emulated.Secp256k1Fp](sy), + X: emulated.NewElement[emulated.Secp256k1Fp](S.X.BigInt(new(big.Int))), + Y: emulated.NewElement[emulated.Secp256k1Fp](S.Y.BigInt(new(big.Int))), }, } err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) @@ -171,8 +182,8 @@ func TestScalarMul2(t *testing.T) { witness := ScalarMulTest[emulated.BN254Fp, emulated.BN254Fr]{ S: emulated.NewElement[emulated.BN254Fr](s), P: AffinePoint[emulated.BN254Fp]{ - X: emulated.NewElement[emulated.BN254Fp](gen.X.ToBigIntRegular(new(big.Int))), - Y: emulated.NewElement[emulated.BN254Fp](gen.Y.ToBigIntRegular(new(big.Int))), + X: emulated.NewElement[emulated.BN254Fp](gen.X.BigInt(new(big.Int))), + Y: emulated.NewElement[emulated.BN254Fp](gen.Y.BigInt(new(big.Int))), }, Q: AffinePoint[emulated.BN254Fp]{ X: emulated.NewElement[emulated.BN254Fp](res.X.ToBigIntRegular(new(big.Int))), diff --git a/std/signature/ecdsa/ecdsa_test.go b/std/signature/ecdsa/ecdsa_test.go index 4f5f8474db..076345a777 100644 --- a/std/signature/ecdsa/ecdsa_test.go +++ b/std/signature/ecdsa/ecdsa_test.go @@ -1,30 +1,19 @@ package ecdsa import ( - "math/big" + "crypto/rand" "testing" "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark-crypto/ecc/secp256k1" + "github.com/consensys/gnark-crypto/ecc/secp256k1/ecdsa" + "github.com/consensys/gnark-crypto/ecc/secp256k1/fr" "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/std/algebra/weierstrass" "github.com/consensys/gnark/std/math/emulated" "github.com/consensys/gnark/test" - "github.com/ethereum/go-ethereum/crypto" ) -var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" - -func sign(t *testing.T) ([]byte, []byte, error) { - t.Helper() - key, _ := crypto.HexToECDSA(testPrivHex) - msg := crypto.Keccak256([]byte("foo")) - sig, err := crypto.Sign(msg, key) - if err != nil { - t.Errorf("Sign error: %s", err) - } - return sig, msg, nil -} - type EcdsaCircuit[T, S emulated.FieldParams] struct { Sig Signature[S] Msg emulated.Element[S] @@ -37,48 +26,38 @@ func (c *EcdsaCircuit[T, S]) Define(api frontend.API) error { } func TestEcdsa(t *testing.T) { - // generate a valid signature - sig, msg, err := sign(t) - if err != nil { - t.Fatal(err) - } - // check that the signature is correct - pub, err := crypto.Ecrecover(msg, sig) - if err != nil { - t.Fatal(err) - } - sig = sig[:len(sig)-1] - if !crypto.VerifySignature(pub, msg, sig) { - t.Errorf("can't verify signature with uncompressed key") - } + // generate parameters + _, g := secp256k1.Generators() + var pp ecdsa.Params + pp.Base.Set(&g) + pp.Order = fr.Modulus() + privKey, _ := pp.GenerateKey(rand.Reader) - r := new(big.Int).SetBytes(sig[:32]) - s := new(big.Int).SetBytes(sig[32:]) - m := new(big.Int).SetBytes(msg) + // sign + hash := []byte("testing ECDSA") + sig, _ := pp.Sign(hash, *privKey, rand.Reader) - _pub, err := crypto.UnmarshalPubkey(pub) - if err != nil { - t.Fatal(err) + // check that the signature is correct + if !pp.Verify(hash, sig, privKey.PublicKey.Q) { + t.Errorf("can't verify signature") } circuit := EcdsaCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} witness := EcdsaCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ Sig: Signature[emulated.Secp256k1Fr]{ - R: emulated.NewElement[emulated.Secp256k1Fr](r), - S: emulated.NewElement[emulated.Secp256k1Fr](s), + R: emulated.NewElement[emulated.Secp256k1Fr](sig.R), + S: emulated.NewElement[emulated.Secp256k1Fr](sig.S), }, - Msg: emulated.NewElement[emulated.Secp256k1Fr](m), + Msg: emulated.NewElement[emulated.Secp256k1Fr](hash), Pub: PublicKey[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ - X: emulated.NewElement[emulated.Secp256k1Fp](_pub.X), - Y: emulated.NewElement[emulated.Secp256k1Fp](_pub.Y), + X: emulated.NewElement[emulated.Secp256k1Fp](privKey.PublicKey.Q.X), + Y: emulated.NewElement[emulated.Secp256k1Fp](privKey.PublicKey.Q.Y), }, } assert := test.NewAssert(t) - err = test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField()) + err := test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField()) assert.NoError(err) - // _, err = frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) - // assert.NoError(err) } // Example how to verify the signature inside the circuit. @@ -104,28 +83,20 @@ func ExamplePublicKey_Verify() { // Example how to create a valid signature for secp256k1 func ExamplePublicKey_Verify_create() { - testPrivHex := "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032" - key, _ := crypto.HexToECDSA(testPrivHex) - msg := crypto.Keccak256([]byte("foo")) - sig, err := crypto.Sign(msg, key) - if err != nil { - panic("sign") - } - _pub, err := crypto.Ecrecover(msg, sig) - if err != nil { - panic("ecrecover") - } - sig = sig[:len(sig)-1] - pub, err := crypto.UnmarshalPubkey(_pub) - if err != nil { - panic("unmarshal") - } - r := new(big.Int).SetBytes(sig[:32]) - s := new(big.Int).SetBytes(sig[32:]) - m := new(big.Int).SetBytes(msg) - pubx := pub.X - puby := pub.Y + // generate parameters + _, g := secp256k1.Generators() + var pp ecdsa.Params + pp.Base.Set(&g) + pp.Order = fr.Modulus() + privKey, _ := pp.GenerateKey(rand.Reader) + + // sign + hash := []byte("testing ECDSA") + sig, _ := pp.Sign(hash, *privKey, rand.Reader) + + pubx := privKey.PublicKey.Q.X + puby := privKey.PublicKey.Q.Y // can continue in the PublicKey Verify example - _, _, _, _, _ = r, s, m, pubx, puby + _, _, _, _, _ = sig.R, sig.S, hash, pubx, puby } From f7909b32ffc0170216437db7ee9500aadb40a3a3 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Fri, 20 Jan 2023 18:25:52 +0100 Subject: [PATCH 05/11] fix(ecdsa): rebase on gnark-crypto --- std/signature/ecdsa/ecdsa_test.go | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/std/signature/ecdsa/ecdsa_test.go b/std/signature/ecdsa/ecdsa_test.go index 076345a777..9f4b2f4655 100644 --- a/std/signature/ecdsa/ecdsa_test.go +++ b/std/signature/ecdsa/ecdsa_test.go @@ -5,9 +5,7 @@ import ( "testing" "github.com/consensys/gnark-crypto/ecc" - "github.com/consensys/gnark-crypto/ecc/secp256k1" - "github.com/consensys/gnark-crypto/ecc/secp256k1/ecdsa" - "github.com/consensys/gnark-crypto/ecc/secp256k1/fr" + scheme "github.com/consensys/gnark-crypto/ecc/secp256k1/ecdsa" "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/std/algebra/weierstrass" "github.com/consensys/gnark/std/math/emulated" @@ -28,18 +26,14 @@ func (c *EcdsaCircuit[T, S]) Define(api frontend.API) error { func TestEcdsa(t *testing.T) { // generate parameters - _, g := secp256k1.Generators() - var pp ecdsa.Params - pp.Base.Set(&g) - pp.Order = fr.Modulus() - privKey, _ := pp.GenerateKey(rand.Reader) + privKey, _ := scheme.GenerateKey(rand.Reader) // sign hash := []byte("testing ECDSA") - sig, _ := pp.Sign(hash, *privKey, rand.Reader) + sig, _ := scheme.Sign(hash, *privKey, rand.Reader) // check that the signature is correct - if !pp.Verify(hash, sig, privKey.PublicKey.Q) { + if !scheme.Verify(hash, sig, privKey.PublicKey.Q) { t.Errorf("can't verify signature") } @@ -85,15 +79,11 @@ func ExamplePublicKey_Verify() { func ExamplePublicKey_Verify_create() { // generate parameters - _, g := secp256k1.Generators() - var pp ecdsa.Params - pp.Base.Set(&g) - pp.Order = fr.Modulus() - privKey, _ := pp.GenerateKey(rand.Reader) + privKey, _ := scheme.GenerateKey(rand.Reader) // sign hash := []byte("testing ECDSA") - sig, _ := pp.Sign(hash, *privKey, rand.Reader) + sig, _ := scheme.Sign(hash, *privKey, rand.Reader) pubx := privKey.PublicKey.Q.X puby := privKey.PublicKey.Q.Y From ae39fc29a019c97ef43c2731b19cdd1c180120c3 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Tue, 24 Jan 2023 14:56:41 +0100 Subject: [PATCH 06/11] refactor(test/ecdsa): update following gnark-crypto --- std/signature/ecdsa/ecdsa_test.go | 50 +++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/std/signature/ecdsa/ecdsa_test.go b/std/signature/ecdsa/ecdsa_test.go index 9f4b2f4655..238a317d55 100644 --- a/std/signature/ecdsa/ecdsa_test.go +++ b/std/signature/ecdsa/ecdsa_test.go @@ -2,6 +2,8 @@ package ecdsa import ( "crypto/rand" + "crypto/sha512" + "math/big" "testing" "github.com/consensys/gnark-crypto/ecc" @@ -27,26 +29,44 @@ func TestEcdsa(t *testing.T) { // generate parameters privKey, _ := scheme.GenerateKey(rand.Reader) + publicKey := privKey.PublicKey // sign - hash := []byte("testing ECDSA") - sig, _ := scheme.Sign(hash, *privKey, rand.Reader) + msg := []byte("testing ECDSA") + md := sha512.New() + sigBin, _ := privKey.Sign(msg, md) // check that the signature is correct - if !scheme.Verify(hash, sig, privKey.PublicKey.Q) { + flag, _ := publicKey.Verify(sigBin, msg, md) + if !flag { t.Errorf("can't verify signature") } + // unmarshal signature + var sig scheme.Signature + sig.SetBytes(sigBin) + r, s := new(big.Int), new(big.Int) + r.SetBytes(sig.R[:32]) + s.SetBytes(sig.S[:32]) + + // compute the hash of the message as an integer + dataToHash := make([]byte, len(msg)) + copy(dataToHash[:], msg[:]) + md.Reset() + md.Write(dataToHash[:]) + hramBin := md.Sum(nil) + hash := scheme.HashToInt(hramBin) + circuit := EcdsaCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} witness := EcdsaCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ Sig: Signature[emulated.Secp256k1Fr]{ - R: emulated.NewElement[emulated.Secp256k1Fr](sig.R), - S: emulated.NewElement[emulated.Secp256k1Fr](sig.S), + R: emulated.NewElement[emulated.Secp256k1Fr](r), + S: emulated.NewElement[emulated.Secp256k1Fr](s), }, Msg: emulated.NewElement[emulated.Secp256k1Fr](hash), Pub: PublicKey[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ - X: emulated.NewElement[emulated.Secp256k1Fp](privKey.PublicKey.Q.X), - Y: emulated.NewElement[emulated.Secp256k1Fp](privKey.PublicKey.Q.Y), + X: emulated.NewElement[emulated.Secp256k1Fp](privKey.PublicKey.A.X), + Y: emulated.NewElement[emulated.Secp256k1Fp](privKey.PublicKey.A.Y), }, } assert := test.NewAssert(t) @@ -82,11 +102,17 @@ func ExamplePublicKey_Verify_create() { privKey, _ := scheme.GenerateKey(rand.Reader) // sign - hash := []byte("testing ECDSA") - sig, _ := scheme.Sign(hash, *privKey, rand.Reader) + msg := []byte("testing ECDSA") + md := sha512.New() + sigBin, _ := privKey.Sign(msg, md) + + pubx := privKey.PublicKey.A.X + puby := privKey.PublicKey.A.Y + + // unmarshal signature + var sig scheme.Signature + sig.SetBytes(sigBin) - pubx := privKey.PublicKey.Q.X - puby := privKey.PublicKey.Q.Y // can continue in the PublicKey Verify example - _, _, _, _, _ = sig.R, sig.S, hash, pubx, puby + _, _, _, _, _ = sig.R, sig.S, msg, pubx, puby } From 9abe20c17535afc22bf9400aae8893dd96c7396d Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Wed, 25 Jan 2023 13:42:47 +0100 Subject: [PATCH 07/11] test: ecdsa with pre-hashed message --- std/signature/ecdsa/ecdsa_test.go | 52 ++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/std/signature/ecdsa/ecdsa_test.go b/std/signature/ecdsa/ecdsa_test.go index 238a317d55..0f639516d1 100644 --- a/std/signature/ecdsa/ecdsa_test.go +++ b/std/signature/ecdsa/ecdsa_test.go @@ -2,7 +2,7 @@ package ecdsa import ( "crypto/rand" - "crypto/sha512" + "crypto/sha256" "math/big" "testing" @@ -25,15 +25,57 @@ func (c *EcdsaCircuit[T, S]) Define(api frontend.API) error { return nil } -func TestEcdsa(t *testing.T) { +func TestEcdsaPreHashed(t *testing.T) { // generate parameters privKey, _ := scheme.GenerateKey(rand.Reader) publicKey := privKey.PublicKey // sign - msg := []byte("testing ECDSA") - md := sha512.New() + msg := []byte("testing ECDSA (pre-hashed)") + sigBin, _ := privKey.Sign(msg, nil) + + // check that the signature is correct + flag, _ := publicKey.Verify(sigBin, msg, nil) + if !flag { + t.Errorf("can't verify signature") + } + + // unmarshal signature + var sig scheme.Signature + sig.SetBytes(sigBin) + r, s := new(big.Int), new(big.Int) + r.SetBytes(sig.R[:32]) + s.SetBytes(sig.S[:32]) + + hash := scheme.HashToInt(msg) + + circuit := EcdsaCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} + witness := EcdsaCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ + Sig: Signature[emulated.Secp256k1Fr]{ + R: emulated.NewElement[emulated.Secp256k1Fr](r), + S: emulated.NewElement[emulated.Secp256k1Fr](s), + }, + Msg: emulated.NewElement[emulated.Secp256k1Fr](hash), + Pub: PublicKey[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ + X: emulated.NewElement[emulated.Secp256k1Fp](privKey.PublicKey.A.X), + Y: emulated.NewElement[emulated.Secp256k1Fp](privKey.PublicKey.A.Y), + }, + } + assert := test.NewAssert(t) + err := test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField()) + assert.NoError(err) +} + +func TestEcdsaSHA256(t *testing.T) { + + // generate parameters + privKey, _ := scheme.GenerateKey(rand.Reader) + publicKey := privKey.PublicKey + + // sign + msg := []byte("testing ECDSA (sha256)") + md := sha256.New() sigBin, _ := privKey.Sign(msg, md) // check that the signature is correct @@ -103,7 +145,7 @@ func ExamplePublicKey_Verify_create() { // sign msg := []byte("testing ECDSA") - md := sha512.New() + md := sha256.New() sigBin, _ := privKey.Sign(msg, md) pubx := privKey.PublicKey.A.X From 4de9eb69a9994936aaebe5b95d3ba890066d55ba Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Mon, 6 Feb 2023 14:30:25 +0100 Subject: [PATCH 08/11] feat: gnark-crypto dependency update --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 9ba2c81a81..8e0c23abb3 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/blang/semver/v4 v4.0.0 github.com/consensys/bavard v0.1.13 - github.com/consensys/gnark-crypto v0.9.1-0.20230126211359-1835092d6670 + github.com/consensys/gnark-crypto v0.9.1-0.20230203170247-e77b0919d1aa github.com/ethereum/go-ethereum v1.10.26 github.com/fxamacker/cbor/v2 v2.2.0 github.com/google/go-cmp v0.5.8 diff --git a/go.sum b/go.sum index 1152a9455d..d12d4adca1 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,8 @@ github.com/consensys/gnark-crypto v0.8.1-0.20221220191316-4b7364bddab8 h1:Ij6UQp github.com/consensys/gnark-crypto v0.8.1-0.20221220191316-4b7364bddab8/go.mod h1:CkbdF9hbRidRJYMRzmfX8TMOr95I2pYXRHF18MzRrvA= github.com/consensys/gnark-crypto v0.9.1-0.20230126211359-1835092d6670 h1:AkewHCm7VuiCV3nDxsFVYE8JHPi9RhR6zFq4I6Ha0Fg= github.com/consensys/gnark-crypto v0.9.1-0.20230126211359-1835092d6670/go.mod h1:CkbdF9hbRidRJYMRzmfX8TMOr95I2pYXRHF18MzRrvA= +github.com/consensys/gnark-crypto v0.9.1-0.20230203170247-e77b0919d1aa h1:y9E8TLAKfwpj1uAnxfiUfsK/hOusP2fo2o/BBQiZxEU= +github.com/consensys/gnark-crypto v0.9.1-0.20230203170247-e77b0919d1aa/go.mod h1:CkbdF9hbRidRJYMRzmfX8TMOr95I2pYXRHF18MzRrvA= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From a60b68d1e05c21a160d96e8767afc4e1c2f24f81 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Mon, 6 Feb 2023 14:30:50 +0100 Subject: [PATCH 09/11] refactor: ValueOf takes any integer-like --- std/algebra/weierstrass/point_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/std/algebra/weierstrass/point_test.go b/std/algebra/weierstrass/point_test.go index b68e593bf4..28faf42109 100644 --- a/std/algebra/weierstrass/point_test.go +++ b/std/algebra/weierstrass/point_test.go @@ -182,8 +182,8 @@ func TestScalarMul2(t *testing.T) { witness := ScalarMulTest[emulated.BN254Fp, emulated.BN254Fr]{ S: emulated.ValueOf[emulated.BN254Fr](s), P: AffinePoint[emulated.BN254Fp]{ - X: emulated.ValueOf[emulated.BN254Fp](gen.X.BigInt(new(big.Int))), - Y: emulated.ValueOf[emulated.BN254Fp](gen.Y.BigInt(new(big.Int))), + X: emulated.ValueOf[emulated.BN254Fp](gen.X), + Y: emulated.ValueOf[emulated.BN254Fp](gen.Y), }, Q: AffinePoint[emulated.BN254Fp]{ X: emulated.ValueOf[emulated.BN254Fp](res.X), From 10a4403c0e3db7dd8d5328daaec39cb85d8a4121 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Mon, 6 Feb 2023 14:34:43 +0100 Subject: [PATCH 10/11] chore: remove unused dependencies --- go.mod | 3 --- go.sum | 13 ------------- 2 files changed, 16 deletions(-) diff --git a/go.mod b/go.mod index 8e0c23abb3..5c4b671650 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( github.com/blang/semver/v4 v4.0.0 github.com/consensys/bavard v0.1.13 github.com/consensys/gnark-crypto v0.9.1-0.20230203170247-e77b0919d1aa - github.com/ethereum/go-ethereum v1.10.26 github.com/fxamacker/cbor/v2 v2.2.0 github.com/google/go-cmp v0.5.8 github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1 @@ -17,9 +16,7 @@ require ( ) require ( - github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index d12d4adca1..c73eece722 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,7 @@ 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/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= -github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= 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.8.1-0.20221220191316-4b7364bddab8 h1:Ij6UQpKx4/Ox6L6qFPk8NhEnTsYCEXlILnh+1Hi1grY= -github.com/consensys/gnark-crypto v0.8.1-0.20221220191316-4b7364bddab8/go.mod h1:CkbdF9hbRidRJYMRzmfX8TMOr95I2pYXRHF18MzRrvA= -github.com/consensys/gnark-crypto v0.9.1-0.20230126211359-1835092d6670 h1:AkewHCm7VuiCV3nDxsFVYE8JHPi9RhR6zFq4I6Ha0Fg= -github.com/consensys/gnark-crypto v0.9.1-0.20230126211359-1835092d6670/go.mod h1:CkbdF9hbRidRJYMRzmfX8TMOr95I2pYXRHF18MzRrvA= github.com/consensys/gnark-crypto v0.9.1-0.20230203170247-e77b0919d1aa h1:y9E8TLAKfwpj1uAnxfiUfsK/hOusP2fo2o/BBQiZxEU= github.com/consensys/gnark-crypto v0.9.1-0.20230203170247-e77b0919d1aa/go.mod h1:CkbdF9hbRidRJYMRzmfX8TMOr95I2pYXRHF18MzRrvA= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -16,12 +9,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/ethereum/go-ethereum v1.10.26 h1:i/7d9RBBwiXCEuyduBQzJw/mKmnvzsN14jqBmytw72s= -github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= github.com/fxamacker/cbor/v2 v2.2.0 h1:6eXqdDDe588rSYAi1HfZKbx6YYQO4mxQ9eC6xYpU/JQ= github.com/fxamacker/cbor/v2 v2.2.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= From 61730b033e33ea04ccc0429523301555a867dea9 Mon Sep 17 00:00:00 2001 From: Ivo Kubjas Date: Mon, 6 Feb 2023 14:36:25 +0100 Subject: [PATCH 11/11] refactor: ecdsa package import --- std/signature/ecdsa/ecdsa_test.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/std/signature/ecdsa/ecdsa_test.go b/std/signature/ecdsa/ecdsa_test.go index 42fc91de5c..711ec69554 100644 --- a/std/signature/ecdsa/ecdsa_test.go +++ b/std/signature/ecdsa/ecdsa_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/consensys/gnark-crypto/ecc" - scheme "github.com/consensys/gnark-crypto/ecc/secp256k1/ecdsa" + "github.com/consensys/gnark-crypto/ecc/secp256k1/ecdsa" "github.com/consensys/gnark/frontend" "github.com/consensys/gnark/std/algebra/weierstrass" "github.com/consensys/gnark/std/math/emulated" @@ -28,7 +28,7 @@ func (c *EcdsaCircuit[T, S]) Define(api frontend.API) error { func TestEcdsaPreHashed(t *testing.T) { // generate parameters - privKey, _ := scheme.GenerateKey(rand.Reader) + privKey, _ := ecdsa.GenerateKey(rand.Reader) publicKey := privKey.PublicKey // sign @@ -42,13 +42,13 @@ func TestEcdsaPreHashed(t *testing.T) { } // unmarshal signature - var sig scheme.Signature + var sig ecdsa.Signature sig.SetBytes(sigBin) r, s := new(big.Int), new(big.Int) r.SetBytes(sig.R[:32]) s.SetBytes(sig.S[:32]) - hash := scheme.HashToInt(msg) + hash := ecdsa.HashToInt(msg) circuit := EcdsaCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} witness := EcdsaCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ @@ -70,7 +70,7 @@ func TestEcdsaPreHashed(t *testing.T) { func TestEcdsaSHA256(t *testing.T) { // generate parameters - privKey, _ := scheme.GenerateKey(rand.Reader) + privKey, _ := ecdsa.GenerateKey(rand.Reader) publicKey := privKey.PublicKey // sign @@ -85,7 +85,7 @@ func TestEcdsaSHA256(t *testing.T) { } // unmarshal signature - var sig scheme.Signature + var sig ecdsa.Signature sig.SetBytes(sigBin) r, s := new(big.Int), new(big.Int) r.SetBytes(sig.R[:32]) @@ -97,7 +97,7 @@ func TestEcdsaSHA256(t *testing.T) { md.Reset() md.Write(dataToHash[:]) hramBin := md.Sum(nil) - hash := scheme.HashToInt(hramBin) + hash := ecdsa.HashToInt(hramBin) circuit := EcdsaCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{} witness := EcdsaCircuit[emulated.Secp256k1Fp, emulated.Secp256k1Fr]{ @@ -141,7 +141,7 @@ func ExamplePublicKey_Verify() { func ExamplePublicKey_Verify_create() { // generate parameters - privKey, _ := scheme.GenerateKey(rand.Reader) + privKey, _ := ecdsa.GenerateKey(rand.Reader) // sign msg := []byte("testing ECDSA") @@ -152,7 +152,7 @@ func ExamplePublicKey_Verify_create() { puby := privKey.PublicKey.A.Y // unmarshal signature - var sig scheme.Signature + var sig ecdsa.Signature sig.SetBytes(sigBin) // can continue in the PublicKey Verify example