kaspad/ecc/signature_test.go
stasatdaglabs f46dec449d [NOD-510] Change all references to Bitcoin to Kaspa (#531)
* [NOD-510] Change coinbase flags to kaspad.

* [NOD-510] Removed superfluous spaces after periods in comments.

* [NOD-510] Rename btcd -> kaspad in the root folder.

* [NOD-510] Rename BtcEncode -> KaspaEncode and BtcDecode -> KaspaDecode.

* [NOD-510] Rename BtcEncode -> KaspaEncode and BtcDecode -> KaspaDecode.

* [NOD-510] Continue renaming btcd -> kaspad.

* [NOD-510] Rename btcjson -> kaspajson.

* [NOD-510] Rename file names inside kaspajson.

* [NOD-510] Rename kaspajson -> jsonrpc.

* [NOD-510] Finish renaming in addrmgr.

* [NOD-510] Rename package btcec to ecc.

* [NOD-510] Finish renaming stuff in blockdag.

* [NOD-510] Rename stuff in cmd.

* [NOD-510] Rename stuff in config.

* [NOD-510] Rename stuff in connmgr.

* [NOD-510] Rename stuff in dagconfig.

* [NOD-510] Rename stuff in database.

* [NOD-510] Rename stuff in docker.

* [NOD-510] Rename stuff in integration.

* [NOD-510] Rename jsonrpc to rpcmodel.

* [NOD-510] Rename stuff in limits.

* [NOD-510] Rename stuff in logger.

* [NOD-510] Rename stuff in mempool.

* [NOD-510] Rename stuff in mining.

* [NOD-510] Rename stuff in netsync.

* [NOD-510] Rename stuff in peer.

* [NOD-510] Rename stuff in release.

* [NOD-510] Rename stuff in rpcclient.

* [NOD-510] Rename stuff in server.

* [NOD-510] Rename stuff in signal.

* [NOD-510] Rename stuff in txscript.

* [NOD-510] Rename stuff in util.

* [NOD-510] Rename stuff in wire.

* [NOD-510] Fix failing tests.

* [NOD-510] Fix merge errors.

* [NOD-510] Fix go vet errors.

* [NOD-510] Remove merged file that's no longer relevant.

* [NOD-510] Add a comment above Op0.

* [NOD-510] Fix some comments referencing Bitcoin Core.

* [NOD-510] Fix some more comments referencing Bitcoin Core.

* [NOD-510] Fix bitcoin -> kaspa.

* [NOD-510] Fix more bitcoin -> kaspa.

* [NOD-510] Fix comments, remove DisconnectBlock in addrindex.

* [NOD-510] Rename KSPD to KASD.

* [NOD-510] Fix comments and user agent.
2019-12-12 15:21:41 +02:00

270 lines
11 KiB
Go

// Copyright (c) 2013-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package ecc
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"testing"
)
type signatureTest struct {
name string
sig []byte
der bool
isValid bool
}
// decodeHex decodes the passed hex string and returns the resulting bytes. It
// panics if an error occurs. This is only used in the tests as a helper since
// the only way it can fail is if there is an error in the test source code.
func decodeHex(hexStr string) []byte {
b, err := hex.DecodeString(hexStr)
if err != nil {
panic("invalid hex string in test source: err " + err.Error() +
", hex: " + hexStr)
}
return b
}
func TestRFC6979(t *testing.T) {
// Test vectors matching Trezor and CoreBitcoin implementations.
// - https://github.com/trezor/trezor-crypto/blob/9fea8f8ab377dc514e40c6fd1f7c89a74c1d8dc6/tests.c#L432-L453
// - https://github.com/oleganza/CoreBitcoin/blob/e93dd71207861b5bf044415db5fa72405e7d8fbc/CoreBitcoin/BTCKey%2BTests.m#L23-L49
tests := []struct {
key string
msg string
nonce string
signature string
}{
{
"cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50",
"sample",
"bbed2b98f40ded8587b0615b8413d2aaf520215f369b098cea4ceec119b3f722",
"e8d6af55a53a1ac260c89aa247cc677a6219132f0d031530c75c22bffde442d894a5edc9cfffa4362f0b9f2af84f4cd13ae67b0b742d18c46eb85dac8eea6171",
},
{
// This signature hits the case when S is higher than halforder.
// If S is not canonicalized (lowered by halforder), this test will fail.
"0000000000000000000000000000000000000000000000000000000000000001",
"Satoshi Nakamoto",
"c2b802cb01789ed38de5cffd81a56374c39b7ee6f31bb36244650141bb3425fe",
"2f78a0720cf85bef9a24aef691fce02002c59381133ee543055d24222e2797cc78531f684122d541bbb4afe536e0b19236ad83e2e97a6277626aa5e0d1428f64",
},
{
"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
"Satoshi Nakamoto",
"b962c5b6537356a8b9362d6a275614df9711dff7b94d803b9ba5b5f2d4d90f8c",
"bebecd554a4c22ad202d074db855af4c974a55a5b9ef5ecf009eff232c806c63b9b37ef1d984feb2aa500777562d66f2ba468fab0491202ede12e76aa69d194a",
},
{
"f8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181",
"Alan Turing",
"65e72825561dd93f7a0ab53cdce97d5e57b2235c056e8b8396857425a6a8ff54",
"864487c21bc3a7823a9dbc99fc2a6de67cf7d7cf5f2feb6585319256393ff0f2192c3292df9979a01bf26f96017bc7e5f4a2e01fa5b9e1007af1a19a58f767d0",
},
{
"0000000000000000000000000000000000000000000000000000000000000001",
"All those moments will be lost in time, like tears in rain. Time to die...",
"60eb74b1fbc2db67be649f56246cee8c2225803155c86ff72f29641958de471a",
"66e3a89b2842c05cf57e5315bc2d063b1054979a4f0e5718ec5e0d68bde268296f855a1595aaa0625c822b526226a0e248fc0a1eae6f160cc97a783b8646b755",
},
{
"e91671c46231f833a6406ccbea0e3e392c76c167bac1cb013f6f1013980455c2",
"There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!",
"a1b518d7f2c6d9b68672f5e2b66fc872ef67a9b0b422d8b70ce0292017a62f60",
"c5290b3ecadc0ed0d674501ffc880f2f44b2ed829bfd101676f6fb55def15f23236ace4b651a52e9d590f421668e2b1b495c9039d27db848eb3edf1d1eb60d50",
},
}
for i, test := range tests {
privKey, _ := PrivKeyFromBytes(S256(), decodeHex(test.key))
hash := sha256.Sum256([]byte(test.msg))
// Ensure deterministically generated nonce is the expected value.
additionalData := []byte{'S', 'c', 'h', 'n', 'o', 'r', 'r', '+', 'S', 'H', 'A', '2', '5', '6', ' ', ' '}
gotNonce := nonceRFC6979(privKey.D, hash[:], additionalData).Bytes()
wantNonce := decodeHex(test.nonce)
if !bytes.Equal(gotNonce, wantNonce) {
t.Errorf("NonceRFC6979 #%d (%s): Nonce is incorrect: "+
"%x (expected %x)", i, test.msg, gotNonce,
wantNonce)
continue
}
// Ensure deterministically generated signature is the expected value.
gotSig, err := privKey.Sign(hash[:])
if err != nil {
t.Errorf("Sign #%d (%s): unexpected error: %v", i,
test.msg, err)
continue
}
gotSigBytes := gotSig.Serialize()
wantSigBytes := decodeHex(test.signature)
if !bytes.Equal(gotSigBytes, wantSigBytes) {
t.Errorf("Sign #%d (%s): mismatched signature: %x "+
"(expected %x)", i, test.msg, gotSigBytes,
wantSigBytes)
continue
}
}
}
func TestSignatureIsEqual(t *testing.T) {
sig1 := &Signature{
R: fromHex("0082235e21a2300022738dabb8e1bbd9d19cfb1e7ab8c30a23b0afbb8d178abcf3"),
S: fromHex("24bf68e256c534ddfaf966bf908deb944305596f7bdcc38d69acad7f9c868724"),
}
sig2 := &Signature{
R: fromHex("4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41"),
S: fromHex("181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09"),
}
if !sig1.IsEqual(sig1) {
t.Fatalf("value of IsEqual is incorrect, %v is "+
"equal to %v", sig1, sig1)
}
if sig1.IsEqual(sig2) {
t.Fatalf("value of IsEqual is incorrect, %v is not "+
"equal to %v", sig1, sig2)
}
}
func TestSchnorrSignatureVerify(t *testing.T) {
// Test vectors taken from https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr/test-vectors.csv
tests := []struct {
pubKey []byte
message []byte
signature []byte
valid bool
}{
{
decodeHex("0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"),
decodeHex("0000000000000000000000000000000000000000000000000000000000000000"),
decodeHex("787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF67031A98831859DC34DFFEEDDA86831842CCD0079E1F92AF177F7F22CC1DCED05"),
true,
},
{
decodeHex("02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
decodeHex("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
decodeHex("2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD"),
true,
},
{
decodeHex("03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B"),
decodeHex("5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C"),
decodeHex("00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380"),
true,
},
{
decodeHex("03DEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34"),
decodeHex("4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703"),
decodeHex("00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C6302A8DC32E64E86A333F20EF56EAC9BA30B7246D6D25E22ADB8C6BE1AEB08D49D"),
true,
},
{
decodeHex("031B84C5567B126440995D3ED5AABA0565D71E1834604819FF9C17F5E9D5DD078F"),
decodeHex("0000000000000000000000000000000000000000000000000000000000000000"),
decodeHex("52818579ACA59767E3291D91B76B637BEF062083284992F2D95F564CA6CB4E3530B1DA849C8E8304ADC0CFE870660334B3CFC18E825EF1DB34CFAE3DFC5D8187"),
true,
},
{
decodeHex("03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B"),
decodeHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
decodeHex("570DD4CA83D4E6317B8EE6BAE83467A1BF419D0767122DE409394414B05080DCE9EE5F237CBD108EABAE1E37759AE47F8E4203DA3532EB28DB860F33D62D49BD"),
true,
},
{
decodeHex("02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
decodeHex("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
decodeHex("2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1DFA16AEE06609280A19B67A24E1977E4697712B5FD2943914ECD5F730901B4AB7"),
false,
},
{
decodeHex("03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B"),
decodeHex("5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C"),
decodeHex("00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BED092F9D860F1776A1F7412AD8A1EB50DACCC222BC8C0E26B2056DF2F273EFDEC"),
false,
},
{
decodeHex("0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"),
decodeHex("0000000000000000000000000000000000000000000000000000000000000000"),
decodeHex("787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF68FCE5677CE7A623CB20011225797CE7A8DE1DC6CCD4F754A47DA6C600E59543C"),
false,
},
{
decodeHex("03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
decodeHex("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
decodeHex("2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD"),
false,
},
{
decodeHex("03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
decodeHex("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
decodeHex("00000000000000000000000000000000000000000000000000000000000000009E9D01AF988B5CEDCE47221BFA9B222721F3FA408915444A4B489021DB55775F"),
false,
},
{
decodeHex("03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
decodeHex("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
decodeHex("0000000000000000000000000000000000000000000000000000000000000001D37DDF0254351836D84B1BD6A795FD5D523048F298C4214D187FE4892947F728"),
false,
},
{
decodeHex("03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
decodeHex("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
decodeHex("4A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD"),
false,
},
{
decodeHex("03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
decodeHex("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
decodeHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2F1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD"),
false,
},
{
decodeHex("03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
decodeHex("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
decodeHex("2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"),
false,
},
}
for i, test := range tests {
pubkey, err := ParsePubKey(test.pubKey, S256())
if err != nil {
t.Fatal(err)
}
sig, err := ParseSignature(test.signature)
if err != nil {
t.Fatal(err)
}
valid := sig.Verify(test.message, pubkey)
if valid != test.valid {
t.Errorf("Schnorr test vector %d didn't produce correct result", i)
}
}
}
func TestDeterministicSchnorrSignatureGen(t *testing.T) {
// Test vector from Bitcoin-ABC
privKeyBytes := decodeHex("12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747")
privKey, _ := PrivKeyFromBytes(S256(), privKeyBytes)
h1 := sha256.Sum256([]byte("Very deterministic message"))
h2 := sha256.Sum256(h1[:])
sig, err := privKey.Sign(h2[:])
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(sig.R.Bytes(), decodeHex("2c56731ac2f7a7e7f11518fc7722a166b02438924ca9d8b4d111347b81d07175")) ||
!bytes.Equal(sig.S.Bytes(), decodeHex("71846de67ad3d913a8fdf9d8f3f73161a4c48ae81cb183b214765feb86e255ce")) {
t.Error("Failed to generate deterministic schnorr signature")
}
}