@@ -350,13 +350,21 @@ var PrecompiledContractsOsaka = PrecompiledContracts{
350350 common .BytesToAddress ([]byte {0x1 , 0x00 }): & p256Verify {eip7951 : true },
351351}
352352
353+ var PrecompiledContractsMendel = func () PrecompiledContracts {
354+ precompiles := maps .Clone (PrecompiledContractsOsaka )
355+ precompiles [common .BytesToAddress ([]byte {0x66 })] = & blsSignatureVerifyMendel {}
356+ precompiles [common .BytesToAddress ([]byte {0x67 })] = & cometBFTLightBlockValidateHertzMendel {}
357+ return precompiles
358+ }()
359+
353360// PrecompiledContractsP256Verify contains the precompiled Ethereum
354361// contract specified in EIP-7212. This is exported for testing purposes.
355362var PrecompiledContractsP256Verify = PrecompiledContracts {
356363 common .BytesToAddress ([]byte {0x1 , 0x00 }): & p256Verify {},
357364}
358365
359366var (
367+ PrecompiledAddressesMendel []common.Address
360368 PrecompiledAddressesOsaka []common.Address
361369 PrecompiledAddressesPrague []common.Address
362370 PrecompiledAddressesHaber []common.Address
@@ -417,6 +425,9 @@ func init() {
417425 for k := range PrecompiledContractsPrague {
418426 PrecompiledAddressesPrague = append (PrecompiledAddressesPrague , k )
419427 }
428+ for k := range PrecompiledContractsMendel {
429+ PrecompiledAddressesMendel = append (PrecompiledAddressesMendel , k )
430+ }
420431 for k := range PrecompiledContractsOsaka {
421432 PrecompiledAddressesOsaka = append (PrecompiledAddressesOsaka , k )
422433 }
@@ -426,6 +437,8 @@ func activePrecompiledContracts(rules params.Rules) PrecompiledContracts {
426437 switch {
427438 case rules .IsVerkle :
428439 return PrecompiledContractsVerkle
440+ case rules .IsMendel :
441+ return PrecompiledContractsMendel
429442 case rules .IsOsaka :
430443 return PrecompiledContractsOsaka
431444 case rules .IsPrague :
@@ -467,6 +480,8 @@ func ActivePrecompiledContracts(rules params.Rules) PrecompiledContracts {
467480// ActivePrecompiles returns the precompile addresses enabled with the current configuration.
468481func ActivePrecompiles (rules params.Rules ) []common.Address {
469482 switch {
483+ case rules .IsMendel :
484+ return PrecompiledAddressesMendel
470485 case rules .IsOsaka :
471486 return PrecompiledAddressesOsaka
472487 case rules .IsPrague :
@@ -1602,6 +1617,10 @@ func (c *bls12381MapG2) Name() string {
16021617// blsSignatureVerify implements bls signature verification precompile.
16031618type blsSignatureVerify struct {}
16041619
1620+ type blsSignatureVerifyMendel struct {
1621+ blsSignatureVerify
1622+ }
1623+
16051624const (
16061625 msgHashLength = uint64 (32 )
16071626 signatureLength = uint64 (96 )
@@ -1620,16 +1639,13 @@ func (c *blsSignatureVerify) RequiredGas(input []byte) uint64 {
16201639 return params .BlsSignatureVerifyBaseGas + pubKeyNumber * params .BlsSignatureVerifyPerKeyGas
16211640}
16221641
1623- // Run input:
1624- // msg | signature | [{bls pubkey}] |
1625- // 32 bytes | 96 bytes | [{48 bytes}] |
1626- func (c * blsSignatureVerify ) Run (input []byte ) ([]byte , error ) {
1642+ func parseBlsSignatureVerifyInput (input []byte , requireUniquePubKeys bool ) ([32 ]byte , bls.Signature , []bls.PublicKey , error ) {
16271643 msgAndSigLength := msgHashLength + signatureLength
16281644 inputLen := uint64 (len (input ))
16291645 if inputLen <= msgAndSigLength ||
16301646 (inputLen - msgAndSigLength )% singleBlsPubkeyLength != 0 {
16311647 log .Debug ("blsSignatureVerify input size wrong" , "inputLen" , inputLen )
1632- return nil , ErrExecutionReverted
1648+ return [ 32 ] byte {}, nil , nil , ErrExecutionReverted
16331649 }
16341650
16351651 var msg [32 ]byte
@@ -1640,38 +1656,76 @@ func (c *blsSignatureVerify) Run(input []byte) ([]byte, error) {
16401656 sig , err := bls .SignatureFromBytes (signatureBytes )
16411657 if err != nil {
16421658 log .Debug ("blsSignatureVerify invalid signature" , "err" , err )
1643- return nil , ErrExecutionReverted
1659+ return [ 32 ] byte {}, nil , nil , ErrExecutionReverted
16441660 }
16451661
16461662 pubKeyNumber := (inputLen - msgAndSigLength ) / singleBlsPubkeyLength
16471663 pubKeys := make ([]bls.PublicKey , pubKeyNumber )
1664+ var seenPubKeys map [string ]struct {}
1665+ if requireUniquePubKeys {
1666+ seenPubKeys = make (map [string ]struct {}, pubKeyNumber )
1667+ }
16481668 for i := uint64 (0 ); i < pubKeyNumber ; i ++ {
16491669 pubKeyBytes := getData (input , msgAndSigLength + i * singleBlsPubkeyLength , singleBlsPubkeyLength )
16501670 pubKey , err := bls .PublicKeyFromBytes (pubKeyBytes )
16511671 if err != nil {
16521672 log .Debug ("blsSignatureVerify invalid pubKey" , "err" , err )
1653- return nil , ErrExecutionReverted
1673+ return [32 ]byte {}, nil , nil , ErrExecutionReverted
1674+ }
1675+ if requireUniquePubKeys {
1676+ key := string (pubKeyBytes )
1677+ if _ , ok := seenPubKeys [key ]; ok {
1678+ return msg , sig , nil , nil
1679+ }
1680+ seenPubKeys [key ] = struct {}{}
16541681 }
16551682 pubKeys [i ] = pubKey
16561683 }
16571684
1658- if pubKeyNumber > 1 {
1685+ return msg , sig , pubKeys , nil
1686+ }
1687+
1688+ func runBlsSignatureVerify (input []byte , requireUniquePubKeys bool ) ([]byte , error ) {
1689+ msg , sig , pubKeys , err := parseBlsSignatureVerifyInput (input , requireUniquePubKeys )
1690+ if err != nil {
1691+ return nil , err
1692+ }
1693+ if pubKeys == nil {
1694+ return common .Big0 .Bytes (), nil
1695+ }
1696+
1697+ if len (pubKeys ) > 1 {
16591698 if ! sig .FastAggregateVerify (pubKeys , msg ) {
16601699 return common .Big0 .Bytes (), nil
16611700 }
16621701 } else {
1663- if ! sig .Verify (pubKeys [0 ], msgBytes ) {
1702+ if ! sig .Verify (pubKeys [0 ], msg [:] ) {
16641703 return common .Big0 .Bytes (), nil
16651704 }
16661705 }
16671706
16681707 return common .Big1 .Bytes (), nil
16691708}
16701709
1710+ // Run input:
1711+ // msg | signature | [{bls pubkey}] |
1712+ // 32 bytes | 96 bytes | [{48 bytes}] |
1713+ func (c * blsSignatureVerify ) Run (input []byte ) ([]byte , error ) {
1714+ return runBlsSignatureVerify (input , false )
1715+ }
1716+
16711717func (c * blsSignatureVerify ) Name () string {
16721718 return "BLS_SIGNATURE_VERIFY"
16731719}
16741720
1721+ func (c * blsSignatureVerifyMendel ) Run (input []byte ) ([]byte , error ) {
1722+ return runBlsSignatureVerify (input , true )
1723+ }
1724+
1725+ func (c * blsSignatureVerifyMendel ) Name () string {
1726+ return "BLS_SIGNATURE_VERIFY_MENDEL"
1727+ }
1728+
16751729// kzgPointEvaluation implements the EIP-4844 point evaluation precompile.
16761730type kzgPointEvaluation struct {}
16771731
0 commit comments