Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: in-circuit ECDSA on secp256k1 #497

Merged
merged 10 commits into from
Mar 1, 2023
5 changes: 1 addition & 4 deletions std/algebra/weierstrass/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ 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.
approach is the extreme cost of the operations.
*/
package weierstrass
12 changes: 8 additions & 4 deletions std/algebra/weierstrass/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import (
//
// 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
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
Gm [][2]*big.Int // m*base point coords
}

// GetSecp256k1Params returns curve parameters for the curve secp256k1. When
Expand All @@ -30,6 +31,7 @@ func GetSecp256k1Params() CurveParams {
B: big.NewInt(7),
Gx: gx,
Gy: gy,
Gm: computeSecp256k1Table(),
}
}

Expand All @@ -39,11 +41,13 @@ func GetSecp256k1Params() CurveParams {
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,
Gm: computeBN254Table(),
}
}

Expand Down
60 changes: 60 additions & 0 deletions std/algebra/weierstrass/params_compute.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package weierstrass

import (
"math/big"

"github.com/consensys/gnark-crypto/ecc/bn254"
"github.com/consensys/gnark-crypto/ecc/secp256k1"
)

func computeSecp256k1Table() [][2]*big.Int {
Gjac, _ := secp256k1.Generators()
table := make([][2]*big.Int, 256)
tmp := new(secp256k1.G1Jac).Set(&Gjac)
aff := new(secp256k1.G1Affine)
jac := new(secp256k1.G1Jac)
for i := 1; i < 256; i++ {
tmp = tmp.Double(tmp)
switch i {
case 1, 2:
jac.Set(tmp).AddAssign(&Gjac)
aff.FromJacobian(jac)
table[i-1] = [2]*big.Int{aff.X.BigInt(new(big.Int)), aff.Y.BigInt(new(big.Int))}
case 3:
jac.Set(tmp).SubAssign(&Gjac)
aff.FromJacobian(jac)
table[i-1] = [2]*big.Int{aff.X.BigInt(new(big.Int)), aff.Y.BigInt(new(big.Int))}
fallthrough
default:
aff.FromJacobian(tmp)
table[i] = [2]*big.Int{aff.X.BigInt(new(big.Int)), aff.Y.BigInt(new(big.Int))}
}
}
return table[:]
}

func computeBN254Table() [][2]*big.Int {
Gjac, _, _, _ := bn254.Generators()
table := make([][2]*big.Int, 256)
tmp := new(bn254.G1Jac).Set(&Gjac)
aff := new(bn254.G1Affine)
jac := new(bn254.G1Jac)
for i := 1; i < 256; i++ {
tmp = tmp.Double(tmp)
switch i {
case 1, 2:
jac.Set(tmp).AddAssign(&Gjac)
aff.FromJacobian(jac)
table[i-1] = [2]*big.Int{aff.X.BigInt(new(big.Int)), aff.Y.BigInt(new(big.Int))}
case 3:
jac.Set(tmp).SubAssign(&Gjac)
aff.FromJacobian(jac)
table[i-1] = [2]*big.Int{aff.X.BigInt(new(big.Int)), aff.Y.BigInt(new(big.Int))}
fallthrough
default:
aff.FromJacobian(tmp)
table[i] = [2]*big.Int{aff.X.BigInt(new(big.Int)), aff.Y.BigInt(new(big.Int))}
}
}
return table
}
Loading