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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ However, it has been variously patched to be optimized for ibet Network. For exa
- The default block generation interval is set to 1 second.
- Fully supports Go 1.25 and applies new 3rd party packages from a security perspective.
- Made temporary fixes for bugs before they were fixed in the original GoQuorum.
- Added secp256r1 (P-256) signature verification precompile support.

## Building the source
Building quorum requires both a Go (version 1.25) and a C compiler.
Expand Down
44 changes: 35 additions & 9 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"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/secp256r1"
"github.com/ethereum/go-ethereum/params"

//lint:ignore SA1019 Needed for precompile
Expand Down Expand Up @@ -81,15 +82,16 @@ var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{
// PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum
// contracts used in the Berlin release.
var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2F{},
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2F{},
common.BytesToAddress([]byte{0x1, 0x0}): &p256Verify{},
}

// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
Expand Down Expand Up @@ -625,6 +627,30 @@ func (c *blake2F) Run(input []byte) ([]byte, error) {
return output, nil
}

// P256VERIFY (secp256r1 signature verification) is implemented as a native contract.
type p256Verify struct{}

func (c *p256Verify) RequiredGas(input []byte) uint64 {
return params.P256VerifyGas
}

func (c *p256Verify) Run(input []byte) ([]byte, error) {
const p256VerifyInputLength = 160
if len(input) != p256VerifyInputLength {
return nil, nil
}
hash := input[0:32]
r := new(big.Int).SetBytes(input[32:64])
s := new(big.Int).SetBytes(input[64:96])
x := new(big.Int).SetBytes(input[96:128])
y := new(big.Int).SetBytes(input[128:160])

if secp256r1.Verify(hash, r, s, x, y) {
return true32Byte, nil
}
return nil, nil
}

var (
errBLS12381InvalidInputLength = errors.New("invalid input length")
errBLS12381InvalidFieldElementTopBytes = errors.New("invalid field element top bytes")
Expand Down
42 changes: 23 additions & 19 deletions core/vm/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,26 @@ type precompiledFailureTest struct {
// allPrecompiles does not map to the actual set of precompiles, as it also contains
// repriced versions of precompiles at certain slots
var allPrecompiles = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false},
common.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2F{},
common.BytesToAddress([]byte{10}): &bls12381G1Add{},
common.BytesToAddress([]byte{11}): &bls12381G1Mul{},
common.BytesToAddress([]byte{12}): &bls12381G1MultiExp{},
common.BytesToAddress([]byte{13}): &bls12381G2Add{},
common.BytesToAddress([]byte{14}): &bls12381G2Mul{},
common.BytesToAddress([]byte{15}): &bls12381G2MultiExp{},
common.BytesToAddress([]byte{16}): &bls12381Pairing{},
common.BytesToAddress([]byte{17}): &bls12381MapG1{},
common.BytesToAddress([]byte{18}): &bls12381MapG2{},
common.BytesToAddress([]byte{1}): &ecrecover{},
common.BytesToAddress([]byte{2}): &sha256hash{},
common.BytesToAddress([]byte{3}): &ripemd160hash{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false},
common.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true},
common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
common.BytesToAddress([]byte{9}): &blake2F{},
common.BytesToAddress([]byte{10}): &bls12381G1Add{},
common.BytesToAddress([]byte{11}): &bls12381G1Mul{},
common.BytesToAddress([]byte{12}): &bls12381G1MultiExp{},
common.BytesToAddress([]byte{13}): &bls12381G2Add{},
common.BytesToAddress([]byte{14}): &bls12381G2Mul{},
common.BytesToAddress([]byte{15}): &bls12381G2MultiExp{},
common.BytesToAddress([]byte{16}): &bls12381Pairing{},
common.BytesToAddress([]byte{17}): &bls12381MapG1{},
common.BytesToAddress([]byte{18}): &bls12381MapG2{},
common.BytesToAddress([]byte{0x1, 0x0}): &p256Verify{},
}

// EIP-152 test vectors
Expand Down Expand Up @@ -264,6 +265,9 @@ func BenchmarkPrecompiledBn256Pairing(b *testing.B) { benchJson("bn256Pairing",
func TestPrecompiledBlake2F(t *testing.T) { testJson("blake2F", "09", t) }
func BenchmarkPrecompiledBlake2F(b *testing.B) { benchJson("blake2F", "09", b) }

func TestPrecompiledP256Verify(t *testing.T) { testJson("p256Verify", "0100", t) }
func BenchmarkPrecompiledP256Verify(b *testing.B) { benchJson("p256Verify", "0100", b) }

func TestPrecompileBlake2FMalformedInput(t *testing.T) {
for _, test := range blake2FMalformedInputTests {
testPrecompiledFailure("09", test, t)
Expand Down
21 changes: 21 additions & 0 deletions core/vm/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,27 @@ func TestActivePrecompiles(t *testing.T) {
evm *EVM
want []common.Address
}{
{
name: "berlin",
evm: &EVM{
chainRules: params.Rules{
IsBerlin: true,
IsPrivacyPrecompile: false,
},
},
want: []common.Address{
common.BytesToAddress([]byte{1}),
common.BytesToAddress([]byte{2}),
common.BytesToAddress([]byte{3}),
common.BytesToAddress([]byte{4}),
common.BytesToAddress([]byte{5}),
common.BytesToAddress([]byte{6}),
common.BytesToAddress([]byte{7}),
common.BytesToAddress([]byte{8}),
common.BytesToAddress([]byte{9}),
common.BytesToAddress([]byte{0x1, 0x0}),
},
},
{
name: "istanbul-plus-quorum-privacy",
evm: &EVM{
Expand Down
Loading