...

Source file src/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce_test.go

Documentation: github.com/decred/dcrd/dcrec/secp256k1/v4

     1  // Copyright (c) 2013-2016 The btcsuite developers
     2  // Copyright (c) 2015-2020 The Decred developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package secp256k1
     7  
     8  import (
     9  	"bytes"
    10  	"crypto/sha256"
    11  	"encoding/hex"
    12  	"testing"
    13  )
    14  
    15  // hexToBytes converts the passed hex string into bytes and will panic if there
    16  // is an error.  This is only provided for the hard-coded constants so errors in
    17  // the source code can be detected. It will only (and must only) be called with
    18  // hard-coded values.
    19  func hexToBytes(s string) []byte {
    20  	b, err := hex.DecodeString(s)
    21  	if err != nil {
    22  		panic("invalid hex in source file: " + s)
    23  	}
    24  	return b
    25  }
    26  
    27  // TestNonceRFC6979 ensures that the deterministic nonces generated by
    28  // NonceRFC6979 produces the expected nonces, including things such as when
    29  // providing extra data and version information, short hashes, and multiple
    30  // iterations.
    31  func TestNonceRFC6979(t *testing.T) {
    32  	tests := []struct {
    33  		name       string
    34  		key        string
    35  		hash       string
    36  		extraData  string
    37  		version    string
    38  		iterations uint32
    39  		expected   string
    40  	}{{
    41  		name:       "key 32 bytes, hash 32 bytes, no extra data, no version",
    42  		key:        "0011111111111111111111111111111111111111111111111111111111111111",
    43  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
    44  		iterations: 0,
    45  		expected:   "154e92760f77ad9af6b547edd6f14ad0fae023eb2221bc8be2911675d8a686a3",
    46  	}, {
    47  		// Should be same as key with 32 bytes due to zero padding.
    48  		name:       "key <32 bytes, hash 32 bytes, no extra data, no version",
    49  		key:        "11111111111111111111111111111111111111111111111111111111111111",
    50  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
    51  		iterations: 0,
    52  		expected:   "154e92760f77ad9af6b547edd6f14ad0fae023eb2221bc8be2911675d8a686a3",
    53  	}, {
    54  		// Should be same as key with 32 bytes due to truncation.
    55  		name:       "key >32 bytes, hash 32 bytes, no extra data, no version",
    56  		key:        "001111111111111111111111111111111111111111111111111111111111111111",
    57  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
    58  		iterations: 0,
    59  		expected:   "154e92760f77ad9af6b547edd6f14ad0fae023eb2221bc8be2911675d8a686a3",
    60  	}, {
    61  		name:       "hash <32 bytes (padded), no extra data, no version",
    62  		key:        "0011111111111111111111111111111111111111111111111111111111111111",
    63  		hash:       "00000000000000000000000000000000000000000000000000000000000001",
    64  		iterations: 0,
    65  		expected:   "154e92760f77ad9af6b547edd6f14ad0fae023eb2221bc8be2911675d8a686a3",
    66  	}, {
    67  		name:       "hash >32 bytes (truncated), no extra data, no version",
    68  		key:        "0011111111111111111111111111111111111111111111111111111111111111",
    69  		hash:       "000000000000000000000000000000000000000000000000000000000000000100",
    70  		iterations: 0,
    71  		expected:   "154e92760f77ad9af6b547edd6f14ad0fae023eb2221bc8be2911675d8a686a3",
    72  	}, {
    73  		name:       "hash 32 bytes, extra data <32 bytes (ignored), no version",
    74  		key:        "0011111111111111111111111111111111111111111111111111111111111111",
    75  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
    76  		extraData:  "00000000000000000000000000000000000000000000000000000000000002",
    77  		iterations: 0,
    78  		expected:   "154e92760f77ad9af6b547edd6f14ad0fae023eb2221bc8be2911675d8a686a3",
    79  	}, {
    80  		name:       "hash 32 bytes, extra data >32 bytes (ignored), no version",
    81  		key:        "0011111111111111111111111111111111111111111111111111111111111111",
    82  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
    83  		extraData:  "000000000000000000000000000000000000000000000000000000000000000002",
    84  		iterations: 0,
    85  		expected:   "154e92760f77ad9af6b547edd6f14ad0fae023eb2221bc8be2911675d8a686a3",
    86  	}, {
    87  		name:       "hash 32 bytes, no extra data, version <16 bytes (ignored)",
    88  		key:        "0011111111111111111111111111111111111111111111111111111111111111",
    89  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
    90  		version:    "000000000000000000000000000003",
    91  		iterations: 0,
    92  		expected:   "154e92760f77ad9af6b547edd6f14ad0fae023eb2221bc8be2911675d8a686a3",
    93  	}, {
    94  		name:       "hash 32 bytes, no extra data, version >16 bytes (ignored)",
    95  		key:        "001111111111111111111111111111111111111111111111111111111111111122",
    96  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
    97  		version:    "0000000000000000000000000000000003",
    98  		iterations: 0,
    99  		expected:   "154e92760f77ad9af6b547edd6f14ad0fae023eb2221bc8be2911675d8a686a3",
   100  	}, {
   101  		name:       "hash 32 bytes, extra data 32 bytes, no version",
   102  		key:        "0011111111111111111111111111111111111111111111111111111111111111",
   103  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
   104  		extraData:  "0000000000000000000000000000000000000000000000000000000000000002",
   105  		iterations: 0,
   106  		expected:   "67893461ade51cde61824b20bc293b585d058e6b9f40fb68453d5143f15116ae",
   107  	}, {
   108  		name:       "hash 32 bytes, no extra data, version 16 bytes",
   109  		key:        "0011111111111111111111111111111111111111111111111111111111111111",
   110  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
   111  		version:    "00000000000000000000000000000003",
   112  		iterations: 0,
   113  		expected:   "7b27d6ceff87e1ded1860ca4e271a530e48514b9d3996db0af2bb8bda189007d",
   114  	}, {
   115  		// Should be same as no extra data + version specified due to padding.
   116  		name:       "hash 32 bytes, extra data 32 bytes all zero, version 16 bytes",
   117  		key:        "0011111111111111111111111111111111111111111111111111111111111111",
   118  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
   119  		extraData:  "0000000000000000000000000000000000000000000000000000000000000000",
   120  		version:    "00000000000000000000000000000003",
   121  		iterations: 0,
   122  		expected:   "7b27d6ceff87e1ded1860ca4e271a530e48514b9d3996db0af2bb8bda189007d",
   123  	}, {
   124  		name:       "hash 32 bytes, extra data 32 bytes, version 16 bytes",
   125  		key:        "0011111111111111111111111111111111111111111111111111111111111111",
   126  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
   127  		extraData:  "0000000000000000000000000000000000000000000000000000000000000002",
   128  		version:    "00000000000000000000000000000003",
   129  		iterations: 0,
   130  		expected:   "9b5657643dfd4b77d99dfa505ed8a17e1b9616354fc890669b4aabece2170686",
   131  	}, {
   132  		name:       "hash 32 bytes, no extra data, no version, extra iteration",
   133  		key:        "0011111111111111111111111111111111111111111111111111111111111111",
   134  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
   135  		iterations: 1,
   136  		expected:   "66fca3fe494a6216e4a3f15cfbc1d969c60d9cdefda1a1c193edabd34aa8cd5e",
   137  	}, {
   138  		name:       "hash 32 bytes, no extra data, no version, 2 extra iterations",
   139  		key:        "0011111111111111111111111111111111111111111111111111111111111111",
   140  		hash:       "0000000000000000000000000000000000000000000000000000000000000001",
   141  		iterations: 2,
   142  		expected:   "70da248c92b5d28a52eafca1848b1a37d4cb36526c02553c9c48bb0b895fc77d",
   143  	}}
   144  
   145  	for _, test := range tests {
   146  		privKey := hexToBytes(test.key)
   147  		hash := hexToBytes(test.hash)
   148  		extraData := hexToBytes(test.extraData)
   149  		version := hexToBytes(test.version)
   150  		wantNonce := hexToBytes(test.expected)
   151  
   152  		// Ensure deterministically generated nonce is the expected value.
   153  		gotNonce := NonceRFC6979(privKey, hash[:], extraData, version,
   154  			test.iterations)
   155  		gotNonceBytes := gotNonce.Bytes()
   156  		if !bytes.Equal(gotNonceBytes[:], wantNonce) {
   157  			t.Errorf("%s: unexpected nonce -- got %x, want %x", test.name,
   158  				gotNonceBytes, wantNonce)
   159  			continue
   160  		}
   161  	}
   162  }
   163  
   164  // TestRFC6979Compat ensures that the deterministic nonces generated by
   165  // NonceRFC6979 produces the expected nonces for known values from other
   166  // implementations.
   167  func TestRFC6979Compat(t *testing.T) {
   168  	// Test vectors matching Trezor and CoreBitcoin implementations.
   169  	// - https://github.com/trezor/trezor-crypto/blob/9fea8f8ab377dc514e40c6fd1f7c89a74c1d8dc6/tests.c#L432-L453
   170  	// - https://github.com/oleganza/CoreBitcoin/blob/e93dd71207861b5bf044415db5fa72405e7d8fbc/CoreBitcoin/BTCKey%2BTests.m#L23-L49
   171  	tests := []struct {
   172  		key   string
   173  		msg   string
   174  		nonce string
   175  	}{{
   176  		"cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50",
   177  		"sample",
   178  		"2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3",
   179  	}, {
   180  		// This signature hits the case when S is higher than halforder.
   181  		// If S is not canonicalized (lowered by halforder), this test will fail.
   182  		"0000000000000000000000000000000000000000000000000000000000000001",
   183  		"Satoshi Nakamoto",
   184  		"8f8a276c19f4149656b280621e358cce24f5f52542772691ee69063b74f15d15",
   185  	}, {
   186  		"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
   187  		"Satoshi Nakamoto",
   188  		"33a19b60e25fb6f4435af53a3d42d493644827367e6453928554f43e49aa6f90",
   189  	}, {
   190  		"f8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181",
   191  		"Alan Turing",
   192  		"525a82b70e67874398067543fd84c83d30c175fdc45fdeee082fe13b1d7cfdf1",
   193  	}, {
   194  		"0000000000000000000000000000000000000000000000000000000000000001",
   195  		"All those moments will be lost in time, like tears in rain. Time to die...",
   196  		"38aa22d72376b4dbc472e06c3ba403ee0a394da63fc58d88686c611aba98d6b3",
   197  	}, {
   198  		"e91671c46231f833a6406ccbea0e3e392c76c167bac1cb013f6f1013980455c2",
   199  		"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!",
   200  		"1f4b84c23a86a221d233f2521be018d9318639d5b8bbd6374a8a59232d16ad3d",
   201  	}}
   202  
   203  	for i, test := range tests {
   204  		privKey := hexToBytes(test.key)
   205  		hash := sha256.Sum256([]byte(test.msg))
   206  
   207  		// Ensure deterministically generated nonce is the expected value.
   208  		gotNonce := NonceRFC6979(privKey, hash[:], nil, nil, 0)
   209  		wantNonce := hexToBytes(test.nonce)
   210  		gotNonceBytes := gotNonce.Bytes()
   211  		if !bytes.Equal(gotNonceBytes[:], wantNonce) {
   212  			t.Errorf("NonceRFC6979 #%d (%s): Nonce is incorrect: "+
   213  				"%x (expected %x)", i, test.msg, gotNonce,
   214  				wantNonce)
   215  			continue
   216  		}
   217  	}
   218  }
   219  

View as plain text