mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 02:42:27 +00:00
crypto/bls12381: use gnark instead of kilic for bls
This commit is contained in:
parent
00a3896dc5
commit
b6c8158885
1 changed files with 89 additions and 86 deletions
|
|
@ -23,12 +23,15 @@ import (
|
|||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc"
|
||||
bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381/fp"
|
||||
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/blake2b"
|
||||
"github.com/ethereum/go-ethereum/crypto/bls12381"
|
||||
"github.com/ethereum/go-ethereum/crypto/bn256"
|
||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
|
|
@ -673,26 +676,23 @@ func (c *bls12381G1Add) Run(input []byte) ([]byte, error) {
|
|||
return nil, errBLS12381InvalidInputLength
|
||||
}
|
||||
var err error
|
||||
var p0, p1 *bls12381.PointG1
|
||||
|
||||
// Initialize G1
|
||||
g := bls12381.NewG1()
|
||||
var p0, p1 *bls12381.G1Affine
|
||||
|
||||
// Decode G1 point p_0
|
||||
if p0, err = decodePointG1(g, input[:128]); err != nil {
|
||||
if p0, err = decodePointG1(input[:128]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Decode G1 point p_1
|
||||
if p1, err = decodePointG1(g, input[128:]); err != nil {
|
||||
if p1, err = decodePointG1(input[128:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Compute r = p_0 + p_1
|
||||
r := g.New()
|
||||
g.Add(r, p0, p1)
|
||||
r := new(bls12381.G1Affine)
|
||||
r.Add(p0, p1)
|
||||
|
||||
// Encode the G1 point result into 128 bytes
|
||||
return encodePointG1(g, r), nil
|
||||
return encodePointG1(r), nil
|
||||
}
|
||||
|
||||
// bls12381G1Mul implements EIP-2537 G1Mul precompile.
|
||||
|
|
@ -711,24 +711,21 @@ func (c *bls12381G1Mul) Run(input []byte) ([]byte, error) {
|
|||
return nil, errBLS12381InvalidInputLength
|
||||
}
|
||||
var err error
|
||||
var p0 *bls12381.PointG1
|
||||
|
||||
// Initialize G1
|
||||
g := bls12381.NewG1()
|
||||
var p0 *bls12381.G1Affine
|
||||
|
||||
// Decode G1 point
|
||||
if p0, err = decodePointG1(g, input[:128]); err != nil {
|
||||
if p0, err = decodePointG1(input[:128]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Decode scalar value
|
||||
e := new(big.Int).SetBytes(input[128:])
|
||||
|
||||
// Compute r = e * p_0
|
||||
r := g.New()
|
||||
g.MulScalarBig(r, p0, e)
|
||||
r := new(bls12381.G1Affine)
|
||||
r.ScalarMultiplication(p0, e)
|
||||
|
||||
// Encode the G1 point into 128 bytes
|
||||
return encodePointG1(g, r), nil
|
||||
return encodePointG1(r), nil
|
||||
}
|
||||
|
||||
// bls12381G1MultiExp implements EIP-2537 G1MultiExp precompile.
|
||||
|
|
@ -761,31 +758,29 @@ func (c *bls12381G1MultiExp) Run(input []byte) ([]byte, error) {
|
|||
if len(input) == 0 || len(input)%160 != 0 {
|
||||
return nil, errBLS12381InvalidInputLength
|
||||
}
|
||||
var err error
|
||||
points := make([]*bls12381.PointG1, k)
|
||||
scalars := make([]*big.Int, k)
|
||||
|
||||
// Initialize G1
|
||||
g := bls12381.NewG1()
|
||||
points := make([]bls12381.G1Affine, k)
|
||||
scalars := make([]fr.Element, k)
|
||||
|
||||
// Decode point scalar pairs
|
||||
for i := 0; i < k; i++ {
|
||||
off := 160 * i
|
||||
t0, t1, t2 := off, off+128, off+160
|
||||
// Decode G1 point
|
||||
if points[i], err = decodePointG1(g, input[t0:t1]); err != nil {
|
||||
p, err := decodePointG1(input[t0:t1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
points[i] = *p
|
||||
// Decode scalar value
|
||||
scalars[i] = new(big.Int).SetBytes(input[t1:t2])
|
||||
scalars[i] = *new(fr.Element).SetBytes(input[t1:t2])
|
||||
}
|
||||
|
||||
// Compute r = e_0 * p_0 + e_1 * p_1 + ... + e_(k-1) * p_(k-1)
|
||||
r := g.New()
|
||||
g.MultiExpBig(r, points, scalars)
|
||||
r := new(bls12381.G1Affine)
|
||||
r.MultiExp(points, scalars, ecc.MultiExpConfig{})
|
||||
|
||||
// Encode the G1 point to 128 bytes
|
||||
return encodePointG1(g, r), nil
|
||||
return encodePointG1(r), nil
|
||||
}
|
||||
|
||||
// bls12381G2Add implements EIP-2537 G2Add precompile.
|
||||
|
|
@ -804,26 +799,23 @@ func (c *bls12381G2Add) Run(input []byte) ([]byte, error) {
|
|||
return nil, errBLS12381InvalidInputLength
|
||||
}
|
||||
var err error
|
||||
var p0, p1 *bls12381.PointG2
|
||||
|
||||
// Initialize G2
|
||||
g := bls12381.NewG2()
|
||||
r := g.New()
|
||||
var p0, p1 *bls12381.G2Affine
|
||||
|
||||
// Decode G2 point p_0
|
||||
if p0, err = decodePointG2(g, input[:256]); err != nil {
|
||||
if p0, err = decodePointG2(input[:256]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Decode G2 point p_1
|
||||
if p1, err = decodePointG2(g, input[256:]); err != nil {
|
||||
if p1, err = decodePointG2(input[256:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Compute r = p_0 + p_1
|
||||
g.Add(r, p0, p1)
|
||||
r := new(bls12381.G2Affine)
|
||||
r.Add(p0, p1)
|
||||
|
||||
// Encode the G2 point into 256 bytes
|
||||
return encodePointG2(g, r), nil
|
||||
return encodePointG2(r), nil
|
||||
}
|
||||
|
||||
// bls12381G2Mul implements EIP-2537 G2Mul precompile.
|
||||
|
|
@ -842,24 +834,21 @@ func (c *bls12381G2Mul) Run(input []byte) ([]byte, error) {
|
|||
return nil, errBLS12381InvalidInputLength
|
||||
}
|
||||
var err error
|
||||
var p0 *bls12381.PointG2
|
||||
|
||||
// Initialize G2
|
||||
g := bls12381.NewG2()
|
||||
var p0 *bls12381.G2Affine
|
||||
|
||||
// Decode G2 point
|
||||
if p0, err = decodePointG2(g, input[:256]); err != nil {
|
||||
if p0, err = decodePointG2(input[:256]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Decode scalar value
|
||||
e := new(big.Int).SetBytes(input[256:])
|
||||
|
||||
// Compute r = e * p_0
|
||||
r := g.New()
|
||||
g.MulScalarBig(r, p0, e)
|
||||
r := new(bls12381.G2Affine)
|
||||
r.ScalarMultiplication(p0, e)
|
||||
|
||||
// Encode the G2 point into 256 bytes
|
||||
return encodePointG2(g, r), nil
|
||||
return encodePointG2(r), nil
|
||||
}
|
||||
|
||||
// bls12381G2MultiExp implements EIP-2537 G2MultiExp precompile.
|
||||
|
|
@ -892,31 +881,29 @@ func (c *bls12381G2MultiExp) Run(input []byte) ([]byte, error) {
|
|||
if len(input) == 0 || len(input)%288 != 0 {
|
||||
return nil, errBLS12381InvalidInputLength
|
||||
}
|
||||
var err error
|
||||
points := make([]*bls12381.PointG2, k)
|
||||
scalars := make([]*big.Int, k)
|
||||
|
||||
// Initialize G2
|
||||
g := bls12381.NewG2()
|
||||
points := make([]bls12381.G2Affine, k)
|
||||
scalars := make([]fr.Element, k)
|
||||
|
||||
// Decode point scalar pairs
|
||||
for i := 0; i < k; i++ {
|
||||
off := 288 * i
|
||||
t0, t1, t2 := off, off+256, off+288
|
||||
// Decode G2 point
|
||||
if points[i], err = decodePointG2(g, input[t0:t1]); err != nil {
|
||||
p, err := decodePointG2(input[t0:t1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
points[i] = *p
|
||||
// Decode scalar value
|
||||
scalars[i] = new(big.Int).SetBytes(input[t1:t2])
|
||||
scalars[i] = *new(fr.Element).SetBytes(input[t1:t2])
|
||||
}
|
||||
|
||||
// Compute r = e_0 * p_0 + e_1 * p_1 + ... + e_(k-1) * p_(k-1)
|
||||
r := g.New()
|
||||
g.MultiExpBig(r, points, scalars)
|
||||
r := new(bls12381.G2Affine)
|
||||
r.MultiExp(points, scalars, ecc.MultiExpConfig{})
|
||||
|
||||
// Encode the G2 point to 256 bytes.
|
||||
return encodePointG2(g, r), nil
|
||||
return encodePointG2(r), nil
|
||||
}
|
||||
|
||||
// bls12381Pairing implements EIP-2537 Pairing precompile.
|
||||
|
|
@ -939,9 +926,10 @@ func (c *bls12381Pairing) Run(input []byte) ([]byte, error) {
|
|||
return nil, errBLS12381InvalidInputLength
|
||||
}
|
||||
|
||||
// Initialize BLS12-381 pairing engine
|
||||
e := bls12381.NewEngine()
|
||||
g1, g2 := e.G1, e.G2
|
||||
var (
|
||||
p []bls12381.G1Affine
|
||||
q []bls12381.G2Affine
|
||||
)
|
||||
|
||||
// Decode pairs
|
||||
for i := 0; i < k; i++ {
|
||||
|
|
@ -949,39 +937,39 @@ func (c *bls12381Pairing) Run(input []byte) ([]byte, error) {
|
|||
t0, t1, t2 := off, off+128, off+384
|
||||
|
||||
// Decode G1 point
|
||||
p1, err := decodePointG1(g1, input[t0:t1])
|
||||
p1, err := decodePointG1(input[t0:t1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Decode G2 point
|
||||
p2, err := decodePointG2(g2, input[t1:t2])
|
||||
p2, err := decodePointG2(input[t1:t2])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 'point is on curve' check already done,
|
||||
// Here we need to apply subgroup checks.
|
||||
if !g1.InCorrectSubgroup(p1) {
|
||||
if !p1.IsInSubGroup() {
|
||||
return nil, errBLS12381G1PointSubgroup
|
||||
}
|
||||
if !g2.InCorrectSubgroup(p2) {
|
||||
if !p2.IsInSubGroup() {
|
||||
return nil, errBLS12381G2PointSubgroup
|
||||
}
|
||||
|
||||
// Update pairing engine with G1 and G2 points
|
||||
e.AddPair(p1, p2)
|
||||
p = append(p, *p1)
|
||||
q = append(q, *p2)
|
||||
}
|
||||
// Prepare 32 byte output
|
||||
out := make([]byte, 32)
|
||||
|
||||
// Compute pairing and set the result
|
||||
if e.Check() {
|
||||
ok, err := bls12381.PairingCheck(p, q)
|
||||
if err == nil && ok {
|
||||
out[31] = 1
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func decodePointG1(g *bls12381.G1, in []byte) (*bls12381.PointG1, error) {
|
||||
func decodePointG1(in []byte) (*bls12381.G1Affine, error) {
|
||||
if len(in) != 128 {
|
||||
return nil, errors.New("invalid g1 point length")
|
||||
}
|
||||
|
|
@ -998,11 +986,14 @@ func decodePointG1(g *bls12381.G1, in []byte) (*bls12381.PointG1, error) {
|
|||
}
|
||||
copy(pointBytes[:48], xBytes)
|
||||
copy(pointBytes[48:], yBytes)
|
||||
return g.FromBytes(pointBytes)
|
||||
|
||||
p := new(bls12381.G1Affine)
|
||||
p.SetBytes(pointBytes)
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// decodePointG2 given encoded (x, y) coordinates in 256 bytes returns a valid G2 Point.
|
||||
func decodePointG2(g *bls12381.G2, in []byte) (*bls12381.PointG2, error) {
|
||||
func decodePointG2(in []byte) (*bls12381.G2Affine, error) {
|
||||
if len(in) != 256 {
|
||||
return nil, errors.New("invalid g2 point length")
|
||||
}
|
||||
|
|
@ -1027,7 +1018,9 @@ func decodePointG2(g *bls12381.G2, in []byte) (*bls12381.PointG2, error) {
|
|||
copy(pointBytes[48:96], x0Bytes)
|
||||
copy(pointBytes[96:144], y1Bytes)
|
||||
copy(pointBytes[144:192], y0Bytes)
|
||||
return g.FromBytes(pointBytes)
|
||||
p := new(bls12381.G2Affine)
|
||||
p.SetBytes(pointBytes)
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// decodeBLS12381FieldElement decodes BLS12-381 elliptic curve field element.
|
||||
|
|
@ -1048,8 +1041,12 @@ func decodeBLS12381FieldElement(in []byte) ([]byte, error) {
|
|||
}
|
||||
|
||||
// encodePointG1 encodes a point into 128 bytes.
|
||||
func encodePointG1(g *bls12381.G1, p *bls12381.PointG1) []byte {
|
||||
outRaw := g.ToBytes(p)
|
||||
func encodePointG1(p *bls12381.G1Affine) []byte {
|
||||
outRaw := p.RawBytes()
|
||||
if p.IsInfinity() {
|
||||
// gnark sets a weird byte if the point is at infinity, remove it
|
||||
outRaw[0] = 0
|
||||
}
|
||||
out := make([]byte, 128)
|
||||
// encode x
|
||||
copy(out[16:], outRaw[:48])
|
||||
|
|
@ -1059,9 +1056,13 @@ func encodePointG1(g *bls12381.G1, p *bls12381.PointG1) []byte {
|
|||
}
|
||||
|
||||
// encodePointG2 encodes a point into 256 bytes.
|
||||
func encodePointG2(g *bls12381.G2, p *bls12381.PointG2) []byte {
|
||||
// outRaw is 96 bytes
|
||||
outRaw := g.ToBytes(p)
|
||||
func encodePointG2(p *bls12381.G2Affine) []byte {
|
||||
// outRaw is 192 bytes
|
||||
outRaw := p.RawBytes()
|
||||
if p.IsInfinity() {
|
||||
// gnark sets a weird byte if the point is at infinity, remove it
|
||||
outRaw[0] = 0
|
||||
}
|
||||
out := make([]byte, 256)
|
||||
// encode x
|
||||
copy(out[16:16+48], outRaw[48:96])
|
||||
|
|
@ -1093,18 +1094,16 @@ func (c *bls12381MapG1) Run(input []byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Initialize G1
|
||||
g := bls12381.NewG1()
|
||||
elem := new(fp.Element).SetBytes(fe)
|
||||
|
||||
// Compute mapping
|
||||
r, err := g.MapToCurve(fe)
|
||||
r := bls12381.MapToG1(*elem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Encode the G1 point to 128 bytes
|
||||
return encodePointG1(g, r), nil
|
||||
return encodePointG1(&r), nil
|
||||
}
|
||||
|
||||
// bls12381MapG2 implements EIP-2537 MapG2 precompile.
|
||||
|
|
@ -1136,17 +1135,21 @@ func (c *bls12381MapG2) Run(input []byte) ([]byte, error) {
|
|||
}
|
||||
copy(fe[:48], c1)
|
||||
|
||||
// Initialize G2
|
||||
g := bls12381.NewG2()
|
||||
// TODO rework once https://github.com/Consensys/gnark-crypto/issues/483 is solved
|
||||
|
||||
s0 := new(big.Int).SetBytes(c0)
|
||||
s1 := new(big.Int).SetBytes(c1)
|
||||
|
||||
elem := new(bls12381.E2).SetString(s0.String(), s1.String())
|
||||
|
||||
// Compute mapping
|
||||
r, err := g.MapToCurve(fe)
|
||||
r := bls12381.MapToG2(*elem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Encode the G2 point to 256 bytes
|
||||
return encodePointG2(g, r), nil
|
||||
return encodePointG2(&r), nil
|
||||
}
|
||||
|
||||
// kzgPointEvaluation implements the EIP-4844 point evaluation precompile.
|
||||
|
|
|
|||
Loading…
Reference in a new issue