diff --git a/CHANGELOG.md b/CHANGELOG.md index 00c58211c..a4fc13aa0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/cosmos). +## v0.34.16 + +Special thanks to external contributors on this release: @yihuang + +### BUG FIXES + +- [consensus] [\#7617](https://github.com/tendermint/tendermint/issues/7617) calculate prevote message delay metric (backport #7551) (@williambanfield). +- [consensus] [\#7631](https://github.com/tendermint/tendermint/issues/7631) check proposal non-nil in prevote message delay metric (backport #7625) (@williambanfield). +- [statesync] [\#7885](https://github.com/tendermint/tendermint/issues/7885) statesync: assert app version matches (backport #7856) (@cmwaters). +- [statesync] [\#7881](https://github.com/tendermint/tendermint/issues/7881) fix app hash in state rollback (backport #7837) (@cmwaters). +- [cli] [#7837](https://github.com/tendermint/tendermint/pull/7837) fix app hash in state rollback. (@yihuang). + ## v0.34.15 Special thanks to external contributors on this release: @thanethomson diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index b9addbd99..bee423db9 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -23,5 +23,3 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi ### IMPROVEMENTS ### BUG FIXES - -- [cli] [#7837](https://github.com/tendermint/tendermint/pull/7837) fix app hash in state rollback. (@yihuang) diff --git a/Makefile b/Makefile index a7ce34ff2..fa7a13d8c 100644 --- a/Makefile +++ b/Makefile @@ -192,9 +192,7 @@ build-docs: mkdir -p ~/output/$${path_prefix} ; \ cp -r .vuepress/dist/* ~/output/$${path_prefix}/ ; \ cp ~/output/$${path_prefix}/index.html ~/output ; \ - done < versions ; \ - mkdir -p ~/output/master ; \ - cp -r .vuepress/dist/* ~/output/master/ + done < versions ; .PHONY: build-docs sync-docs: diff --git a/crypto/secp256k1/secp256k1.go b/crypto/secp256k1/secp256k1.go index fa387e355..0fbd9ad2d 100644 --- a/crypto/secp256k1/secp256k1.go +++ b/crypto/secp256k1/secp256k1.go @@ -122,6 +122,26 @@ func GenPrivKeySecp256k1(secret []byte) PrivKey { return PrivKey(privKey32) } +// used to reject malleable signatures +// see: +// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93 +// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39 +var secp256k1halfN = new(big.Int).Rsh(secp256k1.S256().N, 1) + +// Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg. +// The returned signature will be of the form R || S (in lower-S form). +func (privKey PrivKey) Sign(msg []byte) ([]byte, error) { + priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey) + + sig, err := priv.Sign(crypto.Sha256(msg)) + if err != nil { + return nil, err + } + + sigBytes := serializeSig(sig) + return sigBytes, nil +} + //------------------------------------- var _ crypto.PubKey = PubKey{} @@ -171,3 +191,47 @@ func (pubKey PubKey) Equals(other crypto.PubKey) bool { func (pubKey PubKey) Type() string { return KeyType } + +// VerifySignature verifies a signature of the form R || S. +// It rejects signatures which are not in lower-S form. +func (pubKey PubKey) VerifySignature(msg []byte, sigStr []byte) bool { + if len(sigStr) != 64 { + return false + } + + pub, err := secp256k1.ParsePubKey(pubKey, secp256k1.S256()) + if err != nil { + return false + } + + // parse the signature: + signature := signatureFromBytes(sigStr) + // Reject malleable signatures. libsecp256k1 does this check but btcec doesn't. + // see: https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93 + if signature.S.Cmp(secp256k1halfN) > 0 { + return false + } + + return signature.Verify(crypto.Sha256(msg), pub) +} + +// Read Signature struct from R || S. Caller needs to ensure +// that len(sigStr) == 64. +func signatureFromBytes(sigStr []byte) *secp256k1.Signature { + return &secp256k1.Signature{ + R: new(big.Int).SetBytes(sigStr[:32]), + S: new(big.Int).SetBytes(sigStr[32:64]), + } +} + +// Serialize signature to R || S. +// R, S are padded to 32 bytes respectively. +func serializeSig(sig *secp256k1.Signature) []byte { + rBytes := sig.R.Bytes() + sBytes := sig.S.Bytes() + sigBytes := make([]byte, 64) + // 0 pad the byte arrays from the left if they aren't big enough. + copy(sigBytes[32-len(rBytes):32], rBytes) + copy(sigBytes[64-len(sBytes):64], sBytes) + return sigBytes +} diff --git a/crypto/secp256k1/secp256k1_nocgo.go b/crypto/secp256k1/secp256k1_nocgo.go deleted file mode 100644 index 6b52dc5d2..000000000 --- a/crypto/secp256k1/secp256k1_nocgo.go +++ /dev/null @@ -1,76 +0,0 @@ -//go:build !libsecp256k1 -// +build !libsecp256k1 - -package secp256k1 - -import ( - "math/big" - - secp256k1 "github.com/btcsuite/btcd/btcec" - - "github.com/tendermint/tendermint/crypto" -) - -// used to reject malleable signatures -// see: -// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93 -// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39 -var secp256k1halfN = new(big.Int).Rsh(secp256k1.S256().N, 1) - -// Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg. -// The returned signature will be of the form R || S (in lower-S form). -func (privKey PrivKey) Sign(msg []byte) ([]byte, error) { - priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey) - - sig, err := priv.Sign(crypto.Sha256(msg)) - if err != nil { - return nil, err - } - - sigBytes := serializeSig(sig) - return sigBytes, nil -} - -// VerifySignature verifies a signature of the form R || S. -// It rejects signatures which are not in lower-S form. -func (pubKey PubKey) VerifySignature(msg []byte, sigStr []byte) bool { - if len(sigStr) != 64 { - return false - } - - pub, err := secp256k1.ParsePubKey(pubKey, secp256k1.S256()) - if err != nil { - return false - } - - // parse the signature: - signature := signatureFromBytes(sigStr) - // Reject malleable signatures. libsecp256k1 does this check but btcec doesn't. - // see: https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93 - if signature.S.Cmp(secp256k1halfN) > 0 { - return false - } - - return signature.Verify(crypto.Sha256(msg), pub) -} - -// Read Signature struct from R || S. Caller needs to ensure -// that len(sigStr) == 64. -func signatureFromBytes(sigStr []byte) *secp256k1.Signature { - return &secp256k1.Signature{ - R: new(big.Int).SetBytes(sigStr[:32]), - S: new(big.Int).SetBytes(sigStr[32:64]), - } -} - -// Serialize signature to R || S. -// R, S are padded to 32 bytes respectively. -func serializeSig(sig *secp256k1.Signature) []byte { - rBytes := sig.R.Bytes() - sBytes := sig.S.Bytes() - sigBytes := make([]byte, 64) - // 0 pad the byte arrays from the left if they aren't big enough. - copy(sigBytes[32-len(rBytes):32], rBytes) - copy(sigBytes[64-len(sBytes):64], sBytes) - return sigBytes -} diff --git a/docs/versions b/docs/versions index 90a8a4cf1..70754facc 100644 --- a/docs/versions +++ b/docs/versions @@ -1,3 +1,4 @@ +master master v0.33.x v0.33 v0.34.x v0.34 v0.35.x v0.35 diff --git a/version/version.go b/version/version.go index 146465ed5..d51cd1918 100644 --- a/version/version.go +++ b/version/version.go @@ -7,7 +7,7 @@ var ( const ( // TMVersionDefault is the used as the fallback version of Tendermint Core // when not using git describe. It is formatted with semantic versioning. - TMVersionDefault = "0.34.15" + TMVersionDefault = "0.34.16" // ABCISemVer is the semantic version of the ABCI library ABCISemVer = "0.17.0"