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

Core: EIP-2537 spec updates #30978

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
102 changes: 12 additions & 90 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,12 @@ var PrecompiledContractsPrague = PrecompiledContracts{
common.BytesToAddress([]byte{0x09}): &blake2F{},
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},
common.BytesToAddress([]byte{0x0b}): &bls12381G1Add{},
common.BytesToAddress([]byte{0x0c}): &bls12381G1Mul{},
common.BytesToAddress([]byte{0x0d}): &bls12381G1MultiExp{},
common.BytesToAddress([]byte{0x0e}): &bls12381G2Add{},
common.BytesToAddress([]byte{0x0f}): &bls12381G2Mul{},
common.BytesToAddress([]byte{0x10}): &bls12381G2MultiExp{},
common.BytesToAddress([]byte{0x11}): &bls12381Pairing{},
common.BytesToAddress([]byte{0x12}): &bls12381MapG1{},
common.BytesToAddress([]byte{0x13}): &bls12381MapG2{},
common.BytesToAddress([]byte{0x0c}): &bls12381G1MultiExp{},
common.BytesToAddress([]byte{0x0d}): &bls12381G2Add{},
common.BytesToAddress([]byte{0x0e}): &bls12381G2MultiExp{},
common.BytesToAddress([]byte{0x0f}): &bls12381Pairing{},
common.BytesToAddress([]byte{0x10}): &bls12381MapG1{},
common.BytesToAddress([]byte{0x11}): &bls12381MapG2{},
}

var PrecompiledContractsBLS = PrecompiledContractsPrague
Expand Down Expand Up @@ -750,44 +748,6 @@ func (c *bls12381G1Add) Run(input []byte) ([]byte, error) {
return encodePointG1(p0), nil
}

// bls12381G1Mul implements EIP-2537 G1Mul precompile.
type bls12381G1Mul struct{}

// RequiredGas returns the gas required to execute the pre-compiled contract.
func (c *bls12381G1Mul) RequiredGas(input []byte) uint64 {
return params.Bls12381G1MulGas
}

func (c *bls12381G1Mul) Run(input []byte) ([]byte, error) {
// Implements EIP-2537 G1Mul precompile.
// > G1 multiplication call expects `160` bytes as an input that is interpreted as byte concatenation of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` bytes).
// > Output is an encoding of multiplication operation result - single G1 point (`128` bytes).
if len(input) != 160 {
return nil, errBLS12381InvalidInputLength
}
var err error
var p0 *bls12381.G1Affine

// Decode G1 point
if p0, err = decodePointG1(input[:128]); err != nil {
return nil, err
}
// 'point is on curve' check already done,
// Here we need to apply subgroup checks.
if !p0.IsInSubGroup() {
return nil, errBLS12381G1PointSubgroup
}
// Decode scalar value
e := new(big.Int).SetBytes(input[128:])

// Compute r = e * p_0
r := new(bls12381.G1Affine)
r.ScalarMultiplication(p0, e)

// Encode the G1 point into 128 bytes
return encodePointG1(r), nil
}

// bls12381G1MultiExp implements EIP-2537 G1MultiExp precompile.
type bls12381G1MultiExp struct{}

