btcec: validate R and S signature components in RecoverCompact
This commit is contained in:
parent
fa683a69dc
commit
31b66488b4
2 changed files with 54 additions and 1 deletions
|
@ -284,6 +284,25 @@ func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
|
|||
// format and thus we match bitcoind's behaviour here.
|
||||
func recoverKeyFromSignature(curve *KoblitzCurve, sig *Signature, msg []byte,
|
||||
iter int, doChecks bool) (*PublicKey, error) {
|
||||
// Parse and validate the R and S signature components.
|
||||
//
|
||||
// Fail if r and s are not in [1, N-1].
|
||||
if sig.R.Cmp(curve.Params().N) != -1 {
|
||||
return nil, errors.New("signature R is >= curve order")
|
||||
}
|
||||
|
||||
if sig.R.Sign() == 0 {
|
||||
return nil, errors.New("signature R is 0")
|
||||
}
|
||||
|
||||
if sig.S.Cmp(curve.Params().N) != -1 {
|
||||
return nil, errors.New("signature S is >= curve order")
|
||||
}
|
||||
|
||||
if sig.S.Sign() == 0 {
|
||||
return nil, errors.New("signature S is 0")
|
||||
}
|
||||
|
||||
// 1.1 x = (n * i) + r
|
||||
Rx := new(big.Int).Mul(curve.Params().N,
|
||||
new(big.Int).SetInt64(int64(iter/2)))
|
||||
|
@ -393,7 +412,7 @@ func SignCompact(curve *KoblitzCurve, key *PrivateKey,
|
|||
|
||||
// RecoverCompact verifies the compact signature "signature" of "hash" for the
|
||||
// Koblitz curve in "curve". If the signature matches then the recovered public
|
||||
// key will be returned as well as a boolen if the original key was compressed
|
||||
// key will be returned as well as a boolean if the original key was compressed
|
||||
// or not, else an error will be returned.
|
||||
func RecoverCompact(curve *KoblitzCurve, signature,
|
||||
hash []byte) (*PublicKey, bool, error) {
|
||||
|
|
|
@ -555,6 +555,40 @@ var recoveryTests = []struct {
|
|||
sig: "00000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000004",
|
||||
pub: "04A7640409AA2083FDAD38B2D8DE1263B2251799591D840653FB02DBBA503D7745FCB83D80E08A1E02896BE691EA6AFFB8A35939A646F1FC79052A744B1C82EDC3",
|
||||
},
|
||||
{
|
||||
// Zero R value
|
||||
//
|
||||
// Test case contributed by Ethereum Swarm: GH-1651
|
||||
msg: "3060d2c77c1e192d62ad712fb400e04e6f779914a6876328ff3b213fa85d2012",
|
||||
sig: "65000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037a3",
|
||||
err: fmt.Errorf("signature R is 0"),
|
||||
},
|
||||
{
|
||||
// Zero R value
|
||||
//
|
||||
// Test case contributed by Ethereum Swarm: GH-1651
|
||||
msg: "2bcebac60d8a78e520ae81c2ad586792df495ed429bd730dcd897b301932d054",
|
||||
sig: "060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c",
|
||||
err: fmt.Errorf("signature R is 0"),
|
||||
},
|
||||
{
|
||||
// R = N (curve order of secp256k1)
|
||||
msg: "2bcebac60d8a78e520ae81c2ad586792df495ed429bd730dcd897b301932d054",
|
||||
sig: "65fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036414100000000000000000000000000000000000000000000000000000000000037a3",
|
||||
err: fmt.Errorf("signature R is >= curve order"),
|
||||
},
|
||||
{
|
||||
// Zero S value
|
||||
msg: "ce0677bb30baa8cf067c88db9811f4333d131bf8bcf12fe7065d211dce971008",
|
||||
sig: "0190f27b8b488db00b00606796d2987f6a5f59ae62ea05effe84fef5b8b0e549980000000000000000000000000000000000000000000000000000000000000000",
|
||||
err: fmt.Errorf("signature S is 0"),
|
||||
},
|
||||
{
|
||||
// S = N (curve order of secp256k1)
|
||||
msg: "ce0677bb30baa8cf067c88db9811f4333d131bf8bcf12fe7065d211dce971008",
|
||||
sig: "0190f27b8b488db00b00606796d2987f6a5f59ae62ea05effe84fef5b8b0e54998fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
|
||||
err: fmt.Errorf("signature S is >= curve order"),
|
||||
},
|
||||
}
|
||||
|
||||
func TestRecoverCompact(t *testing.T) {
|
||||
|
|
Loading…
Add table
Reference in a new issue