Skip to content

Commit

Permalink
[#1028] Replace oldschnorr with the BIP340 schnorr variant (#1165)
Browse files Browse the repository at this point in the history
* Update go-secp256k1 to v0.0.3

* Update the txscript engine to support only 32 bytes pubkeys

* Update the txscript engine tests

* Update txscript/sign.go to use the new Schnorr KeyPair API

* Update txscript sign_test to use the new schnorr

* Update sigcache tests to use new schnorr pubkey

* Update integration tests to use the new txscript and new schnorr pubkey
  • Loading branch information
elichai authored Dec 1, 2020
1 parent 80c445c commit f1c6df4
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 397 deletions.
7 changes: 1 addition & 6 deletions domain/consensus/utils/txscript/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,12 +364,7 @@ func (vm *Engine) checkHashTypeEncoding(hashType SigHashType) error {
// checkPubKeyEncoding returns whether or not the passed public key adheres to
// the strict encoding requirements if enabled.
func (vm *Engine) checkPubKeyEncoding(pubKey []byte) error {
if len(pubKey) == 33 && (pubKey[0] == 0x02 || pubKey[0] == 0x03) {
// Compressed
return nil
}
if len(pubKey) == 65 && pubKey[0] == 0x04 {
// Uncompressed
if len(pubKey) == 32 {
return nil
}

Expand Down
19 changes: 12 additions & 7 deletions domain/consensus/utils/txscript/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,33 +163,38 @@ func TestCheckPubKeyEncoding(t *testing.T) {
isValid bool
}{
{
name: "uncompressed ok",
name: "uncompressed - invalid",
key: hexToBytes("0411db93e1dcdb8a016b49840f8c53bc1eb68" +
"a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf" +
"9744464f82e160bfa9b8b64f9d4c03f999b8643f656b" +
"412a3"),
isValid: true,
isValid: false,
},
{
name: "compressed ok",
name: "compressed - invalid",
key: hexToBytes("02ce0b14fb842b1ba549fdd675c98075f12e9" +
"c510f8ef52bd021a9a1f4809d3b4d"),
isValid: true,
isValid: false,
},
{
name: "compressed ok",
name: "compressed - invalid",
key: hexToBytes("032689c7c2dab13309fb143e0e8fe39634252" +
"1887e976690b6b47f5b2a4b7d448e"),
isValid: true,
isValid: false,
},
{
name: "hybrid",
name: "hybrid - invalid",
key: hexToBytes("0679be667ef9dcbbac55a06295ce870b07029" +
"bfcdb2dce28d959f2815b16f81798483ada7726a3c46" +
"55da4fbfc0e1108a8fd17b448a68554199c47d08ffb1" +
"0d4b8"),
isValid: false,
},
{
name: "32 bytes pubkey - Ok",
key: hexToBytes("2689c7c2dab13309fb143e0e8fe396342521887e976690b6b47f5b2a4b7d448e"),
isValid: true,
},
{
name: "empty",
key: nil,
Expand Down
16 changes: 8 additions & 8 deletions domain/consensus/utils/txscript/sigcache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ func TestSigCacheAddExists(t *testing.T) {

// The previously added triplet should now be found within the sigcache.
sig1Copy := secp256k1.DeserializeSchnorrSignature(sig1.Serialize())
key1Serialized, _ := key1.SerializeCompressed()
key1Copy, _ := secp256k1.DeserializeSchnorrPubKey(key1Serialized)
key1Serialized, _ := key1.Serialize()
key1Copy, _ := secp256k1.DeserializeSchnorrPubKey(key1Serialized[:])
if !sigCache.Exists(*msg1, sig1Copy, key1Copy) {
t.Errorf("previously added item not found in signature cache")
}
Expand All @@ -78,8 +78,8 @@ func TestSigCacheAddEvictEntry(t *testing.T) {
sigCache.Add(*msg, sig, key)

sigCopy := secp256k1.DeserializeSchnorrSignature(sig.Serialize())
keySerialized, _ := key.SerializeCompressed()
keyCopy, _ := secp256k1.DeserializeSchnorrPubKey(keySerialized)
keySerialized, _ := key.Serialize()
keyCopy, _ := secp256k1.DeserializeSchnorrPubKey(keySerialized[:])
if !sigCache.Exists(*msg, sigCopy, keyCopy) {
t.Errorf("previously added item not found in signature" +
"cache")
Expand Down Expand Up @@ -108,8 +108,8 @@ func TestSigCacheAddEvictEntry(t *testing.T) {

// The entry added above should be found within the sigcache.
sigNewCopy := secp256k1.DeserializeSchnorrSignature(sigNew.Serialize())
keyNewSerialized, _ := keyNew.SerializeCompressed()
keyNewCopy, _ := secp256k1.DeserializeSchnorrPubKey(keyNewSerialized)
keyNewSerialized, _ := keyNew.Serialize()
keyNewCopy, _ := secp256k1.DeserializeSchnorrPubKey(keyNewSerialized[:])
if !sigCache.Exists(*msgNew, sigNewCopy, keyNewCopy) {
t.Fatalf("previously added item not found in signature cache")
}
Expand All @@ -132,8 +132,8 @@ func TestSigCacheAddMaxEntriesZeroOrNegative(t *testing.T) {

// The generated triplet should not be found.
sig1Copy := secp256k1.DeserializeSchnorrSignature(sig1.Serialize())
key1Serialized, _ := key1.SerializeCompressed()
key1Copy, _ := secp256k1.DeserializeSchnorrPubKey(key1Serialized)
key1Serialized, _ := key1.Serialize()
key1Copy, _ := secp256k1.DeserializeSchnorrPubKey(key1Serialized[:])
if sigCache.Exists(*msg1, sig1Copy, key1Copy) {
t.Errorf("previously added signature found in sigcache, but" +
"shouldn't have been")
Expand Down
25 changes: 9 additions & 16 deletions domain/consensus/utils/txscript/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
// RawTxInSignature returns the serialized Schnorr signature for the input idx of
// the given transaction, with hashType appended to it.
func RawTxInSignature(tx *externalapi.DomainTransaction, idx int, script []byte,
hashType SigHashType, key *secp256k1.PrivateKey) ([]byte, error) {
hashType SigHashType, key *secp256k1.SchnorrKeyPair) ([]byte, error) {

hash, err := CalcSignatureHash(script, hashType, tx, idx)
if err != nil {
Expand All @@ -39,7 +39,7 @@ func RawTxInSignature(tx *externalapi.DomainTransaction, idx int, script []byte,
// as the idx'th input. privKey is serialized in either a compressed or
// uncompressed format based on compress. This format must match the same format
// used to generate the payment address, or the script validation will fail.
func SignatureScript(tx *externalapi.DomainTransaction, idx int, script []byte, hashType SigHashType, privKey *secp256k1.PrivateKey, compress bool) ([]byte, error) {
func SignatureScript(tx *externalapi.DomainTransaction, idx int, script []byte, hashType SigHashType, privKey *secp256k1.SchnorrKeyPair) ([]byte, error) {
sig, err := RawTxInSignature(tx, idx, script, hashType, privKey)
if err != nil {
return nil, err
Expand All @@ -49,17 +49,12 @@ func SignatureScript(tx *externalapi.DomainTransaction, idx int, script []byte,
if err != nil {
return nil, err
}
var pkData []byte
if compress {
pkData, err = pk.SerializeCompressed()
} else {
pkData, err = pk.SerializeUncompressed()
}
pkData, err := pk.Serialize()
if err != nil {
return nil, err
}

return NewScriptBuilder().AddData(sig).AddData(pkData).Script()
return NewScriptBuilder().AddData(sig).AddData(pkData[:]).Script()
}

func sign(dagParams *dagconfig.Params, tx *externalapi.DomainTransaction, idx int,
Expand All @@ -75,13 +70,12 @@ func sign(dagParams *dagconfig.Params, tx *externalapi.DomainTransaction, idx in
switch class {
case PubKeyHashTy:
// look up key for address
key, compressed, err := kdb.GetKey(address)
key, err := kdb.GetKey(address)
if err != nil {
return nil, class, nil, err
}

signedScript, err := SignatureScript(tx, idx, script, hashType,
key, compressed)
signedScript, err := SignatureScript(tx, idx, script, hashType, key)
if err != nil {
return nil, class, nil, err
}
Expand Down Expand Up @@ -162,15 +156,14 @@ func mergeScripts(dagParams *dagconfig.Params, tx *externalapi.DomainTransaction
// KeyDB is an interface type provided to SignTxOutput, it encapsulates
// any user state required to get the private keys for an address.
type KeyDB interface {
GetKey(util.Address) (*secp256k1.PrivateKey, bool, error)
GetKey(util.Address) (*secp256k1.SchnorrKeyPair, error)
}

// KeyClosure implements KeyDB with a closure.
type KeyClosure func(util.Address) (*secp256k1.PrivateKey, bool, error)
type KeyClosure func(util.Address) (*secp256k1.SchnorrKeyPair, error)

// GetKey implements KeyDB by returning the result of calling the closure.
func (kc KeyClosure) GetKey(address util.Address) (*secp256k1.PrivateKey,
bool, error) {
func (kc KeyClosure) GetKey(address util.Address) (*secp256k1.SchnorrKeyPair, error) {
return kc(address)
}

Expand Down
Loading

0 comments on commit f1c6df4

Please sign in to comment.