From 1b12bead4bf8f74a202ba7ec5210851f6b7d479a Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 29 Nov 2024 16:08:31 +0800 Subject: [PATCH] crypto: add SignatureLength constant and use it everywhere (#19996) --- accounts/abi/bind/backends/simulated.go | 3 ++- accounts/usbwallet/ledger.go | 5 +++-- accounts/usbwallet/trezor.go | 3 ++- cmd/puppeth/wizard_genesis.go | 4 ++-- consensus/XDPoS/engines/engine_v1/utils.go | 2 +- consensus/clique/clique.go | 6 +++--- core/genesis.go | 3 ++- core/types/lending_signing.go | 2 +- core/types/order_signing.go | 2 +- core/types/transaction_signing.go | 2 +- core/vm/contracts.go | 2 +- crypto/signature_cgo.go | 17 +++++++++-------- crypto/signature_nocgo.go | 5 +++-- internal/ethapi/api.go | 4 ++-- p2p/rlpx.go | 10 +++++----- 15 files changed, 38 insertions(+), 32 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 4de5a89885ddb..f6b4a13da6fcf 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -42,6 +42,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" + "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/eth/filters" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/event" @@ -101,7 +102,7 @@ func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64, chainConfi GasLimit: gasLimit, // need this big, support initial smart contract Config: chainConfig, Alloc: alloc, - ExtraData: append(make([]byte, 32), make([]byte, 65)...), + ExtraData: append(make([]byte, 32), make([]byte, crypto.SignatureLength)...), } genesis.MustCommit(database) consensus := XDPoS.NewFaker(database, chainConfig) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index a1091add84e04..f9d06aa032dc8 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -32,6 +32,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/rlp" ) @@ -341,7 +342,7 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction op = ledgerP1ContTransactionData } // Extract the Ethereum signature and do a sanity validation - if len(reply) != 65 { + if len(reply) != crypto.SignatureLength { return common.Address{}, nil, errors.New("reply lacks signature") } signature := append(reply[1:], reply[0]) @@ -352,7 +353,7 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction signer = new(types.HomesteadSigner) } else { signer = types.NewEIP155Signer(chainID) - signature[64] = signature[64] - byte(chainID.Uint64()*2+35) + signature[crypto.RecoveryIDOffset] = signature[crypto.RecoveryIDOffset] - byte(chainID.Uint64()*2+35) } signed, err := tx.WithSignature(signer, signature) if err != nil { diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index 04e57292bafe8..8bc51bb83538d 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -32,6 +32,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/log" "github.com/golang/protobuf/proto" ) @@ -222,7 +223,7 @@ func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction } else { // Trezor backend does not support typed transactions yet. signer = types.NewEIP155Signer(chainID) - signature[64] = signature[64] - byte(chainID.Uint64()*2+35) + signature[crypto.RecoveryIDOffset] = signature[crypto.RecoveryIDOffset] - byte(chainID.Uint64()*2+35) } // Inject the final signature into the transaction and sanity check the sender diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go index c1e077c595135..d7a8f93cec02f 100644 --- a/cmd/puppeth/wizard_genesis.go +++ b/cmd/puppeth/wizard_genesis.go @@ -105,7 +105,7 @@ func (w *wizard) makeGenesis() { } } } - genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+65) + genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+crypto.SignatureLength) for i, signer := range signers { copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:]) } @@ -179,7 +179,7 @@ func (w *wizard) makeGenesis() { validatorCap := new(big.Int) validatorCap.SetString("50000000000000000000000", 10) var validatorCaps []*big.Int - genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+65) + genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+crypto.SignatureLength) for i, signer := range signers { validatorCaps = append(validatorCaps, validatorCap) copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:]) diff --git a/consensus/XDPoS/engines/engine_v1/utils.go b/consensus/XDPoS/engines/engine_v1/utils.go index b07a5e0f69b6f..a0128331220c4 100644 --- a/consensus/XDPoS/engines/engine_v1/utils.go +++ b/consensus/XDPoS/engines/engine_v1/utils.go @@ -74,7 +74,7 @@ func sigHash(header *types.Header) (hash common.Hash) { header.GasLimit, header.GasUsed, header.Time, - header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short + header.Extra[:len(header.Extra)-crypto.SignatureLength], // Yes, this will panic if extra is too short header.MixDigest, header.Nonce, } diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 899649eb84f30..bb1e8ef1189c6 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -56,8 +56,8 @@ var ( epochLength = uint64(30000) // Default number of blocks after which to checkpoint and reset the pending votes blockPeriod = uint64(15) // Default minimum difference between two consecutive block's timestamps - extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity - extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal + extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity + extraSeal = crypto.SignatureLength // Fixed number of extra-data suffix bytes reserved for signer seal nonceAuthVote = hexutil.MustDecode("0xffffffffffffffff") // Magic nonce number to vote on adding a new signer nonceDropVote = hexutil.MustDecode("0x0000000000000000") // Magic nonce number to vote on removing a signer. @@ -160,7 +160,7 @@ func sigHash(header *types.Header) (hash common.Hash) { header.GasLimit, header.GasUsed, header.Time, - header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short + header.Extra[:len(header.Extra)-crypto.SignatureLength], // Yes, this will panic if extra is too short header.MixDigest, header.Nonce, } diff --git a/core/genesis.go b/core/genesis.go index a005b3a14a589..d14b1c73d153a 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -26,6 +26,7 @@ import ( "strings" "github.com/XinFinOrg/XDPoSChain/core/rawdb" + "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" @@ -376,7 +377,7 @@ func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis { // Assemble and return the genesis with the precompiles and faucet pre-funded return &Genesis{ Config: &config, - ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, 65)...), + ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...), GasLimit: 6283185, BaseFee: big.NewInt(params.InitialBaseFee), Difficulty: big.NewInt(1), diff --git a/core/types/lending_signing.go b/core/types/lending_signing.go index 8fc37815d33fc..cce6e607af526 100644 --- a/core/types/lending_signing.go +++ b/core/types/lending_signing.go @@ -97,7 +97,7 @@ func (lendingsign LendingTxSigner) Equal(s2 LendingSigner) bool { // SignatureValues returns signature values. This signature needs to be in the [R || S || V] format where V is 0 or 1. func (lendingsign LendingTxSigner) SignatureValues(tx *LendingTransaction, sig []byte) (r, s, v *big.Int, err error) { - if len(sig) != 65 { + if len(sig) != crypto.SignatureLength { panic(fmt.Sprintf("wrong size for signature: got %d, want 65", len(sig))) } r = new(big.Int).SetBytes(sig[:32]) diff --git a/core/types/order_signing.go b/core/types/order_signing.go index 6a7f400255365..8fa5625529995 100644 --- a/core/types/order_signing.go +++ b/core/types/order_signing.go @@ -97,7 +97,7 @@ func (ordersign OrderTxSigner) Equal(s2 OrderSigner) bool { // SignatureValues returns signature values. This signature needs to be in the [R || S || V] format where V is 0 or 1. func (ordersign OrderTxSigner) SignatureValues(tx *OrderTransaction, sig []byte) (r, s, v *big.Int, err error) { - if len(sig) != 65 { + if len(sig) != crypto.SignatureLength { panic(fmt.Sprintf("wrong size for signature: got %d, want 65", len(sig))) } r = new(big.Int).SetBytes(sig[:32]) diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index b835e45af1bad..ff8c4b530ada7 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -477,7 +477,7 @@ func recoverPlain(sighash common.Hash, R, S, Vb *big.Int, homestead bool) (commo } // encode the snature in uncompressed format r, s := R.Bytes(), S.Bytes() - sig := make([]byte, 65) + sig := make([]byte, crypto.SignatureLength) copy(sig[32-len(r):32], r) copy(sig[64-len(s):64], s) sig[64] = V diff --git a/core/vm/contracts.go b/core/vm/contracts.go index be9df1adfecd2..7da6949ded53a 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -200,7 +200,7 @@ func (c *ecrecover) Run(input []byte) ([]byte, error) { } // We must make sure not to modify the 'input', so placing the 'v' along with // the signature needs to be done on a new allocation - sig := make([]byte, 65) + sig := make([]byte, crypto.SignatureLength) copy(sig, input[64:128]) sig[64] = v // v needs to be at the end for libsecp256k1 diff --git a/crypto/signature_cgo.go b/crypto/signature_cgo.go index ad5bd7c247d1d..fcf0fa9d8ad44 100644 --- a/crypto/signature_cgo.go +++ b/crypto/signature_cgo.go @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . +//go:build !nacl && !js && cgo // +build !nacl,!js,cgo package crypto @@ -47,24 +48,24 @@ func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { // // This function is susceptible to chosen plaintext attacks that can leak // information about the private key that is used for signing. Callers must -// be aware that the given hash cannot be chosen by an adversery. Common +// be aware that the given digest cannot be chosen by an adversery. Common // solution is to hash any input before calculating the signature. // // The produced signature is in the [R || S || V] format where V is 0 or 1. -func Sign(hash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) { - if len(hash) != 32 { - return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash)) +func Sign(digestHash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) { + if len(digestHash) != DigestLength { + return nil, fmt.Errorf("hash is required to be exactly %d bytes (%d)", DigestLength, len(digestHash)) } seckey := math.PaddedBigBytes(prv.D, prv.Params().BitSize/8) defer zeroBytes(seckey) - return secp256k1.Sign(hash, seckey) + return secp256k1.Sign(digestHash, seckey) } -// VerifySignature checks that the given public key created signature over hash. +// VerifySignature checks that the given public key created signature over digest. // The public key should be in compressed (33 bytes) or uncompressed (65 bytes) format. // The signature should have the 64 byte [R || S] format. -func VerifySignature(pubkey, hash, signature []byte) bool { - return secp256k1.VerifySignature(pubkey, hash, signature) +func VerifySignature(pubkey, digestHash, signature []byte) bool { + return secp256k1.VerifySignature(pubkey, digestHash, signature) } // DecompressPubkey parses a public key in the 33-byte compressed format. diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go index 908b04e4f881b..e52f50409c490 100644 --- a/crypto/signature_nocgo.go +++ b/crypto/signature_nocgo.go @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . +//go:build nacl || js || !cgo // +build nacl js !cgo package crypto @@ -41,7 +42,7 @@ func Ecrecover(hash, sig []byte) ([]byte, error) { // SigToPub returns the public key that created the given signature. func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { // Convert to btcec input format with 'recovery id' v at the beginning. - btcsig := make([]byte, 65) + btcsig := make([]byte, SignatureLength) btcsig[0] = sig[64] + 27 copy(btcsig[1:], sig) @@ -58,7 +59,7 @@ func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { // // The produced signature is in the [R || S || V] format where V is 0 or 1. func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) { - if len(hash) != 32 { + if len(hash) != DigestLength { return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash)) } if prv.Curve != btcec.S256() { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index ac7ac6739b3e4..273021e4f0a68 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -542,7 +542,7 @@ func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr c if err != nil { return nil, err } - signature[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper + signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper return signature, nil } @@ -3264,7 +3264,7 @@ func (s *PublicTransactionPoolAPI) Sign(addr common.Address, data hexutil.Bytes) // Sign the requested hash with the wallet signature, err := wallet.SignHash(account, signHash(data)) if err == nil { - signature[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper + signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper } return signature, err } diff --git a/p2p/rlpx.go b/p2p/rlpx.go index 6544ac8c3c139..640e7ce3f21e6 100644 --- a/p2p/rlpx.go +++ b/p2p/rlpx.go @@ -37,19 +37,19 @@ import ( "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto/ecies" "github.com/XinFinOrg/XDPoSChain/crypto/secp256k1" - "golang.org/x/crypto/sha3" "github.com/XinFinOrg/XDPoSChain/p2p/discover" "github.com/XinFinOrg/XDPoSChain/rlp" "github.com/golang/snappy" + "golang.org/x/crypto/sha3" ) const ( maxUint24 = ^uint32(0) >> 8 - sskLen = 16 // ecies.MaxSharedKeyLength(pubKey) / 2 - sigLen = 65 // elliptic S256 - pubLen = 64 // 512 bit pubkey in uncompressed representation without format byte - shaLen = 32 // hash length (for nonce etc) + sskLen = 16 // ecies.MaxSharedKeyLength(pubKey) / 2 + sigLen = crypto.SignatureLength // elliptic S256 + pubLen = 64 // 512 bit pubkey in uncompressed representation without format byte + shaLen = 32 // hash length (for nonce etc) authMsgLen = sigLen + shaLen + pubLen + shaLen + 1 authRespLen = pubLen + shaLen + 1