//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 }
//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 }
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 } } }
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) } } }
//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 }
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) } } }
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) } }
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) }
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) } }
// 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 }
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) } } }
//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 }
//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 } } }
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 } } } }
// 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") } }
// 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") } }
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 } } }
func TestOnCurve(t *testing.T) { s256 := btcec.S256() if !s256.IsOnCurve(s256.Params().Gx, s256.Params().Gy) { t.Errorf("FAIL S256") } }
// 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 } } }
func TestSignAndVerify(t *testing.T) { testSignAndVerify(t, btcec.S256(), "S256") }
// 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) } } }
func TestKeyGeneration(t *testing.T) { testKeyGeneration(t, btcec.S256(), "S256") }
// 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 } } }
// 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 } } }
// 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 } } }
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 } } }
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) } } }