Example #1
0
//GetKeyFromWIF gets PublicKey and PrivateKey from private key of WIF format.
func GetKeyFromWIF(wif string) (*Key, error) {
	secp256k1 := btcec.S256()
	privateKeyBytes, isCmpressed, err := base58check.Decode(wif)
	if err != nil {
		return nil, err
	}

	pub := PublicKey{}
	priv := PrivateKey{}
	key := Key{
		Pub:  &pub,
		Priv: &priv,
	}
	switch privateKeyBytes[0] {
	case 0xef:
		pub.isTestnet = true
		priv.isTestnet = true
	case 0x80:
		pub.isTestnet = false
		priv.isTestnet = false
	default:
		return nil, errors.New("cannot determin net param from private key")
	}
	pub.isCompressed = isCmpressed

	//Get the raw public
	priv.key, pub.key = btcec.PrivKeyFromBytes(secp256k1, privateKeyBytes[1:])

	return &key, nil

}
Example #2
0
//GenerateKey generates random PublicKey and PrivateKey.
func GenerateKey(flagTestnet bool) (*Key, error) {
	seed := make([]byte, 32)
	_, err := rand.Read(seed)
	if err != nil {
		return nil, err
	}
	s256 := btcec.S256()

	private := PrivateKey{}
	private.isTestnet = flagTestnet
	public := PublicKey{}
	public.isTestnet = flagTestnet
	private.key, public.key = btcec.PrivKeyFromBytes(s256, seed)
	key := Key{
		Pub:  &public,
		Priv: &private,
	}

	//Print the keys
	logging.Println("Your private key in WIF is")
	logging.Println(private.GetWIFAddress())

	logging.Println("Your address is")
	logging.Println(public.GetAddress())

	return &key, nil
}
Example #3
0
func TestScalarMult(t *testing.T) {
	// Strategy for this test:
	// Get a random exponent from the generator point at first
	// This creates a new point which is used in the next iteration
	// Use another random exponent on the new point.
	// We use BaseMult to verify by multiplying the previous exponent
	// and the new random exponent together (mod N)
	s256 := btcec.S256()
	x, y := s256.Gx, s256.Gy
	exponent := big.NewInt(1)
	for i := 0; i < 1024; i++ {
		data := make([]byte, 32)
		_, err := rand.Read(data)
		if err != nil {
			t.Fatalf("failed to read random data at %d", i)
			break
		}
		x, y = s256.ScalarMult(x, y, data)
		exponent.Mul(exponent, new(big.Int).SetBytes(data))
		xWant, yWant := s256.ScalarBaseMult(exponent.Bytes())
		if x.Cmp(xWant) != 0 || y.Cmp(yWant) != 0 {
			t.Fatalf("%d: bad output for %X: got (%X, %X), want (%X, %X)", i, data, x, y, xWant, yWant)
			break
		}
	}
}
Example #4
0
func TestPubKeys(t *testing.T) {
	for _, test := range pubKeyTests {
		pk, err := btcec.ParsePubKey(test.key, btcec.S256())
		if err != nil {
			if test.isValid {
				t.Errorf("%s pubkey failed when shouldn't %v",
					test.name, err)
			}
			continue
		}
		if !test.isValid {
			t.Errorf("%s counted as valid when it should fail",
				test.name)
			continue
		}
		var pkStr []byte
		switch test.format {
		case btcec.TstPubkeyUncompressed:
			pkStr = (*btcec.PublicKey)(pk).SerializeUncompressed()
		case btcec.TstPubkeyCompressed:
			pkStr = (*btcec.PublicKey)(pk).SerializeCompressed()
		case btcec.TstPubkeyHybrid:
			pkStr = (*btcec.PublicKey)(pk).SerializeHybrid()
		}
		if !bytes.Equal(test.key, pkStr) {
			t.Errorf("%s pubkey: serialized keys do not match.",
				test.name)
			spew.Dump(test.key)
			spew.Dump(pkStr)
		}
	}
}
Example #5
0
//GetPublicKey returns PublicKey struct using public key hex string.
func GetPublicKey(pubKeyByte []byte, isTestnet bool) (*PublicKey, error) {
	secp256k1 := btcec.S256()
	key, err := btcec.ParsePubKey(pubKeyByte, secp256k1)
	if err != nil {
		return nil, err
	}
	return &PublicKey{key: key, isTestnet: isTestnet}, nil
}
Example #6
0
func TestPrivKeys(t *testing.T) {
	tests := []struct {
		name string
		key  []byte
	}{
		{
			name: "check curve",
			key: []byte{
				0xea, 0xf0, 0x2c, 0xa3, 0x48, 0xc5, 0x24, 0xe6,
				0x39, 0x26, 0x55, 0xba, 0x4d, 0x29, 0x60, 0x3c,
				0xd1, 0xa7, 0x34, 0x7d, 0x9d, 0x65, 0xcf, 0xe9,
				0x3c, 0xe1, 0xeb, 0xff, 0xdc, 0xa2, 0x26, 0x94,
			},
		},
	}

	for _, test := range tests {
		priv, pub := btcec.PrivKeyFromBytes(btcec.S256(), test.key)

		_, err := btcec.ParsePubKey(
			pub.SerializeUncompressed(), btcec.S256())
		if err != nil {
			t.Errorf("%s privkey: %v", test.name, err)
			continue
		}

		hash := []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9}
		sig, err := priv.Sign(hash)
		if err != nil {
			t.Errorf("%s could not sign: %v", test.name, err)
			continue
		}

		if !sig.Verify(hash, pub) {
			t.Errorf("%s could not verify: %v", test.name, err)
			continue
		}

		serializedKey := priv.Serialize()
		if !bytes.Equal(serializedKey, test.key) {
			t.Errorf("%s unexpected serialized bytes - got: %x, "+
				"want: %x", test.name, serializedKey, test.key)
		}
	}
}
Example #7
0
func TestGenerateSharedSecret(t *testing.T) {
	privKey1, err := btcec.NewPrivateKey(btcec.S256())
	if err != nil {
		t.Errorf("private key generation error: %s", err)
		return
	}
	privKey2, err := btcec.NewPrivateKey(btcec.S256())
	if err != nil {
		t.Errorf("private key generation error: %s", err)
		return
	}

	secret1 := btcec.GenerateSharedSecret(privKey1, privKey2.PubKey())
	secret2 := btcec.GenerateSharedSecret(privKey2, privKey1.PubKey())

	if !bytes.Equal(secret1, secret2) {
		t.Errorf("ECDH failed, secrets mismatch - first: %x, second: %x",
			secret1, secret2)
	}
}
Example #8
0
func main() {
	fi, err := os.Create("secp256k1.go")
	if err != nil {
		log.Fatal(err)
	}
	defer fi.Close()

	// Compress the serialized byte points.
	serialized := btcec.S256().SerializedBytePoints()
	var compressed bytes.Buffer
	w := zlib.NewWriter(&compressed)
	if _, err := w.Write(serialized); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	w.Close()

	// Encode the compressed byte points with base64.
	encoded := make([]byte, base64.StdEncoding.EncodedLen(compressed.Len()))
	base64.StdEncoding.Encode(encoded, compressed.Bytes())

	fmt.Fprintln(fi, "// Copyright (c) 2015 The btcsuite developers")
	fmt.Fprintln(fi, "// Use of this source code is governed by an ISC")
	fmt.Fprintln(fi, "// license that can be found in the LICENSE file.")
	fmt.Fprintln(fi)
	fmt.Fprintln(fi, "package btcec")
	fmt.Fprintln(fi)
	fmt.Fprintln(fi, "// Auto-generated file (see genprecomps.go)")
	fmt.Fprintln(fi, "// DO NOT EDIT")
	fmt.Fprintln(fi)
	fmt.Fprintf(fi, "var secp256k1BytePoints = %q\n", string(encoded))

	a1, b1, a2, b2 := btcec.S256().EndomorphismVectors()
	fmt.Println("The following values are the computed linearly " +
		"independent vectors needed to make use of the secp256k1 " +
		"endomorphism:")
	fmt.Printf("a1: %x\n", a1)
	fmt.Printf("b1: %x\n", b1)
	fmt.Printf("a2: %x\n", a2)
	fmt.Printf("b2: %x\n", b2)
}
Example #9
0
func TestSignCompact(t *testing.T) {
	for i := 0; i < 256; i++ {
		name := fmt.Sprintf("test %d", i)
		data := make([]byte, 32)
		_, err := rand.Read(data)
		if err != nil {
			t.Errorf("failed to read random data for %s", name)
			continue
		}
		compressed := i%2 != 0
		testSignCompact(t, name, btcec.S256(), data, compressed)
	}
}
Example #10
0
// CreateScriptSig signs a raw transaction with keys.
func (rs *RedeemScript) createScriptSig(rawTransactionHashed []byte, signs [][]byte) ([]byte, error) {

	//Verify that it worked.
	secp256k1 := btcec.S256()
	count := 0
	for i, signature := range signs {
		if signature == nil {
			continue
		}
		count++
		sig, err := btcec.ParseSignature(signature, secp256k1)
		if err != nil {
			return nil, err
		}
		valid := sig.Verify(rawTransactionHashed, rs.PublicKeys[i].key)
		if !valid {
			return nil, fmt.Errorf("number %d of signature is invalid", i)
		}
	}

	if count != rs.M {
		return nil, fmt.Errorf("number of signatures %d must be %d", count, rs.M)
	}

	//redeemScript length. To allow redeemScript > 255 bytes, we use OP_PUSHDATA2 and use two bytes to specify length
	var redeemScriptLengthBytes []byte
	var requiredPUSHDATA byte
	if len(rs.Script) < 255 {
		requiredPUSHDATA = opPUSHDATA1 //OP_PUSHDATA1 specifies next *one byte* will be length to be pushed to stack
		redeemScriptLengthBytes = []byte{byte(len(rs.Script))}
	} else {
		requiredPUSHDATA = opPUSHDATA2 //OP_PUSHDATA2 specifies next *two bytes* will be length to be pushed to stack
		redeemScriptLengthBytes = make([]byte, 2)
		binary.LittleEndian.PutUint16(redeemScriptLengthBytes, uint16(len(rs.Script)))
	}
	//Create scriptSig
	var buffer bytes.Buffer
	buffer.WriteByte(op0) //OP_0 for Multisig off-by-one error
	for _, signature := range signs {
		if signature == nil {
			continue
		}
		buffer.WriteByte(byte(len(signature) + 1)) //PUSH each signature. Add one for hash type byte
		buffer.Write(signature)                    // Signature bytes
		buffer.WriteByte(0x1)                      //hash type
	}
	buffer.WriteByte(requiredPUSHDATA)    //OP_PUSHDATA1 or OP_PUSHDATA2 depending on size of redeemScript
	buffer.Write(redeemScriptLengthBytes) //PUSH redeemScript
	buffer.Write(rs.Script)               //redeemScript
	return buffer.Bytes(), nil
}
Example #11
0
func TestSignatures(t *testing.T) {
	for _, test := range signatureTests {
		var err error
		if test.der {
			_, err = btcec.ParseDERSignature(test.sig, btcec.S256())
		} else {
			_, err = btcec.ParseSignature(test.sig, btcec.S256())
		}
		if err != nil {
			if test.isValid {
				t.Errorf("%s signature failed when shouldn't %v",
					test.name, err)
			} /* else {
				t.Errorf("%s got error %v", test.name, err)
			} */
			continue
		}
		if !test.isValid {
			t.Errorf("%s counted as valid when it should fail",
				test.name)
		}
	}
}
Example #12
0
//SignMessage sign using bitcoin sign struct
func (key *Key) SignMessage(hash []byte) ([]byte, error) {
	msg := make([]byte, 0)
	msg = append(msg, []byte("\x18Bitcoin Signed Message:\n")...)
	msg = append(msg, []byte{byte(len(hash))}...)
	msg = append(msg, hash...)
	h := sha256.Sum256(msg)
	hh := sha256.Sum256(h[:])
	s256 := btcec.S256()

	sig, err := btcec.SignCompact(s256, key.Priv.key, hh[:], key.Pub.isCompressed)
	if err != nil {
		return nil, err
	}
	return sig, nil
}
Example #13
0
//TODO: test different curves as well?
func TestBaseMult(t *testing.T) {
	s256 := btcec.S256()
	for i, e := range s256BaseMultTests {
		k, ok := new(big.Int).SetString(e.k, 16)
		if !ok {
			t.Errorf("%d: bad value for k: %s", i, e.k)
		}
		x, y := s256.ScalarBaseMult(k.Bytes())
		if fmt.Sprintf("%X", x) != e.x || fmt.Sprintf("%X", y) != e.y {
			t.Errorf("%d: bad output for k=%s: got (%X, %X), want (%s, %s)", i, e.k, x, y, e.x, e.y)
		}
		if testing.Short() && i > 5 {
			break
		}
	}
}
Example #14
0
func TestBaseMultVerify(t *testing.T) {
	s256 := btcec.S256()
	for bytes := 1; bytes < 40; bytes++ {
		for i := 0; i < 30; i++ {
			data := make([]byte, bytes)
			_, err := rand.Read(data)
			if err != nil {
				t.Errorf("failed to read random data for %d", i)
				continue
			}
			x, y := s256.ScalarBaseMult(data)
			xWant, yWant := s256.ScalarMult(s256.Gx, s256.Gy, data)
			if x.Cmp(xWant) != 0 || y.Cmp(yWant) != 0 {
				t.Errorf("%d: bad output for %X: got (%X, %X), want (%X, %X)", i, data, x, y, xWant, yWant)
			}
			if testing.Short() && i > 2 {
				break
			}
		}
	}
}
Example #15
0
// Test 2: Byte compatibility with Pyelliptic
func TestCiphering(t *testing.T) {
	pb, _ := hex.DecodeString("fe38240982f313ae5afb3e904fb8215fb11af1200592b" +
		"fca26c96c4738e4bf8f")
	privkey, _ := btcec.PrivKeyFromBytes(btcec.S256(), pb)

	in := []byte("This is just a test.")
	out, _ := hex.DecodeString("b0d66e5adaa5ed4e2f0ca68e17b8f2fc02ca002009e3" +
		"3487e7fa4ab505cf34d98f131be7bd258391588ca7804acb30251e71a04e0020ecf" +
		"df0f84608f8add82d7353af780fbb28868c713b7813eb4d4e61f7b75d7534dd9856" +
		"9b0ba77cf14348fcff80fee10e11981f1b4be372d93923e9178972f69937ec850ed" +
		"6c3f11ff572ddd5b2bedf9f9c0b327c54da02a28fcdce1f8369ffec")

	dec, err := btcec.Decrypt(privkey, out)
	if err != nil {
		t.Fatal("failed to decrypt:", err)
	}

	if !bytes.Equal(in, dec) {
		t.Error("decrypted data doesn't match original")
	}
}
Example #16
0
// Test 1: Encryption and decryption
func TestCipheringBasic(t *testing.T) {
	privkey, err := btcec.NewPrivateKey(btcec.S256())
	if err != nil {
		t.Fatal("failed to generate private key")
	}

	in := []byte("Hey there dude. How are you doing? This is a test.")

	out, err := btcec.Encrypt(privkey.PubKey(), in)
	if err != nil {
		t.Fatal("failed to encrypt:", err)
	}

	dec, err := btcec.Decrypt(privkey, out)
	if err != nil {
		t.Fatal("failed to decrypt:", err)
	}

	if !bytes.Equal(in, dec) {
		t.Error("decrypted data doesn't match original")
	}
}
Example #17
0
func TestVectors(t *testing.T) {
	sha := sha1.New()

	for i, test := range testVectors {
		pub := btcec.PublicKey{
			Curve: btcec.S256(),
			X:     fromHex(test.Qx),
			Y:     fromHex(test.Qy),
		}
		msg, _ := hex.DecodeString(test.msg)
		sha.Reset()
		sha.Write(msg)
		hashed := sha.Sum(nil)
		sig := btcec.Signature{R: fromHex(test.r), S: fromHex(test.s)}
		if f**k := sig.Verify(hashed, &pub); f**k != test.ok {
			//t.Errorf("%d: bad result %v %v", i, pub, hashed)
			t.Errorf("%d: bad result %v instead of %v", i, f**k,
				test.ok)
		}
		if testing.Short() {
			break
		}
	}
}
Example #18
0
func TestOnCurve(t *testing.T) {
	s256 := btcec.S256()
	if !s256.IsOnCurve(s256.Params().Gx, s256.Params().Gy) {
		t.Errorf("FAIL S256")
	}
}
Example #19
0
// TestDoubleAffine tests doubling of points in affine coordinates.
func TestDoubleAffine(t *testing.T) {
	tests := []struct {
		x1, y1 string // Coordinates (in hex) of point to double
		x3, y3 string // Coordinates (in hex) of expected point
	}{
		// Doubling a point at infinity is still infinity.
		// 2*∞ = ∞ (point at infinity)

		{
			"0",
			"0",
			"0",
			"0",
		},

		// Random points.
		{
			"e41387ffd8baaeeb43c2faa44e141b19790e8ac1f7ff43d480dc132230536f86",
			"1b88191d430f559896149c86cbcb703193105e3cf3213c0c3556399836a2b899",
			"88da47a089d333371bd798c548ef7caae76e737c1980b452d367b3cfe3082c19",
			"3b6f659b09a362821dfcfefdbfbc2e59b935ba081b6c249eb147b3c2100b1bc1",
		},
		{
			"b3589b5d984f03ef7c80aeae444f919374799edf18d375cab10489a3009cff0c",
			"c26cf343875b3630e15bccc61202815b5d8f1fd11308934a584a5babe69db36a",
			"e193860172998751e527bb12563855602a227fc1f612523394da53b746bb2fb1",
			"2bfcf13d2f5ab8bb5c611fab5ebbed3dc2f057062b39a335224c22f090c04789",
		},
		{
			"2b31a40fbebe3440d43ac28dba23eee71c62762c3fe3dbd88b4ab82dc6a82340",
			"9ba7deb02f5c010e217607fd49d58db78ec273371ea828b49891ce2fd74959a1",
			"2c8d5ef0d343b1a1a48aa336078eadda8481cb048d9305dc4fdf7ee5f65973a2",
			"bb4914ac729e26d3cd8f8dc8f702f3f4bb7e0e9c5ae43335f6e94c2de6c3dc95",
		},
		{
			"61c64b760b51981fab54716d5078ab7dffc93730b1d1823477e27c51f6904c7a",
			"ef6eb16ea1a36af69d7f66524c75a3a5e84c13be8fbc2e811e0563c5405e49bd",
			"5f0dcdd2595f5ad83318a0f9da481039e36f135005420393e72dfca985b482f4",
			"a01c849b0837065c1cb481b0932c441f49d1cab1b4b9f355c35173d93f110ae0",
		},
	}

	t.Logf("Running %d tests", len(tests))
	for i, test := range tests {
		// Convert hex to field values.
		x1, y1 := fromHex(test.x1), fromHex(test.y1)
		x3, y3 := fromHex(test.x3), fromHex(test.y3)

		// Ensure the test data is using points that are actually on
		// the curve (or the point at infinity).
		if !(x1.Sign() == 0 && y1.Sign() == 0) && !btcec.S256().IsOnCurve(x1, y1) {
			t.Errorf("#%d first point is not on the curve -- "+
				"invalid test data", i)
			continue
		}
		if !(x3.Sign() == 0 && y3.Sign() == 0) && !btcec.S256().IsOnCurve(x3, y3) {
			t.Errorf("#%d expected point is not on the curve -- "+
				"invalid test data", i)
			continue
		}

		// Double the point.
		rx, ry := btcec.S256().Double(x1, y1)

		// Ensure result matches expected.
		if rx.Cmp(x3) != 00 || ry.Cmp(y3) != 0 {
			t.Errorf("#%d wrong result\ngot: (%x, %x)\n"+
				"want: (%x, %x)", i, rx, ry, x3, y3)
			continue
		}
	}
}
Example #20
0
func TestSignAndVerify(t *testing.T) {
	testSignAndVerify(t, btcec.S256(), "S256")
}
Example #21
0
// TestSignatureSerialize ensures that serializing signatures works as expected.
func TestSignatureSerialize(t *testing.T) {
	tests := []struct {
		name     string
		ecsig    *btcec.Signature
		expected []byte
	}{
		// signature from bitcoin blockchain tx
		// 0437cd7f8525ceed2324359c2d0ba26006d92d85
		{
			"valid 1 - r and s most significant bits are zero",
			&btcec.Signature{
				R: fromHex("4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41"),
				S: fromHex("181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09"),
			},
			[]byte{
				0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
				0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3,
				0xa1, 0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32,
				0xe9, 0xd6, 0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab,
				0x5f, 0xb8, 0xcd, 0x41, 0x02, 0x20, 0x18, 0x15,
				0x22, 0xec, 0x8e, 0xca, 0x07, 0xde, 0x48, 0x60,
				0xa4, 0xac, 0xdd, 0x12, 0x90, 0x9d, 0x83, 0x1c,
				0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22, 0x08, 0x22,
				0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
			},
		},
		// signature from bitcoin blockchain tx
		// cb00f8a0573b18faa8c4f467b049f5d202bf1101d9ef2633bc611be70376a4b4
		{
			"valid 2 - r most significant bit is one",
			&btcec.Signature{
				R: fromHex("0082235e21a2300022738dabb8e1bbd9d19cfb1e7ab8c30a23b0afbb8d178abcf3"),
				S: fromHex("24bf68e256c534ddfaf966bf908deb944305596f7bdcc38d69acad7f9c868724"),
			},
			[]byte{
				0x30, 0x45, 0x02, 0x21, 0x00, 0x82, 0x23, 0x5e,
				0x21, 0xa2, 0x30, 0x00, 0x22, 0x73, 0x8d, 0xab,
				0xb8, 0xe1, 0xbb, 0xd9, 0xd1, 0x9c, 0xfb, 0x1e,
				0x7a, 0xb8, 0xc3, 0x0a, 0x23, 0xb0, 0xaf, 0xbb,
				0x8d, 0x17, 0x8a, 0xbc, 0xf3, 0x02, 0x20, 0x24,
				0xbf, 0x68, 0xe2, 0x56, 0xc5, 0x34, 0xdd, 0xfa,
				0xf9, 0x66, 0xbf, 0x90, 0x8d, 0xeb, 0x94, 0x43,
				0x05, 0x59, 0x6f, 0x7b, 0xdc, 0xc3, 0x8d, 0x69,
				0xac, 0xad, 0x7f, 0x9c, 0x86, 0x87, 0x24,
			},
		},
		// signature from bitcoin blockchain tx
		// fda204502a3345e08afd6af27377c052e77f1fefeaeb31bdd45f1e1237ca5470
		{
			"valid 3 - s most significant bit is one",
			&btcec.Signature{
				R: fromHex("1cadddc2838598fee7dc35a12b340c6bde8b389f7bfd19a1252a17c4b5ed2d71"),
				S: new(big.Int).Add(fromHex("00c1a251bbecb14b058a8bd77f65de87e51c47e95904f4c0e9d52eddc21c1415ac"), btcec.S256().N),
			},
			[]byte{
				0x30, 0x45, 0x02, 0x20, 0x1c, 0xad, 0xdd, 0xc2,
				0x83, 0x85, 0x98, 0xfe, 0xe7, 0xdc, 0x35, 0xa1,
				0x2b, 0x34, 0x0c, 0x6b, 0xde, 0x8b, 0x38, 0x9f,
				0x7b, 0xfd, 0x19, 0xa1, 0x25, 0x2a, 0x17, 0xc4,
				0xb5, 0xed, 0x2d, 0x71, 0x02, 0x21, 0x00, 0xc1,
				0xa2, 0x51, 0xbb, 0xec, 0xb1, 0x4b, 0x05, 0x8a,
				0x8b, 0xd7, 0x7f, 0x65, 0xde, 0x87, 0xe5, 0x1c,
				0x47, 0xe9, 0x59, 0x04, 0xf4, 0xc0, 0xe9, 0xd5,
				0x2e, 0xdd, 0xc2, 0x1c, 0x14, 0x15, 0xac,
			},
		},
		{
			"zero signature",
			&btcec.Signature{
				R: big.NewInt(0),
				S: big.NewInt(0),
			},
			[]byte{0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00},
		},
	}

	for i, test := range tests {
		result := test.ecsig.Serialize()
		if !bytes.Equal(result, test.expected) {
			t.Errorf("Serialize #%d (%s) unexpected result:\n"+
				"got:  %x\nwant: %x", i, test.name, result,
				test.expected)
		}
	}
}
Example #22
0
func TestKeyGeneration(t *testing.T) {
	testKeyGeneration(t, btcec.S256(), "S256")
}
Example #23
0
// TestAddJacobian tests addition of points projected in Jacobian coordinates.
func TestAddJacobian(t *testing.T) {
	tests := []struct {
		x1, y1, z1 string // Coordinates (in hex) of first point to add
		x2, y2, z2 string // Coordinates (in hex) of second point to add
		x3, y3, z3 string // Coordinates (in hex) of expected point
	}{
		// Addition with a point at infinity (left hand side).
		// ∞ + P = P
		{
			"0",
			"0",
			"0",
			"d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575",
			"131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d",
			"1",
			"d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575",
			"131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d",
			"1",
		},
		// Addition with a point at infinity (right hand side).
		// P + ∞ = P
		{
			"d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575",
			"131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d",
			"1",
			"0",
			"0",
			"0",
			"d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575",
			"131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d",
			"1",
		},

		// Addition with z1=z2=1 different x values.
		{
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232",
			"1",
			"d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575",
			"131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d",
			"1",
			"0cfbc7da1e569b334460788faae0286e68b3af7379d5504efc25e4dba16e46a6",
			"e205f79361bbe0346b037b4010985dbf4f9e1e955e7d0d14aca876bfa79aad87",
			"44a5646b446e3877a648d6d381370d9ef55a83b666ebce9df1b1d7d65b817b2f",
		},
		// Addition with z1=z2=1 same x opposite y.
		// P(x, y, z) + P(x, -y, z) = infinity
		{
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232",
			"1",
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"f48e156428cf0276dc092da5856e182288d7569f97934a56fe44be60f0d359fd",
			"1",
			"0",
			"0",
			"0",
		},
		// Addition with z1=z2=1 same point.
		// P(x, y, z) + P(x, y, z) = 2P
		{
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232",
			"1",
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232",
			"1",
			"ec9f153b13ee7bd915882859635ea9730bf0dc7611b2c7b0e37ee64f87c50c27",
			"b082b53702c466dcf6e984a35671756c506c67c2fcb8adb408c44dd0755c8f2a",
			"16e3d537ae61fb1247eda4b4f523cfbaee5152c0d0d96b520376833c1e594464",
		},

		// Addition with z1=z2 (!=1) different x values.
		{
			"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
			"5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190",
			"2",
			"5d2fe112c21891d440f65a98473cb626111f8a234d2cd82f22172e369f002147",
			"98e3386a0a622a35c4561ffb32308d8e1c6758e10ebb1b4ebd3d04b4eb0ecbe8",
			"2",
			"cfbc7da1e569b334460788faae0286e68b3af7379d5504efc25e4dba16e46a60",
			"817de4d86ef80d1ac0ded00426176fd3e787a5579f43452b2a1db021e6ac3778",
			"129591ad11b8e1de99235b4e04dc367bd56a0ed99baf3a77c6c75f5a6e05f08d",
		},
		// Addition with z1=z2 (!=1) same x opposite y.
		// P(x, y, z) + P(x, -y, z) = infinity
		{
			"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
			"5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190",
			"2",
			"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
			"a470ab21467813b6e0496d2c2b70c11446bab4fcbc9a52b7f225f30e869aea9f",
			"2",
			"0",
			"0",
			"0",
		},
		// Addition with z1=z2 (!=1) same point.
		// P(x, y, z) + P(x, y, z) = 2P
		{
			"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
			"5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190",
			"2",
			"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
			"5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190",
			"2",
			"9f153b13ee7bd915882859635ea9730bf0dc7611b2c7b0e37ee65073c50fabac",
			"2b53702c466dcf6e984a35671756c506c67c2fcb8adb408c44dd125dc91cb988",
			"6e3d537ae61fb1247eda4b4f523cfbaee5152c0d0d96b520376833c2e5944a11",
		},

		// Addition with z1!=z2 and z2=1 different x values.
		{
			"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
			"5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190",
			"2",
			"d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575",
			"131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d",
			"1",
			"3ef1f68795a6ccd1181e23eab80a1b9a2cebdcde755413bf097936eb5b91b4f3",
			"0bef26c377c068d606f6802130bb7e9f3c3d2abcfa1a295950ed81133561cb04",
			"252b235a2371c3bd3246b69c09b86cf7aad41db3375e74ef8d8ebeb4dc0be11a",
		},
		// Addition with z1!=z2 and z2=1 same x opposite y.
		// P(x, y, z) + P(x, -y, z) = infinity
		{
			"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
			"5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190",
			"2",
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"f48e156428cf0276dc092da5856e182288d7569f97934a56fe44be60f0d359fd",
			"1",
			"0",
			"0",
			"0",
		},
		// Addition with z1!=z2 and z2=1 same point.
		// P(x, y, z) + P(x, y, z) = 2P
		{
			"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
			"5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190",
			"2",
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232",
			"1",
			"9f153b13ee7bd915882859635ea9730bf0dc7611b2c7b0e37ee65073c50fabac",
			"2b53702c466dcf6e984a35671756c506c67c2fcb8adb408c44dd125dc91cb988",
			"6e3d537ae61fb1247eda4b4f523cfbaee5152c0d0d96b520376833c2e5944a11",
		},

		// Addition with z1!=z2 and z2!=1 different x values.
		// P(x, y, z) + P(x, y, z) = 2P
		{
			"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
			"5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190",
			"2",
			"91abba6a34b7481d922a4bd6a04899d5a686f6cf6da4e66a0cb427fb25c04bd4",
			"03fede65e30b4e7576a2abefc963ddbf9fdccbf791b77c29beadefe49951f7d1",
			"3",
			"3f07081927fd3f6dadd4476614c89a09eba7f57c1c6c3b01fa2d64eac1eef31e",
			"949166e04ebc7fd95a9d77e5dfd88d1492ecffd189792e3944eb2b765e09e031",
			"eb8cba81bcffa4f44d75427506737e1f045f21e6d6f65543ee0e1d163540c931",
		}, // Addition with z1!=z2 and z2!=1 same x opposite y.
		// P(x, y, z) + P(x, -y, z) = infinity
		{
			"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
			"5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190",
			"2",
			"dcc3768780c74a0325e2851edad0dc8a566fa61a9e7fc4a34d13dcb509f99bc7",
			"cafc41904dd5428934f7d075129c8ba46eb622d4fc88d72cd1401452664add18",
			"3",
			"0",
			"0",
			"0",
		},
		// Addition with z1!=z2 and z2!=1 same point.
		// P(x, y, z) + P(x, y, z) = 2P
		{
			"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
			"5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190",
			"2",
			"dcc3768780c74a0325e2851edad0dc8a566fa61a9e7fc4a34d13dcb509f99bc7",
			"3503be6fb22abd76cb082f8aed63745b9149dd2b037728d32ebfebac99b51f17",
			"3",
			"9f153b13ee7bd915882859635ea9730bf0dc7611b2c7b0e37ee65073c50fabac",
			"2b53702c466dcf6e984a35671756c506c67c2fcb8adb408c44dd125dc91cb988",
			"6e3d537ae61fb1247eda4b4f523cfbaee5152c0d0d96b520376833c2e5944a11",
		},
	}

	t.Logf("Running %d tests", len(tests))
	for i, test := range tests {
		// Convert hex to field values.
		x1 := btcec.NewFieldVal().SetHex(test.x1)
		y1 := btcec.NewFieldVal().SetHex(test.y1)
		z1 := btcec.NewFieldVal().SetHex(test.z1)
		x2 := btcec.NewFieldVal().SetHex(test.x2)
		y2 := btcec.NewFieldVal().SetHex(test.y2)
		z2 := btcec.NewFieldVal().SetHex(test.z2)
		x3 := btcec.NewFieldVal().SetHex(test.x3)
		y3 := btcec.NewFieldVal().SetHex(test.y3)
		z3 := btcec.NewFieldVal().SetHex(test.z3)

		// Ensure the test data is using points that are actually on
		// the curve (or the point at infinity).
		if !z1.IsZero() && !btcec.S256().TstIsJacobianOnCurve(x1, y1, z1) {
			t.Errorf("#%d first point is not on the curve -- "+
				"invalid test data", i)
			continue
		}
		if !z2.IsZero() && !btcec.S256().TstIsJacobianOnCurve(x2, y2, z2) {
			t.Errorf("#%d second point is not on the curve -- "+
				"invalid test data", i)
			continue
		}
		if !z3.IsZero() && !btcec.S256().TstIsJacobianOnCurve(x3, y3, z3) {
			t.Errorf("#%d expected point is not on the curve -- "+
				"invalid test data", i)
			continue
		}

		// Add the two points.
		rx, ry, rz := btcec.NewFieldVal(), btcec.NewFieldVal(), btcec.NewFieldVal()
		btcec.S256().TstAddJacobian(x1, y1, z1, x2, y2, z2, rx, ry, rz)

		// Ensure result matches expected.
		if !rx.Equals(x3) || !ry.Equals(y3) || !rz.Equals(z3) {
			t.Errorf("#%d wrong result\ngot: (%v, %v, %v)\n"+
				"want: (%v, %v, %v)", i, rx, ry, rz, x3, y3, z3)
			continue
		}
	}
}
Example #24
0
// TestAddAffine tests addition of points in affine coordinates.
func TestAddAffine(t *testing.T) {
	tests := []struct {
		x1, y1 string // Coordinates (in hex) of first point to add
		x2, y2 string // Coordinates (in hex) of second point to add
		x3, y3 string // Coordinates (in hex) of expected point
	}{
		// Addition with a point at infinity (left hand side).
		// ∞ + P = P
		{
			"0",
			"0",
			"d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575",
			"131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d",
			"d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575",
			"131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d",
		},
		// Addition with a point at infinity (right hand side).
		// P + ∞ = P
		{
			"d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575",
			"131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d",
			"0",
			"0",
			"d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575",
			"131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d",
		},

		// Addition with different x values.
		{
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232",
			"d74bf844b0862475103d96a611cf2d898447e288d34b360bc885cb8ce7c00575",
			"131c670d414c4546b88ac3ff664611b1c38ceb1c21d76369d7a7a0969d61d97d",
			"fd5b88c21d3143518d522cd2796f3d726793c88b3e05636bc829448e053fed69",
			"21cf4f6a5be5ff6380234c50424a970b1f7e718f5eb58f68198c108d642a137f",
		},
		// Addition with same x opposite y.
		// P(x, y) + P(x, -y) = infinity
		{
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232",
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"f48e156428cf0276dc092da5856e182288d7569f97934a56fe44be60f0d359fd",
			"0",
			"0",
		},
		// Addition with same point.
		// P(x, y) + P(x, y) = 2P
		{
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232",
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232",
			"59477d88ae64a104dbb8d31ec4ce2d91b2fe50fa628fb6a064e22582196b365b",
			"938dc8c0f13d1e75c987cb1a220501bd614b0d3dd9eb5c639847e1240216e3b6",
		},
	}

	t.Logf("Running %d tests", len(tests))
	for i, test := range tests {
		// Convert hex to field values.
		x1, y1 := fromHex(test.x1), fromHex(test.y1)
		x2, y2 := fromHex(test.x2), fromHex(test.y2)
		x3, y3 := fromHex(test.x3), fromHex(test.y3)

		// Ensure the test data is using points that are actually on
		// the curve (or the point at infinity).
		if !(x1.Sign() == 0 && y1.Sign() == 0) && !btcec.S256().IsOnCurve(x1, y1) {
			t.Errorf("#%d first point is not on the curve -- "+
				"invalid test data", i)
			continue
		}
		if !(x2.Sign() == 0 && y2.Sign() == 0) && !btcec.S256().IsOnCurve(x2, y2) {
			t.Errorf("#%d second point is not on the curve -- "+
				"invalid test data", i)
			continue
		}
		if !(x3.Sign() == 0 && y3.Sign() == 0) && !btcec.S256().IsOnCurve(x3, y3) {
			t.Errorf("#%d expected point is not on the curve -- "+
				"invalid test data", i)
			continue
		}

		// Add the two points.
		rx, ry := btcec.S256().Add(x1, y1, x2, y2)

		// Ensure result matches expected.
		if rx.Cmp(x3) != 00 || ry.Cmp(y3) != 0 {
			t.Errorf("#%d wrong result\ngot: (%x, %x)\n"+
				"want: (%x, %x)", i, rx, ry, x3, y3)
			continue
		}
	}
}
Example #25
0
// TestDoubleJacobian tests doubling of points projected in Jacobian
// coordinates.
func TestDoubleJacobian(t *testing.T) {
	tests := []struct {
		x1, y1, z1 string // Coordinates (in hex) of point to double
		x3, y3, z3 string // Coordinates (in hex) of expected point
	}{
		// Doubling a point at infinity is still infinity.
		{
			"0",
			"0",
			"0",
			"0",
			"0",
			"0",
		},
		// Doubling with z1=1.
		{
			"34f9460f0e4f08393d192b3c5133a6ba099aa0ad9fd54ebccfacdfa239ff49c6",
			"0b71ea9bd730fd8923f6d25a7a91e7dd7728a960686cb5a901bb419e0f2ca232",
			"1",
			"ec9f153b13ee7bd915882859635ea9730bf0dc7611b2c7b0e37ee64f87c50c27",
			"b082b53702c466dcf6e984a35671756c506c67c2fcb8adb408c44dd0755c8f2a",
			"16e3d537ae61fb1247eda4b4f523cfbaee5152c0d0d96b520376833c1e594464",
		},
		// Doubling with z1!=1.
		{
			"d3e5183c393c20e4f464acf144ce9ae8266a82b67f553af33eb37e88e7fd2718",
			"5b8f54deb987ec491fb692d3d48f3eebb9454b034365ad480dda0cf079651190",
			"2",
			"9f153b13ee7bd915882859635ea9730bf0dc7611b2c7b0e37ee65073c50fabac",
			"2b53702c466dcf6e984a35671756c506c67c2fcb8adb408c44dd125dc91cb988",
			"6e3d537ae61fb1247eda4b4f523cfbaee5152c0d0d96b520376833c2e5944a11",
		},
	}

	t.Logf("Running %d tests", len(tests))
	for i, test := range tests {
		// Convert hex to field values.
		x1 := btcec.NewFieldVal().SetHex(test.x1)
		y1 := btcec.NewFieldVal().SetHex(test.y1)
		z1 := btcec.NewFieldVal().SetHex(test.z1)
		x3 := btcec.NewFieldVal().SetHex(test.x3)
		y3 := btcec.NewFieldVal().SetHex(test.y3)
		z3 := btcec.NewFieldVal().SetHex(test.z3)

		// Ensure the test data is using points that are actually on
		// the curve (or the point at infinity).
		if !z1.IsZero() && !btcec.S256().TstIsJacobianOnCurve(x1, y1, z1) {
			t.Errorf("#%d first point is not on the curve -- "+
				"invalid test data", i)
			continue
		}
		if !z3.IsZero() && !btcec.S256().TstIsJacobianOnCurve(x3, y3, z3) {
			t.Errorf("#%d expected point is not on the curve -- "+
				"invalid test data", i)
			continue
		}

		// Double the point.
		rx, ry, rz := btcec.NewFieldVal(), btcec.NewFieldVal(), btcec.NewFieldVal()
		btcec.S256().TstDoubleJacobian(x1, y1, z1, rx, ry, rz)

		// Ensure result matches expected.
		if !rx.Equals(x3) || !ry.Equals(y3) || !rz.Equals(z3) {
			t.Errorf("#%d wrong result\ngot: (%v, %v, %v)\n"+
				"want: (%v, %v, %v)", i, rx, ry, rz, x3, y3, z3)
			continue
		}
	}
}
Example #26
0
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",
			"2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3",
			"3045022100af340daf02cc15c8d5d08d7735dfe6b98a474ed373bdb5fbecf7571be52b384202205009fb27f37034a9b24b707b7c6b79ca23ddef9e25f7282e8a797efe53a8f124",
		},
		{
			// 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",
			"8f8a276c19f4149656b280621e358cce24f5f52542772691ee69063b74f15d15",
			"3045022100934b1ea10a4b3c1757e2b0c017d0b6143ce3c9a7e6a4a49860d7a6ab210ee3d802202442ce9d2b916064108014783e923ec36b49743e2ffa1c4496f01a512aafd9e5",
		},
		{
			"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
			"Satoshi Nakamoto",
			"33a19b60e25fb6f4435af53a3d42d493644827367e6453928554f43e49aa6f90",
			"3045022100fd567d121db66e382991534ada77a6bd3106f0a1098c231e47993447cd6af2d002206b39cd0eb1bc8603e159ef5c20a5c8ad685a45b06ce9bebed3f153d10d93bed5",
		},
		{
			"f8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181",
			"Alan Turing",
			"525a82b70e67874398067543fd84c83d30c175fdc45fdeee082fe13b1d7cfdf1",
			"304402207063ae83e7f62bbb171798131b4a0564b956930092b33b07b395615d9ec7e15c022058dfcc1e00a35e1572f366ffe34ba0fc47db1e7189759b9fb233c5b05ab388ea",
		},
		{
			"0000000000000000000000000000000000000000000000000000000000000001",
			"All those moments will be lost in time, like tears in rain. Time to die...",
			"38aa22d72376b4dbc472e06c3ba403ee0a394da63fc58d88686c611aba98d6b3",
			"30450221008600dbd41e348fe5c9465ab92d23e3db8b98b873beecd930736488696438cb6b0220547fe64427496db33bf66019dacbf0039c04199abb0122918601db38a72cfc21",
		},
		{
			"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!",
			"1f4b84c23a86a221d233f2521be018d9318639d5b8bbd6374a8a59232d16ad3d",
			"3045022100b552edd27580141f3b2a5463048cb7cd3e047b97c9f98076c32dbdf85a68718b0220279fa72dd19bfae05577e06c7c0c1900c371fcd5893f7e1d56a37d30174671f6",
		},
	}

	for i, test := range tests {
		privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), decodeHex(test.key))
		hash := sha256.Sum256([]byte(test.msg))

		// Ensure deterministically generated nonce is the expected value.
		gotNonce := btcec.TstNonceRFC6979(privKey.D, hash[:]).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
		}
	}
}
Example #27
0
func TestCipheringErrors(t *testing.T) {
	privkey, err := btcec.NewPrivateKey(btcec.S256())
	if err != nil {
		t.Fatal("failed to generate private key")
	}

	tests1 := []struct {
		ciphertext []byte // input ciphertext
	}{
		{bytes.Repeat([]byte{0x00}, 133)},                   // errInputTooShort
		{bytes.Repeat([]byte{0x00}, 134)},                   // errUnsupportedCurve
		{bytes.Repeat([]byte{0x02, 0xCA}, 134)},             // errInvalidXLength
		{bytes.Repeat([]byte{0x02, 0xCA, 0x00, 0x20}, 134)}, // errInvalidYLength
		{[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // IV
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x02, 0xCA, 0x00, 0x20, // curve and X length
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // X
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x20, // Y length
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Y
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ciphertext
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // MAC
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		}}, // invalid pubkey
		{[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // IV
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x02, 0xCA, 0x00, 0x20, // curve and X length
			0x11, 0x5C, 0x42, 0xE7, 0x57, 0xB2, 0xEF, 0xB7, // X
			0x67, 0x1C, 0x57, 0x85, 0x30, 0xEC, 0x19, 0x1A,
			0x13, 0x59, 0x38, 0x1E, 0x6A, 0x71, 0x12, 0x7A,
			0x9D, 0x37, 0xC4, 0x86, 0xFD, 0x30, 0xDA, 0xE5,
			0x00, 0x20, // Y length
			0x7E, 0x76, 0xDC, 0x58, 0xF6, 0x93, 0xBD, 0x7E, // Y
			0x70, 0x10, 0x35, 0x8C, 0xE6, 0xB1, 0x65, 0xE4,
			0x83, 0xA2, 0x92, 0x10, 0x10, 0xDB, 0x67, 0xAC,
			0x11, 0xB1, 0xB5, 0x1B, 0x65, 0x19, 0x53, 0xD2,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ciphertext
			// padding not aligned to 16 bytes
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // MAC
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		}}, // errInvalidPadding
		{[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // IV
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x02, 0xCA, 0x00, 0x20, // curve and X length
			0x11, 0x5C, 0x42, 0xE7, 0x57, 0xB2, 0xEF, 0xB7, // X
			0x67, 0x1C, 0x57, 0x85, 0x30, 0xEC, 0x19, 0x1A,
			0x13, 0x59, 0x38, 0x1E, 0x6A, 0x71, 0x12, 0x7A,
			0x9D, 0x37, 0xC4, 0x86, 0xFD, 0x30, 0xDA, 0xE5,
			0x00, 0x20, // Y length
			0x7E, 0x76, 0xDC, 0x58, 0xF6, 0x93, 0xBD, 0x7E, // Y
			0x70, 0x10, 0x35, 0x8C, 0xE6, 0xB1, 0x65, 0xE4,
			0x83, 0xA2, 0x92, 0x10, 0x10, 0xDB, 0x67, 0xAC,
			0x11, 0xB1, 0xB5, 0x1B, 0x65, 0x19, 0x53, 0xD2,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ciphertext
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // MAC
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		}}, // ErrInvalidMAC
	}

	for i, test := range tests1 {
		_, err = btcec.Decrypt(privkey, test.ciphertext)
		if err == nil {
			t.Errorf("Decrypt #%d did not get error", i)
		}
	}

	// test error from removePKCSPadding
	tests2 := []struct {
		in []byte // input data
	}{
		{bytes.Repeat([]byte{0x11}, 17)},
		{bytes.Repeat([]byte{0x07}, 15)},
	}
	for i, test := range tests2 {
		_, err = btcec.TstRemovePKCSPadding(test.in)
		if err == nil {
			t.Errorf("removePKCSPadding #%d did not get error", i)
		}
	}
}