Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions std/algebra/emulated/sw_bls12381/g2.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,19 @@ func (g2 *G2) scalarMulGeneric(p *G2Affine, s *Scalar, opts ...algopts.AlgebraOp
return R0
}

// ScalarMul computes [s]Q using an efficient endomorphism and returns it. It doesn't modify Q nor s.
// It implements an optimized version based on algorithm 1 of [Halo] (see Section 6.2 and appendix C).
//
// ⚠️ The scalar s must be nonzero and the point Q different from (0,0) unless [algopts.WithCompleteArithmetic] is set.
// (0,0) is not on the curve but we conventionally take it as the
// neutral/infinity point as per the [EVM].
//
// [Halo]: https://eprint.iacr.org/2019/1021.pdf
// [EVM]: https://ethereum.github.io/yellowpaper/paper.pdf
func (g2 *G2) ScalarMul(Q *G2Affine, s *Scalar, opts ...algopts.AlgebraOption) *G2Affine {
return g2.scalarMulGLV(Q, s, opts...)
}

// scalarMulGLV computes [s]Q using an efficient endomorphism and returns it. It doesn't modify Q nor s.
// It implements an optimized version based on algorithm 1 of [Halo] (see Section 6.2 and appendix C).
//
Expand Down
6 changes: 4 additions & 2 deletions std/evmprecompiles/11-blsg1add.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
// ECAddG1BLS implements [BLS12_G1ADD] precompile contract at address 0x0b.
//
// [BLS12_G1ADD]: https://eips.ethereum.org/EIPS/eip-2537
func ECAddG1BLS(api frontend.API, P, Q *sw_emulated.AffinePoint[emulated.BLS12381Fp]) *sw_emulated.AffinePoint[emulated.BLS12381Fp] {
func ECAddG1BLS(api frontend.API, P, Q, expected *sw_emulated.AffinePoint[emulated.BLS12381Fp]) {
curve, err := sw_emulated.New[emulated.BLS12381Fp, emulated.BLS12381Fr](api, sw_emulated.GetBLS12381Params())
if err != nil {
panic(err)
Expand All @@ -21,5 +21,7 @@ func ECAddG1BLS(api frontend.API, P, Q *sw_emulated.AffinePoint[emulated.BLS1238

// We use AddUnified because P can be equal to Q, -Q and either or both can be (0,0)
res := curve.AddUnified(P, Q)
return res

// Check that the result is equal to the expected value
curve.AssertIsEqual(res, expected)
}
35 changes: 18 additions & 17 deletions std/evmprecompiles/12-blsg1msm.go
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
package evmprecompiles

import (
"fmt"

"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/algebra/algopts"
"github.com/consensys/gnark/std/algebra/emulated/sw_bls12381"
"github.com/consensys/gnark/std/algebra/emulated/sw_emulated"
"github.com/consensys/gnark/std/math/emulated"
)

// ECMSMG1BLS implements [BLS12_G1MSM] precompile contract at address 0x0c.
// ECG1ScalarMulSumBLS computes the scalar multiplication of a point P by a
// scalar s, adds it to a previous point prev, and checks that the result is
// equal to expected. It is used to implement the [BLS12_G1MSM] precompile
// contract at address 0x0c.
//
// [BLS12_G1MSM]: https://eips.ethereum.org/EIPS/eip-2537
func ECMSMG1BLS(api frontend.API, P []*sw_emulated.AffinePoint[emulated.BLS12381Fp], s []*emulated.Element[emulated.BLS12381Fr]) *sw_emulated.AffinePoint[emulated.BLS12381Fp] {
func ECG1ScalarMulSumBLS(api frontend.API, prev, P *sw_bls12381.G1Affine, s *emulated.Element[sw_bls12381.ScalarField], expected *sw_bls12381.G1Affine) error {
curve, err := sw_emulated.New[emulated.BLS12381Fp, emulated.BLS12381Fr](api, sw_emulated.GetBLS12381Params())
if err != nil {
panic(err)
return fmt.Errorf("new curve: %w", err)
}
g1, err := sw_bls12381.NewG1(api)
if err != nil {
panic(err)
}

// Check that Pᵢ are on G1
for _, p := range P {
g1.AssertIsOnG1(p)
return fmt.Errorf("new G1: %w", err)
}

// Compute the MSM
res, err := curve.MultiScalarMul(P, s, algopts.WithCompleteArithmetic())
if err != nil {
panic(err)
}

return res
// Check the point is in G1
g1.AssertIsOnG1(P)
// Compute the scalar multiplication
res := curve.ScalarMul(P, s, algopts.WithCompleteArithmetic())
// Compute the aggregate
sum := curve.AddUnified(prev, res)
// Assert that the sum is as expected
g1.AssertIsEqual(sum, expected)
return nil
}
6 changes: 4 additions & 2 deletions std/evmprecompiles/13-blsg2add.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
// ECAddG2BLS implements [BLS12_G2ADD] precompile contract at address 0x0d.
//
// [BLS12_G2ADD]: https://eips.ethereum.org/EIPS/eip-2537
func ECAddG2BLS(api frontend.API, P, Q *sw_bls12381.G2Affine) *sw_bls12381.G2Affine {
func ECAddG2BLS(api frontend.API, P, Q, expected *sw_bls12381.G2Affine) {
g2, err := sw_bls12381.NewG2(api)
if err != nil {
panic(err)
Expand All @@ -21,5 +21,7 @@ func ECAddG2BLS(api frontend.API, P, Q *sw_bls12381.G2Affine) *sw_bls12381.G2Aff

// We use AddUnified because P can be equal to Q, -Q and either or both can be (0,0)
res := g2.AddUnified(P, Q)
return res

// Check that the result is equal to the expected value
g2.AssertIsEqual(res, expected)
}
35 changes: 18 additions & 17 deletions std/evmprecompiles/14-blsg2msm.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
package evmprecompiles

import (
"fmt"

"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/algebra/algopts"
"github.com/consensys/gnark/std/algebra/emulated/sw_bls12381"
"github.com/consensys/gnark/std/math/emulated"
)

// ECMSMG2BLS implements [BLS12_G2MSM] precompile contract at address 0x0e.
// ECG2ScalarMulSumBLS computes the scalar multiplication of a point P by a
// scalar s in G2, adds it to a previous point prev, and checks that the result
// is equal to expected. It is used to implement the [BLS12_G2MSM] precompile
// contract at address 0x0e.
//
// [BLS12_G2MSM]: https://eips.ethereum.org/EIPS/eip-2537
func ECMSMG2BLS(api frontend.API, P []*sw_bls12381.G2Affine, s []*emulated.Element[emulated.BLS12381Fr]) *sw_bls12381.G2Affine {
// [BLS12_G1MSM]: https://eips.ethereum.org/EIPS/eip-2537
func ECG2ScalarMulSumBLS(api frontend.API, prev, Q *sw_bls12381.G2Affine, s *emulated.Element[sw_bls12381.ScalarField], expected *sw_bls12381.G2Affine) error {
g2, err := sw_bls12381.NewG2(api)
if err != nil {
panic(err)
}

// Check that Pᵢ are on G2
for _, p := range P {
g2.AssertIsOnG2(p)
return fmt.Errorf("new G2: %w", err)
}

// Compute the MSM
res, err := g2.MultiScalarMul(P, s, algopts.WithCompleteArithmetic())
if err != nil {
panic(err)
}

return res
// Check the point is in G2
g2.AssertIsOnG2(Q)
// Compute the scalar multiplication
res := g2.ScalarMul(Q, s, algopts.WithCompleteArithmetic())
// Compute the aggregate
sum := g2.AddUnified(prev, res)
// Assert that the sum is as expected
g2.AssertIsEqual(sum, expected)
return nil
}
14 changes: 8 additions & 6 deletions std/evmprecompiles/16-blsmaptog1.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package evmprecompiles

import (
"fmt"

"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/algebra/emulated/sw_bls12381"
"github.com/consensys/gnark/std/algebra/emulated/sw_emulated"
Expand All @@ -10,16 +12,16 @@ import (
// ECMapToG1BLS implements [BLS12_MAP_FP_TO_G1] precompile contract at address 0x10.
//
// [ECMapToG1BLS]: https://eips.ethereum.org/EIPS/eip-2537
func ECMapToG1BLS(api frontend.API, u *emulated.Element[emulated.BLS12381Fp]) *sw_emulated.AffinePoint[emulated.BLS12381Fp] {
func ECMapToG1BLS(api frontend.API, P *emulated.Element[emulated.BLS12381Fp], expected *sw_emulated.AffinePoint[emulated.BLS12381Fp]) error {
g, err := sw_bls12381.NewG1(api)
if err != nil {
panic(err)
return fmt.Errorf("new G1: %w", err)
}
res, err := g.MapToG1(u)
res, err := g.MapToG1(P)
if err != nil {
panic(err)
return fmt.Errorf("map to G1: %w", err)
}
g.AssertIsEqual(res, expected)

return res

return nil
}
11 changes: 7 additions & 4 deletions std/evmprecompiles/17-blsmaptog2.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package evmprecompiles

import (
"fmt"

"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/algebra/emulated/fields_bls12381"
"github.com/consensys/gnark/std/algebra/emulated/sw_bls12381"
Expand All @@ -9,14 +11,15 @@ import (
// ECMapToG2BLS implements [BLS12_MAP_FP2_TO_G2] precompile contract at address 0x11.
//
// [ECMapToG2BLS]: https://eips.ethereum.org/EIPS/eip-2537
func ECMapToG2BLS(api frontend.API, u *fields_bls12381.E2) *sw_bls12381.G2Affine {
func ECMapToG2BLS(api frontend.API, u *fields_bls12381.E2, expected *sw_bls12381.G2Affine) error {
g, err := sw_bls12381.NewG2(api)
if err != nil {
panic(err)
return fmt.Errorf("new G2: %w", err)
}
res, err := g.MapToG2(u)
if err != nil {
panic(err)
return fmt.Errorf("map to G2: %w", err)
}
return res
g.AssertIsEqual(res, expected)
return nil
}
Loading