mirror of
https://github.com/btcsuite/btcd.git
synced 2025-03-11 17:57:50 +01:00
txscript: Add new flag ScriptVerifyLowS
The ScriptVerifyLowS flag defines that script signatures must comply with the DER format as well as have an S value less than or equal to the half order.
This commit is contained in:
parent
9523345814
commit
369b352452
3 changed files with 36 additions and 2 deletions
|
@ -701,6 +701,12 @@
|
||||||
"DERSIG",
|
"DERSIG",
|
||||||
"P2PK with multi-byte hashtype, with DERSIG"
|
"P2PK with multi-byte hashtype, with DERSIG"
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001",
|
||||||
|
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
|
||||||
|
"LOW_S",
|
||||||
|
"P2PK with high S"
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"0x47 0x30440220745d63eb70d45652128b450aa5ca7d9b513439963f261cb1c40a60f0785e7ee402204877785b38945ca9dbec78e1c1d4dd12148cc25c868bd27480023b49ae0f310501",
|
"0x47 0x30440220745d63eb70d45652128b450aa5ca7d9b513439963f261cb1c40a60f0785e7ee402204877785b38945ca9dbec78e1c1d4dd12148cc25c868bd27480023b49ae0f310501",
|
||||||
"0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
|
"0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
|
||||||
|
|
|
@ -4579,6 +4579,8 @@ func parseScriptFlags(flagStr string) (ScriptFlags, error) {
|
||||||
flags |= ScriptVerifyDERSignatures
|
flags |= ScriptVerifyDERSignatures
|
||||||
case "DISCOURAGE_UPGRADABLE_NOPS":
|
case "DISCOURAGE_UPGRADABLE_NOPS":
|
||||||
flags |= ScriptDiscourageUpgradableNops
|
flags |= ScriptDiscourageUpgradableNops
|
||||||
|
case "LOW_S":
|
||||||
|
flags |= ScriptVerifyLowS
|
||||||
case "MINIMALDATA":
|
case "MINIMALDATA":
|
||||||
flags |= ScriptVerifyMinimalData
|
flags |= ScriptVerifyMinimalData
|
||||||
case "NONE":
|
case "NONE":
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
|
@ -123,6 +124,11 @@ var (
|
||||||
// is over the limit.
|
// is over the limit.
|
||||||
ErrStackOverflow = errors.New("Stacks overflowed")
|
ErrStackOverflow = errors.New("Stacks overflowed")
|
||||||
|
|
||||||
|
// ErrStackInvalidLowSSignature is returned when the ScriptVerifyLowS
|
||||||
|
// flag is set and the script contains any signatures whose S values
|
||||||
|
// are higher than the half order.
|
||||||
|
ErrStackInvalidLowSSignature = errors.New("invalid low s signature")
|
||||||
|
|
||||||
// ErrStackInvalidPubKey is returned when the ScriptVerifyScriptEncoding
|
// ErrStackInvalidPubKey is returned when the ScriptVerifyScriptEncoding
|
||||||
// flag is set and the script contains invalid pubkeys.
|
// flag is set and the script contains invalid pubkeys.
|
||||||
ErrStackInvalidPubKey = errors.New("invalid strict pubkey")
|
ErrStackInvalidPubKey = errors.New("invalid strict pubkey")
|
||||||
|
@ -164,6 +170,9 @@ var ErrUnsupportedAddress = errors.New("unsupported address type")
|
||||||
// This timestamp corresponds to Sun Apr 1 00:00:00 UTC 2012.
|
// This timestamp corresponds to Sun Apr 1 00:00:00 UTC 2012.
|
||||||
var Bip16Activation = time.Unix(1333238400, 0)
|
var Bip16Activation = time.Unix(1333238400, 0)
|
||||||
|
|
||||||
|
// curve halforder, used to tame ECDSA malleability (see BIP0062)
|
||||||
|
var halfOrder = new(big.Int).Rsh(btcec.S256().N, 1)
|
||||||
|
|
||||||
// SigHashType represents hash type bits at the end of a signature.
|
// SigHashType represents hash type bits at the end of a signature.
|
||||||
type SigHashType byte
|
type SigHashType byte
|
||||||
|
|
||||||
|
@ -232,7 +241,8 @@ type Script struct {
|
||||||
discourageUpgradableNops bool // NOP1 to NOP10 are reserved for future soft-fork upgrades
|
discourageUpgradableNops bool // NOP1 to NOP10 are reserved for future soft-fork upgrades
|
||||||
verifyStrictEncoding bool // verify strict encoding of signatures
|
verifyStrictEncoding bool // verify strict encoding of signatures
|
||||||
verifyCleanStack bool // verify stack is clean after script evaluation
|
verifyCleanStack bool // verify stack is clean after script evaluation
|
||||||
verifyDERSignatures bool // verify signatures compily with the DER
|
verifyDERSignatures bool // verify signatures comply with the DER format
|
||||||
|
verifyLowS bool // verify signatures comply with the DER format and have an S value <= halforder
|
||||||
savedFirstStack [][]byte // stack from first script for bip16 scripts
|
savedFirstStack [][]byte // stack from first script for bip16 scripts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +398,7 @@ func (s *Script) checkPubKeyEncoding(pubKey []byte) error {
|
||||||
// checkSignatureEncoding returns whether or not the passed signature adheres to
|
// checkSignatureEncoding returns whether or not the passed signature adheres to
|
||||||
// the strict encoding requirements if enabled.
|
// the strict encoding requirements if enabled.
|
||||||
func (s *Script) checkSignatureEncoding(sig []byte) error {
|
func (s *Script) checkSignatureEncoding(sig []byte) error {
|
||||||
if !s.verifyStrictEncoding && !s.verifyDERSignatures {
|
if !s.verifyDERSignatures && !s.verifyLowS && !s.verifyStrictEncoding {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,6 +480,14 @@ func (s *Script) checkSignatureEncoding(sig []byte) error {
|
||||||
return fmt.Errorf("malformed signature: invalid S value")
|
return fmt.Errorf("malformed signature: invalid S value")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify the S value is <= halforder.
|
||||||
|
if s.verifyLowS {
|
||||||
|
sValue := new(big.Int).SetBytes(sig[rLen+6 : rLen+6+sLen])
|
||||||
|
if sValue.Cmp(halfOrder) > 0 {
|
||||||
|
return ErrStackInvalidLowSSignature
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,6 +662,11 @@ const (
|
||||||
// to compily with the DER format.
|
// to compily with the DER format.
|
||||||
ScriptVerifyDERSignatures
|
ScriptVerifyDERSignatures
|
||||||
|
|
||||||
|
// ScriptVerifyLowS defines that signtures are required to comply with
|
||||||
|
// the DER format and whose S value is <= order / 2. This is rule 5
|
||||||
|
// of BIP0062.
|
||||||
|
ScriptVerifyLowS
|
||||||
|
|
||||||
// ScriptVerifyMinimalData defines that signatures must use the smallest
|
// ScriptVerifyMinimalData defines that signatures must use the smallest
|
||||||
// push operator. This is both rules 3 and 4 of BIP0062.
|
// push operator. This is both rules 3 and 4 of BIP0062.
|
||||||
ScriptVerifyMinimalData
|
ScriptVerifyMinimalData
|
||||||
|
@ -737,6 +760,9 @@ func NewScript(scriptSig []byte, scriptPubKey []byte, txidx int, tx *wire.MsgTx,
|
||||||
}
|
}
|
||||||
m.verifyCleanStack = true
|
m.verifyCleanStack = true
|
||||||
}
|
}
|
||||||
|
if flags&ScriptVerifyLowS == ScriptVerifyLowS {
|
||||||
|
m.verifyLowS = true
|
||||||
|
}
|
||||||
|
|
||||||
m.tx = *tx
|
m.tx = *tx
|
||||||
m.txidx = txidx
|
m.txidx = txidx
|
||||||
|
|
Loading…
Add table
Reference in a new issue