Expand All @@ -801,10 +761,10 @@ func (c *bls12381G1MultiExp) RequiredGas(input []byte) uint64 {
}
// Lookup discount value for G1 point, scalar value pair length
var discount uint64
if dLen := len(params.Bls12381MultiExpDiscountTable); k < dLen {
discount = params.Bls12381MultiExpDiscountTable[k-1]
if dLen := len(params.Bls12381G1MultiExpDiscountTable); k < dLen {
discount = params.Bls12381G1MultiExpDiscountTable[k-1]
} else {
discount = params.Bls12381MultiExpDiscountTable[dLen-1]
discount = params.Bls12381G1MultiExpDiscountTable[dLen-1]
}
// Calculate gas and return the result
return (uint64(k) * params.Bls12381G1MulGas * discount) / 1000
Expand Down Expand Up @@ -885,44 +845,6 @@ func (c *bls12381G2Add) Run(input []byte) ([]byte, error) {
return encodePointG2(r), nil
}

// bls12381G2Mul implements EIP-2537 G2Mul precompile.
type bls12381G2Mul struct{}

// RequiredGas returns the gas required to execute the pre-compiled contract.
func (c *bls12381G2Mul) RequiredGas(input []byte) uint64 {
return params.Bls12381G2MulGas
}

func (c *bls12381G2Mul) Run(input []byte) ([]byte, error) {
// Implements EIP-2537 G2MUL precompile logic.
// > G2 multiplication call expects `288` bytes as an input that is interpreted as byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes).
// > Output is an encoding of multiplication operation result - single G2 point (`256` bytes).
if len(input) != 288 {
return nil, errBLS12381InvalidInputLength
}
var err error
var p0 *bls12381.G2Affine

// Decode G2 point
if p0, err = decodePointG2(input[:256]); err != nil {
return nil, err
}
// 'point is on curve' check already done,
// Here we need to apply subgroup checks.
if !p0.IsInSubGroup() {
return nil, errBLS12381G2PointSubgroup
}
// Decode scalar value
e := new(big.Int).SetBytes(input[256:])

// Compute r = e * p_0
r := new(bls12381.G2Affine)
r.ScalarMultiplication(p0, e)

// Encode the G2 point into 256 bytes
return encodePointG2(r), nil
}

// bls12381G2MultiExp implements EIP-2537 G2MultiExp precompile.
type bls12381G2MultiExp struct{}

Expand All @@ -936,10 +858,10 @@ func (c *bls12381G2MultiExp) RequiredGas(input []byte) uint64 {
}
// Lookup discount value for G2 point, scalar value pair length
var discount uint64
if dLen := len(params.Bls12381MultiExpDiscountTable); k < dLen {
discount = params.Bls12381MultiExpDiscountTable[k-1]
if dLen := len(params.Bls12381G2MultiExpDiscountTable); k < dLen {
discount = params.Bls12381G2MultiExpDiscountTable[k-1]
} else {
discount = params.Bls12381MultiExpDiscountTable[dLen-1]
discount = params.Bls12381G2MultiExpDiscountTable[dLen-1]
}
// Calculate gas and return the result
return (uint64(k) * params.Bls12381G2MulGas * discount) / 1000
Expand Down
56 changes: 24 additions & 32 deletions core/vm/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,12 @@ var allPrecompiles = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{},

common.BytesToAddress([]byte{0x0f, 0x0a}): &bls12381G1Add{},
common.BytesToAddress([]byte{0x0f, 0x0b}): &bls12381G1Mul{},
common.BytesToAddress([]byte{0x0f, 0x0c}): &bls12381G1MultiExp{},
common.BytesToAddress([]byte{0x0f, 0x0d}): &bls12381G2Add{},
common.BytesToAddress([]byte{0x0f, 0x0e}): &bls12381G2Mul{},
common.BytesToAddress([]byte{0x0f, 0x0f}): &bls12381G2MultiExp{},
common.BytesToAddress([]byte{0x0f, 0x10}): &bls12381Pairing{},
common.BytesToAddress([]byte{0x0f, 0x11}): &bls12381MapG1{},
common.BytesToAddress([]byte{0x0f, 0x12}): &bls12381MapG2{},
common.BytesToAddress([]byte{0x0f, 0x0b}): &bls12381G1MultiExp{},
common.BytesToAddress([]byte{0x0f, 0x0c}): &bls12381G2Add{},
common.BytesToAddress([]byte{0x0f, 0x0d}): &bls12381G2MultiExp{},
common.BytesToAddress([]byte{0x0f, 0x0e}): &bls12381Pairing{},
common.BytesToAddress([]byte{0x0f, 0x0f}): &bls12381MapG1{},
common.BytesToAddress([]byte{0x0f, 0x10}): &bls12381MapG2{},
}

// EIP-152 test vectors
Expand Down Expand Up @@ -305,39 +303,33 @@ func benchJson(name, addr string, b *testing.B) {
}

func TestPrecompiledBLS12381G1Add(t *testing.T) { testJson("blsG1Add", "f0a", t) }
func TestPrecompiledBLS12381G1Mul(t *testing.T) { testJson("blsG1Mul", "f0b", t) }
func TestPrecompiledBLS12381G1MultiExp(t *testing.T) { testJson("blsG1MultiExp", "f0c", t) }
func TestPrecompiledBLS12381G2Add(t *testing.T) { testJson("blsG2Add", "f0d", t) }
func TestPrecompiledBLS12381G2Mul(t *testing.T) { testJson("blsG2Mul", "f0e", t) }
func TestPrecompiledBLS12381G2MultiExp(t *testing.T) { testJson("blsG2MultiExp", "f0f", t) }
func TestPrecompiledBLS12381Pairing(t *testing.T) { testJson("blsPairing", "f10", t) }
func TestPrecompiledBLS12381MapG1(t *testing.T) { testJson("blsMapG1", "f11", t) }
func TestPrecompiledBLS12381MapG2(t *testing.T) { testJson("blsMapG2", "f12", t) }
func TestPrecompiledBLS12381G1MultiExp(t *testing.T) { testJson("blsG1MultiExp", "f0b", t) }
func TestPrecompiledBLS12381G2Add(t *testing.T) { testJson("blsG2Add", "f0c", t) }
func TestPrecompiledBLS12381G2MultiExp(t *testing.T) { testJson("blsG2MultiExp", "f0d", t) }
func TestPrecompiledBLS12381Pairing(t *testing.T) { testJson("blsPairing", "f0e", t) }
func TestPrecompiledBLS12381MapG1(t *testing.T) { testJson("blsMapG1", "f0f", t) }
func TestPrecompiledBLS12381MapG2(t *testing.T) { testJson("blsMapG2", "f10", t) }

func TestPrecompiledPointEvaluation(t *testing.T) { testJson("pointEvaluation", "0a", t) }

func BenchmarkPrecompiledPointEvaluation(b *testing.B) { benchJson("pointEvaluation", "0a", b) }

func BenchmarkPrecompiledBLS12381G1Add(b *testing.B) { benchJson("blsG1Add", "f0a", b) }
func BenchmarkPrecompiledBLS12381G1Mul(b *testing.B) { benchJson("blsG1Mul", "f0b", b) }
func BenchmarkPrecompiledBLS12381G1MultiExp(b *testing.B) { benchJson("blsG1MultiExp", "f0c", b) }
func BenchmarkPrecompiledBLS12381G2Add(b *testing.B) { benchJson("blsG2Add", "f0d", b) }
func BenchmarkPrecompiledBLS12381G2Mul(b *testing.B) { benchJson("blsG2Mul", "f0e", b) }
func BenchmarkPrecompiledBLS12381G2MultiExp(b *testing.B) { benchJson("blsG2MultiExp", "f0f", b) }
func BenchmarkPrecompiledBLS12381Pairing(b *testing.B) { benchJson("blsPairing", "f10", b) }
func BenchmarkPrecompiledBLS12381MapG1(b *testing.B) { benchJson("blsMapG1", "f11", b) }
func BenchmarkPrecompiledBLS12381MapG2(b *testing.B) { benchJson("blsMapG2", "f12", b) }
func BenchmarkPrecompiledBLS12381G1MultiExp(b *testing.B) { benchJson("blsG1MultiExp", "f0b", b) }
func BenchmarkPrecompiledBLS12381G2Add(b *testing.B) { benchJson("blsG2Add", "f0c", b) }
func BenchmarkPrecompiledBLS12381G2MultiExp(b *testing.B) { benchJson("blsG2MultiExp", "f0d", b) }
func BenchmarkPrecompiledBLS12381Pairing(b *testing.B) { benchJson("blsPairing", "f0e", b) }
func BenchmarkPrecompiledBLS12381MapG1(b *testing.B) { benchJson("blsMapG1", "f0f", b) }
func BenchmarkPrecompiledBLS12381MapG2(b *testing.B) { benchJson("blsMapG2", "f10", b) }

// Failure tests
func TestPrecompiledBLS12381G1AddFail(t *testing.T) { testJsonFail("blsG1Add", "f0a", t) }
func TestPrecompiledBLS12381G1MulFail(t *testing.T) { testJsonFail("blsG1Mul", "f0b", t) }
func TestPrecompiledBLS12381G1MultiExpFail(t *testing.T) { testJsonFail("blsG1MultiExp", "f0c", t) }
func TestPrecompiledBLS12381G2AddFail(t *testing.T) { testJsonFail("blsG2Add", "f0d", t) }
func TestPrecompiledBLS12381G2MulFail(t *testing.T) { testJsonFail("blsG2Mul", "f0e", t) }
func TestPrecompiledBLS12381G2MultiExpFail(t *testing.T) { testJsonFail("blsG2MultiExp", "f0f", t) }
func TestPrecompiledBLS12381PairingFail(t *testing.T) { testJsonFail("blsPairing", "f10", t) }
func TestPrecompiledBLS12381MapG1Fail(t *testing.T) { testJsonFail("blsMapG1", "f11", t) }
func TestPrecompiledBLS12381MapG2Fail(t *testing.T) { testJsonFail("blsMapG2", "f12", t) }
func TestPrecompiledBLS12381G1MultiExpFail(t *testing.T) { testJsonFail("blsG1MultiExp", "f0b", t) }
func TestPrecompiledBLS12381G2AddFail(t *testing.T) { testJsonFail("blsG2Add", "f0c", t) }
func TestPrecompiledBLS12381G2MultiExpFail(t *testing.T) { testJsonFail("blsG2MultiExp", "f0d", t) }
func TestPrecompiledBLS12381PairingFail(t *testing.T) { testJsonFail("blsPairing", "f0e", t) }
func TestPrecompiledBLS12381MapG1Fail(t *testing.T) { testJsonFail("blsMapG1", "f0f", t) }
func TestPrecompiledBLS12381MapG2Fail(t *testing.T) { testJsonFail("blsMapG2", "f10", t) }

func loadJson(name string) ([]precompiledTest, error) {
data, err := os.ReadFile(fmt.Sprintf("testdata/precompiles/%v.json", name))
Expand Down
Loading
Loading