github.com/chain5j/chain5j-pkg@v1.0.7/crypto/signature/prime256v1/signature_test.go (about)

     1  package prime256v1
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/elliptic"
     6  	"crypto/rand"
     7  	"crypto/sha256"
     8  	"encoding/hex"
     9  	"fmt"
    10  	"testing"
    11  
    12  	"github.com/chain5j/chain5j-pkg/util/hexutil"
    13  )
    14  
    15  type signatureTest struct {
    16  	name    string
    17  	sig     []byte
    18  	der     bool
    19  	isValid bool
    20  }
    21  
    22  var curve = elliptic.P256()
    23  
    24  // decodeHex decodes the passed hex string and returns the resulting bytes.  It
    25  // panics if an error occurs.  This is only used in the tests as a helper since
    26  // the only way it can fail is if there is an error in the test source code.
    27  func decodeHex(hexStr string) []byte {
    28  	b, err := hex.DecodeString(hexStr)
    29  	if err != nil {
    30  		panic("invalid hex string in test source: err " + err.Error() +
    31  			", hex: " + hexStr)
    32  	}
    33  
    34  	return b
    35  }
    36  
    37  func testSignCompact(priv *PrivateKey, tag string, data []byte, isCompressed bool) {
    38  	// priv, _ := GeneratePrivateKey()
    39  
    40  	hashed := []byte("testing")
    41  	sig, err := SignCompact(priv, hashed, isCompressed)
    42  	if err != nil {
    43  		fmt.Println(" error signing: ", tag, err)
    44  		return
    45  	}
    46  	fmt.Printf("签名长度%x,%d \n", sig, len(sig))
    47  
    48  	// 校验签名内容
    49  	key := priv.PublicKey
    50  	publicKey := NewPublicKey(curve, key.X, key.Y)
    51  	verify := VerifySignature(publicKey.ToECDSA(), hashed, sig[:64])
    52  
    53  	fmt.Println("签名校验", verify)
    54  
    55  	// fmt.Println("签名内容", hexutil.Encode(sig))
    56  
    57  	pk, wasCompressed, err := RecoverCompact(curve, sig, hashed)
    58  
    59  	fmt.Println("公钥", pk)
    60  	if err != nil {
    61  		fmt.Println(" error recovering: ", tag, err)
    62  		return
    63  	}
    64  	if pk.X.Cmp(priv.X) != 0 || pk.Y.Cmp(priv.Y) != 0 {
    65  		fmt.Println("%s: recovered pubkey doesn't match original "+
    66  			"(%v,%v) vs (%v,%v) ", tag, pk.X, pk.Y, priv.X, priv.Y)
    67  		return
    68  	}
    69  	if wasCompressed != isCompressed {
    70  		fmt.Println("%s: recovered pubkey doesn't match compressed state "+
    71  			"(%v vs %v)", tag, isCompressed, wasCompressed)
    72  		return
    73  	}
    74  
    75  	// If we change the compressed bit we should get the same key back,
    76  	// but the compressed flag should be reversed.
    77  	if isCompressed {
    78  		sig[len(sig)-1] -= 4
    79  	} else {
    80  		sig[len(sig)-1] += 4
    81  	}
    82  
    83  	pk, wasCompressed, err = RecoverCompact(curve, sig, hashed)
    84  	fmt.Println("恢复的公钥", pk)
    85  	if err != nil {
    86  		fmt.Println(" error recovering (2):", tag, err)
    87  		return
    88  	}
    89  	if pk.X.Cmp(priv.X) != 0 || pk.Y.Cmp(priv.Y) != 0 {
    90  		fmt.Println("%s: recovered pubkey (2) doesn't match original "+
    91  			"(%v,%v) vs (%v,%v) ", tag, pk.X, pk.Y, priv.X, priv.Y)
    92  		return
    93  	}
    94  	if wasCompressed == isCompressed {
    95  		fmt.Println("%s: recovered pubkey doesn't match reversed "+
    96  			"compressed state (%v vs %v)", tag, isCompressed,
    97  			wasCompressed)
    98  		return
    99  	}
   100  }
   101  
   102  func TestSignCompact(t *testing.T) {
   103  	priv1, _ := GeneratePrivateKey(curve)
   104  	t.Log("priv1.Serialize()", hexutil.Encode(priv1.Serialize()))
   105  
   106  	key := "cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50"
   107  	priv, _ := PrivKeyFromBytes(curve, decodeHex(key))
   108  
   109  	s := hex.EncodeToString(priv.Serialize())
   110  	fmt.Println("私钥String", s)
   111  
   112  	fmt.Println("私钥", priv.D)
   113  	fmt.Println("公钥", priv.PublicKey)
   114  	// fmt.Println("地址", crypto.PubkeyToAddress(priv.PublicKey))
   115  
   116  	// for i := 0; i < 256; i++ {
   117  	for i := 0; i < 1; i++ {
   118  		name := fmt.Sprintf("test %d", i)
   119  		data := make([]byte, 32)
   120  		_, err := rand.Read(data)
   121  		if err != nil {
   122  			t.Errorf("failed to read random data for %s", name)
   123  			continue
   124  		}
   125  		compressed := i%2 != 0
   126  		testSignCompact(priv, name, data, compressed)
   127  	}
   128  }
   129  
   130  func TestRFC6979(t *testing.T) {
   131  	// Test vectors matching Trezor and CoreBitcoin implementations.
   132  	// - https://github.com/trezor/trezor-crypto/blob/9fea8f8ab377dc514e40c6fd1f7c89a74c1d8dc6/tests.c#L432-L453
   133  	// - https://github.com/oleganza/CoreBitcoin/blob/e93dd71207861b5bf044415db5fa72405e7d8fbc/CoreBitcoin/BTCKey%2BTests.m#L23-L49
   134  	tests := []struct {
   135  		key       string
   136  		msg       string
   137  		nonce     string
   138  		signature string
   139  	}{
   140  		{
   141  			"cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50",
   142  			"sample",
   143  			"2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3",
   144  			"3045022100af340daf02cc15c8d5d08d7735dfe6b98a474ed373bdb5fbecf7571be52b384202205009fb27f37034a9b24b707b7c6b79ca23ddef9e25f7282e8a797efe53a8f124",
   145  		},
   146  		{
   147  			// This signature hits the case when S is higher than halforder.
   148  			// If S is not canonicalized (lowered by halforder), this test will fail.
   149  			"0000000000000000000000000000000000000000000000000000000000000001",
   150  			"Satoshi Nakamoto",
   151  			"8f8a276c19f4149656b280621e358cce24f5f52542772691ee69063b74f15d15",
   152  			"3045022100934b1ea10a4b3c1757e2b0c017d0b6143ce3c9a7e6a4a49860d7a6ab210ee3d802202442ce9d2b916064108014783e923ec36b49743e2ffa1c4496f01a512aafd9e5",
   153  		},
   154  		{
   155  			"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
   156  			"Satoshi Nakamoto",
   157  			"33a19b60e25fb6f4435af53a3d42d493644827367e6453928554f43e49aa6f90",
   158  			"3045022100fd567d121db66e382991534ada77a6bd3106f0a1098c231e47993447cd6af2d002206b39cd0eb1bc8603e159ef5c20a5c8ad685a45b06ce9bebed3f153d10d93bed5",
   159  		},
   160  		{
   161  			"f8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181",
   162  			"Alan Turing",
   163  			"525a82b70e67874398067543fd84c83d30c175fdc45fdeee082fe13b1d7cfdf1",
   164  			"304402207063ae83e7f62bbb171798131b4a0564b956930092b33b07b395615d9ec7e15c022058dfcc1e00a35e1572f366ffe34ba0fc47db1e7189759b9fb233c5b05ab388ea",
   165  		},
   166  		{
   167  			"0000000000000000000000000000000000000000000000000000000000000001",
   168  			"All those moments will be lost in time, like tears in rain. Time to die...",
   169  			"38aa22d72376b4dbc472e06c3ba403ee0a394da63fc58d88686c611aba98d6b3",
   170  			"30450221008600dbd41e348fe5c9465ab92d23e3db8b98b873beecd930736488696438cb6b0220547fe64427496db33bf66019dacbf0039c04199abb0122918601db38a72cfc21",
   171  		},
   172  		{
   173  			"e91671c46231f833a6406ccbea0e3e392c76c167bac1cb013f6f1013980455c2",
   174  			"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!",
   175  			"1f4b84c23a86a221d233f2521be018d9318639d5b8bbd6374a8a59232d16ad3d",
   176  			"3045022100b552edd27580141f3b2a5463048cb7cd3e047b97c9f98076c32dbdf85a68718b0220279fa72dd19bfae05577e06c7c0c1900c371fcd5893f7e1d56a37d30174671f6",
   177  		},
   178  	}
   179  
   180  	for i, test := range tests {
   181  		privKey, _ := PrivKeyFromBytes(curve, decodeHex(test.key))
   182  		hash := sha256.Sum256([]byte(test.msg))
   183  
   184  		// Ensure deterministically generated nonce is the expected value.
   185  		gotNonce := NonceRFC6979(curve, privKey.D, hash[:], nil, nil).Bytes()
   186  		wantNonce := decodeHex(test.nonce)
   187  		if !bytes.Equal(gotNonce, wantNonce) {
   188  			t.Errorf("NonceRFC6979 #%d (%s): Nonce is incorrect: "+
   189  				"%x (expected %x)", i, test.msg, gotNonce,
   190  				wantNonce)
   191  			continue
   192  		}
   193  
   194  		// Ensure deterministically generated signature is the expected value.
   195  		gotSig, err := privKey.Sign(hash[:])
   196  		if err != nil {
   197  			t.Errorf("Sign #%d (%s): unexpected error: %v", i,
   198  				test.msg, err)
   199  			continue
   200  		}
   201  		gotSigBytes := gotSig.Serialize()
   202  		wantSigBytes := decodeHex(test.signature)
   203  		if !bytes.Equal(gotSigBytes, wantSigBytes) {
   204  			t.Errorf("Sign #%d (%s): mismatched signature: %x "+
   205  				"(expected %x)", i, test.msg, gotSigBytes,
   206  				wantSigBytes)
   207  			continue
   208  		}
   209  	}
   210  }