// isPubKey returns whether or not the passed public key script is a standard // pay-to-pubkey script that pays to a valid compressed or uncompressed public // key along with the serialized pubkey it is paying to if it is. // // NOTE: This function ensures the public key is actually valid since the // compression algorithm requires valid pubkeys. It does not support hybrid // pubkeys. This means that even if the script has the correct form for a // pay-to-pubkey script, this function will only return true when it is paying // to a valid compressed or uncompressed pubkey. func isPubKey(script []byte) (bool, []byte) { // Pay-to-compressed-pubkey script. if len(script) == 35 && script[0] == txscript.OP_DATA_33 && script[34] == txscript.OP_CHECKSIG && (script[1] == 0x02 || script[1] == 0x03) { // Ensure the public key is valid. serializedPubKey := script[1:34] _, err := btcec.ParsePubKey(serializedPubKey, btcec.S256()) if err == nil { return true, serializedPubKey } } // Pay-to-uncompressed-pubkey script. if len(script) == 67 && script[0] == txscript.OP_DATA_65 && script[66] == txscript.OP_CHECKSIG && script[1] == 0x04 { // Ensure the public key is valid. serializedPubKey := script[1:66] _, err := btcec.ParsePubKey(serializedPubKey, btcec.S256()) if err == nil { return true, serializedPubKey } } return false, nil }
func TestPublicKeyIsEqual(t *testing.T) { pubKey1, err := btcec.ParsePubKey( []byte{0x03, 0x26, 0x89, 0xc7, 0xc2, 0xda, 0xb1, 0x33, 0x09, 0xfb, 0x14, 0x3e, 0x0e, 0x8f, 0xe3, 0x96, 0x34, 0x25, 0x21, 0x88, 0x7e, 0x97, 0x66, 0x90, 0xb6, 0xb4, 0x7f, 0x5b, 0x2a, 0x4b, 0x7d, 0x44, 0x8e, }, btcec.S256(), ) if err != nil { t.Fatalf("failed to parse raw bytes for pubKey1: %v", err) } pubKey2, err := btcec.ParsePubKey( []byte{0x02, 0xce, 0x0b, 0x14, 0xfb, 0x84, 0x2b, 0x1b, 0xa5, 0x49, 0xfd, 0xd6, 0x75, 0xc9, 0x80, 0x75, 0xf1, 0x2e, 0x9c, 0x51, 0x0f, 0x8e, 0xf5, 0x2b, 0xd0, 0x21, 0xa9, 0xa1, 0xf4, 0x80, 0x9d, 0x3b, 0x4d, }, btcec.S256(), ) if err != nil { t.Fatalf("failed to parse raw bytes for pubKey2: %v", err) } if !pubKey1.IsEqual(pubKey1) { t.Fatalf("value of IsEqual is incorrect, %v is "+ "equal to %v", pubKey1, pubKey1) } if pubKey1.IsEqual(pubKey2) { t.Fatalf("value of IsEqual is incorrect, %v is not "+ "equal to %v", pubKey1, pubKey2) } }
// TestSigCacheAddMaxEntriesZeroOrNegative tests that if a sigCache is created // with a max size <= 0, then no entries are added to the sigcache at all. func TestSigCacheAddMaxEntriesZeroOrNegative(t *testing.T) { // Create a sigcache that can hold up to 0 entries. sigCache := NewSigCache(0) // Generate a random sigCache entry triplet. msg1, sig1, key1, err := genRandomSig() if err != nil { t.Errorf("unable to generate random signature test data") } // Add the triplet to the signature cache. sigCache.Add(*msg1, sig1, key1) // The generated triplet should not be found. sig1Copy, _ := btcec.ParseSignature(sig1.Serialize(), btcec.S256()) key1Copy, _ := btcec.ParsePubKey(key1.SerializeCompressed(), btcec.S256()) if sigCache.Exists(*msg1, sig1Copy, key1Copy) { t.Errorf("previously added signature found in sigcache, but" + "shouldn't have been") } // There shouldn't be any entries in the sigCache. if len(sigCache.validSigs) != 0 { t.Errorf("%v items found in sigcache, no items should have"+ "been added", len(sigCache.validSigs)) } }
// GetIdentity returns the public identity corresponding to the given address // if it exists. func (c *Client) GetIdentity(address string) (*identity.Public, error) { addr, err := bmutil.DecodeAddress(address) if err != nil { return nil, fmt.Errorf("Address decode failed: %v", addr) } res, err := c.bmd.GetIdentity(context.Background(), &pb.GetIdentityRequest{ Address: address, }) if grpc.Code(err) == codes.NotFound { return nil, ErrIdentityNotFound } else if err != nil { return nil, err } signKey, err := btcec.ParsePubKey(res.SigningKey, btcec.S256()) if err != nil { return nil, err } encKey, err := btcec.ParsePubKey(res.EncryptionKey, btcec.S256()) if err != nil { return nil, err } return identity.NewPublic(signKey, encKey, &pow.Data{ res.NonceTrials, res.ExtraBytes, }, addr.Version, addr.Stream), nil }
//Deriving Child public Key from Public Parent Key func (parent *ExtendedPublicKey) CKDpub(index uint32) (*ExtendedPublicKey, error) { if index >= HardenedKeyIndex { return nil, nil } // let I = HMAC-SHA512(Key = cpar, Data = serP(Kpar) || ser32(i)). //serP(P): serializes the coordinate pair P = (x,y) as a byte sequence using SEC1's //compressed form: (0x02 or 0x03) || ser256(x) <-- done above //, where the header byte depends on the parity of the omitted y coordinate. data := make([]byte, 37) copy(data[0:], parent.PublicKey) binary.BigEndian.PutUint32(data[33:], index) hmac512 := hmac.New(sha512.New, parent.Chaincode) hmac512.Write(data) raw := hmac512.Sum(nil) //child Chaincode is the right 32 bytes of the result childChaincode := raw[32:] // The returned child key Ki is point(parse256(IL)) + Kpar leftX, leftY := Point(raw[:32]) x1 := new(big.Int).SetBytes(leftX) y1 := new(big.Int).SetBytes(leftY) x2 := new(big.Int).SetBytes(parent.X) y2 := new(big.Int).SetBytes(parent.Y) childX, childY := btcec.S256().Add(x1, y1, x2, y2) ParentFingerPrint := parent.GetFingerPrint() depthBytes := []byte{parent.Depth} depthInt := new(big.Int).SetBytes(depthBytes) depthInt.Add(depthInt, big.NewInt(1)) depth := depthInt.Bytes() publicKey := btcec.PublicKey{Curve: btcec.S256(), X: childX, Y: childY} childExtendedPublicKey := NewExtendedPublicKey(childX.Bytes(), childY.Bytes(), depth[len(depth)-1], ParentFingerPrint, index, childChaincode, publicKey.SerializeCompressed()) return childExtendedPublicKey, nil }
func TestEncodeDecodeWIF(t *testing.T) { priv1, _ := btcec.PrivKeyFromBytes(btcec.S256(), []byte{ 0x0c, 0x28, 0xfc, 0xa3, 0x86, 0xc7, 0xa2, 0x27, 0x60, 0x0b, 0x2f, 0xe5, 0x0b, 0x7c, 0xae, 0x11, 0xec, 0x86, 0xd3, 0xbf, 0x1f, 0xbe, 0x47, 0x1b, 0xe8, 0x98, 0x27, 0xe1, 0x9d, 0x72, 0xaa, 0x1d}) priv2, _ := btcec.PrivKeyFromBytes(btcec.S256(), []byte{ 0xdd, 0xa3, 0x5a, 0x14, 0x88, 0xfb, 0x97, 0xb6, 0xeb, 0x3f, 0xe6, 0xe9, 0xef, 0x2a, 0x25, 0x81, 0x4e, 0x39, 0x6f, 0xb5, 0xdc, 0x29, 0x5f, 0xe9, 0x94, 0xb9, 0x67, 0x89, 0xb2, 0x1a, 0x03, 0x98}) wif1, err := NewWIF(priv1, &chaincfg.MainNetParams, false) if err != nil { t.Fatal(err) } wif2, err := NewWIF(priv2, &chaincfg.TestNet3Params, true) if err != nil { t.Fatal(err) } tests := []struct { wif *WIF encoded string }{ { wif1, "5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ", }, { wif2, "cV1Y7ARUr9Yx7BR55nTdnR7ZXNJphZtCCMBTEZBJe1hXt2kB684q", }, } for _, test := range tests { // Test that encoding the WIF structure matches the expected string. s := test.wif.String() if s != test.encoded { t.Errorf("TestEncodeDecodePrivateKey failed: want '%s', got '%s'", test.encoded, s) continue } // Test that decoding the expected string results in the original WIF // structure. w, err := DecodeWIF(test.encoded) if err != nil { t.Error(err) continue } if got := w.String(); got != test.encoded { t.Errorf("NewWIF failed: want '%v', got '%v'", test.wif, got) } } }
// Verifies a hash using DER encoded signature func verifyECDSA(pubKey, signature, hash []byte) (bool, error) { sig, err := btcec.ParseDERSignature(signature, btcec.S256()) if err != nil { return false, err } pk, err := btcec.ParsePubKey(pubKey, btcec.S256()) if err != nil { return false, nil } return sig.Verify(hash, pk), nil }
// NewKeyFromString returns a new extended key instance from a base58-encoded // extended key. func NewKeyFromString(key string) (*ExtendedKey, error) { // The base58-decoded extended key must consist of a serialized payload // plus an additional 4 bytes for the checksum. decoded := base58.Decode(key) if len(decoded) != serializedKeyLen+4 { return nil, ErrInvalidKeyLen } // The serialized format is: // version (4) || depth (1) || parent fingerprint (4)) || // child num (4) || chain code (32) || key data (33) || checksum (4) // Split the payload and checksum up and ensure the checksum matches. payload := decoded[:len(decoded)-4] checkSum := decoded[len(decoded)-4:] expectedCheckSum := chainhash.DoubleHashB(payload)[:4] if !bytes.Equal(checkSum, expectedCheckSum) { return nil, ErrBadChecksum } // Deserialize each of the payload fields. version := payload[:4] depth := uint16(payload[4:5][0]) parentFP := payload[5:9] childNum := binary.BigEndian.Uint32(payload[9:13]) chainCode := payload[13:45] keyData := payload[45:78] // The key data is a private key if it starts with 0x00. Serialized // compressed pubkeys either start with 0x02 or 0x03. isPrivate := keyData[0] == 0x00 if isPrivate { // Ensure the private key is valid. It must be within the range // of the order of the secp256k1 curve and not be 0. keyData = keyData[1:] keyNum := new(big.Int).SetBytes(keyData) if keyNum.Cmp(btcec.S256().N) >= 0 || keyNum.Sign() == 0 { return nil, ErrUnusableSeed } } else { // Ensure the public key parses correctly and is actually on the // secp256k1 curve. _, err := btcec.ParsePubKey(keyData, btcec.S256()) if err != nil { return nil, err } } return newExtendedKey(version, keyData, chainCode, parentFP, depth, childNum, isPrivate), nil }
// TestSigCacheAddEvictEntry tests the eviction case where a new signature // triplet is added to a full signature cache which should trigger randomized // eviction, followed by adding the new element to the cache. func TestSigCacheAddEvictEntry(t *testing.T) { // Create a sigcache that can hold up to 100 entries. sigCacheSize := uint(100) sigCache := NewSigCache(sigCacheSize) // Fill the sigcache up with some random sig triplets. for i := uint(0); i < sigCacheSize; i++ { msg, sig, key, err := genRandomSig() if err != nil { t.Fatalf("unable to generate random signature test data") } sigCache.Add(*msg, sig, key) sigCopy, _ := btcec.ParseSignature(sig.Serialize(), btcec.S256()) keyCopy, _ := btcec.ParsePubKey(key.SerializeCompressed(), btcec.S256()) if !sigCache.Exists(*msg, sigCopy, keyCopy) { t.Errorf("previously added item not found in signature" + "cache") } } // The sigcache should now have sigCacheSize entries within it. if uint(len(sigCache.validSigs)) != sigCacheSize { t.Fatalf("sigcache should now have %v entries, instead it has %v", sigCacheSize, len(sigCache.validSigs)) } // Add a new entry, this should cause eviction of a randomly chosen // previously entry. msgNew, sigNew, keyNew, err := genRandomSig() if err != nil { t.Fatalf("unable to generate random signature test data") } sigCache.Add(*msgNew, sigNew, keyNew) // The sigcache should still have sigCache entries. if uint(len(sigCache.validSigs)) != sigCacheSize { t.Fatalf("sigcache should now have %v entries, instead it has %v", sigCacheSize, len(sigCache.validSigs)) } // The entry added above should be found within the sigcache. sigNewCopy, _ := btcec.ParseSignature(sigNew.Serialize(), btcec.S256()) keyNewCopy, _ := btcec.ParsePubKey(keyNew.SerializeCompressed(), btcec.S256()) if !sigCache.Exists(*msgNew, sigNewCopy, keyNewCopy) { t.Fatalf("previously added item not found in signature cache") } }
func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool { pub__, err := secp256k1.ParsePubKey(append([]byte{0x04}, pubKey[:]...), secp256k1.S256()) if err != nil { return false } sig, ok := sig_.(SignatureSecp256k1) if !ok { return false } sig__, err := secp256k1.ParseDERSignature(sig[:], secp256k1.S256()) if err != nil { return false } return sig__.Verify(Sha256(msg), pub__) }
// PrivKey returns the private key for the address. It can fail if the address // manager is watching-only or locked, or the address does not have any keys. // // This is part of the ManagedPubKeyAddress interface implementation. func (a *managedAddress) PrivKey() (*btcec.PrivateKey, error) { // No private keys are available for a watching-only address manager. if a.manager.watchingOnly { return nil, managerError(ErrWatchingOnly, errWatchingOnly, nil) } a.manager.mtx.Lock() defer a.manager.mtx.Unlock() // Account manager must be unlocked to decrypt the private key. if a.manager.locked { return nil, managerError(ErrLocked, errLocked, nil) } // Decrypt the key as needed. Also, make sure it's a copy since the // private key stored in memory can be cleared at any time. Otherwise // the returned private key could be invalidated from under the caller. privKeyCopy, err := a.unlock(a.manager.cryptoKeyPriv) if err != nil { return nil, err } privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyCopy) zero.Bytes(privKeyCopy) return privKey, nil }
// This example demonstrates signing a message with a secp256k1 private key that // is first parsed form raw bytes and serializing the generated signature. func Example_signMessage() { // Decode a hex-encoded private key. pkBytes, err := hex.DecodeString("22a47fa09a223f2aa079edf85a7c2d4f87" + "20ee63e502ee2869afab7de234b80c") if err != nil { fmt.Println(err) return } privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes) // Sign a message using the private key. message := "test message" messageHash := wire.DoubleSha256([]byte(message)) signature, err := privKey.Sign(messageHash) if err != nil { fmt.Println(err) return } // Serialize and display the signature. fmt.Printf("Serialized Signature: %x\n", signature.Serialize()) // Verify the signature for the message using the public key. verified := signature.Verify(messageHash, pubKey) fmt.Printf("Signature Verified? %v\n", verified) // Output: // Serialized Signature: 304402201008e236fa8cd0f25df4482dddbb622e8a8b26ef0ba731719458de3ccd93805b022032f8ebe514ba5f672466eba334639282616bb3c2f0ab09998037513d1f9e3d6d // Signature Verified? true }
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 } } }
// NewMaster creates a new master node for use in creating a hierarchical // deterministic key chain. The seed must be between 128 and 512 bits and // should be generated by a cryptographically secure random generation source. // // NOTE: There is an extremely small chance (< 1 in 2^127) the provided seed // will derive to an unusable secret key. The ErrUnusable error will be // returned if this should occur, so the caller must check for it and generate a // new seed accordingly. func NewMaster(seed []byte, net *chaincfg.Params) (*ExtendedKey, error) { // Per [BIP32], the seed must be in range [MinSeedBytes, MaxSeedBytes]. if len(seed) < MinSeedBytes || len(seed) > MaxSeedBytes { return nil, ErrInvalidSeedLen } // First take the HMAC-SHA512 of the master key and the seed data: // I = HMAC-SHA512(Key = "Bitcoin seed", Data = S) hmac512 := hmac.New(sha512.New, masterKey) hmac512.Write(seed) lr := hmac512.Sum(nil) // Split "I" into two 32-byte sequences Il and Ir where: // Il = master secret key // Ir = master chain code secretKey := lr[:len(lr)/2] chainCode := lr[len(lr)/2:] // Ensure the key in usable. secretKeyNum := new(big.Int).SetBytes(secretKey) if secretKeyNum.Cmp(btcec.S256().N) >= 0 || secretKeyNum.Sign() == 0 { return nil, ErrUnusableSeed } parentFP := []byte{0x00, 0x00, 0x00, 0x00} return newExtendedKey(net.HDPrivateKeyID[:], secretKey, chainCode, parentFP, 0, 0, true), nil }
// pubKeyBytes returns bytes for the serialized compressed public key associated // with this extended key in an efficient manner including memoization as // necessary. // // When the extended key is already a public key, the key is simply returned as // is since it's already in the correct form. However, when the extended key is // a private key, the public key will be calculated and memoized so future // accesses can simply return the cached result. func (k *ExtendedKey) pubKeyBytes() []byte { // Just return the key if it's already an extended public key. if !k.isPrivate { return k.key } // This is a private extended key, so calculate and memoize the public // key if needed. if len(k.pubKey) == 0 { pkx, pky := btcec.S256().ScalarBaseMult(k.key) pubKey := btcec.PublicKey{Curve: btcec.S256(), X: pkx, Y: pky} k.pubKey = pubKey.SerializeCompressed() } return k.pubKey }
//All BitPay clients use a PEM file to store the private and public keys. func GeneratePem() string { priv, _ := btcec.NewPrivateKey(btcec.S256()) pub := priv.PubKey() ecd := pub.ToECDSA() oid := asn1.ObjectIdentifier{1, 3, 132, 0, 10} curve := btcec.S256() der, _ := asn1.Marshal(ecPrivateKey{ Version: 1, PrivateKey: priv.D.Bytes(), NamedCurveOID: oid, PublicKey: asn1.BitString{Bytes: elliptic.Marshal(curve, ecd.X, ecd.Y)}, }) blck := pem.Block{Type: "EC PRIVATE KEY", Bytes: der} pm := pem.EncodeToMemory(&blck) return string(pm) }
// NOTE: secret should be the output of a KDF like bcrypt, // if it's derived from user input. func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1 { privKey32 := Sha256(secret) // Not Ripemd160 because we want 32 bytes. priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey32) privKeyBytes := [32]byte{} copy(privKeyBytes[:], priv.Serialize()) return PrivKeySecp256k1(privKeyBytes) }
// This example demonstrates signing a message with a secp256k1 private key that // is first parsed form raw bytes and serializing the generated signature. func Example_signMessage() { // Decode a hex-encoded private key. pkBytes, err := hex.DecodeString("22a47fa09a223f2aa079edf85a7c2d4f87" + "20ee63e502ee2869afab7de234b80c") if err != nil { fmt.Println(err) return } privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes) // Sign a message using the private key. message := "test message" messageHash := wire.DoubleSha256([]byte(message)) signature, err := privKey.Sign(messageHash) if err != nil { fmt.Println(err) return } // Serialize and display the signature. // // NOTE: This is commented out for the example since the signature // produced uses random numbers and therefore will always be different. //fmt.Printf("Serialized Signature: %x\n", signature.Serialize()) // Verify the signature for the message using the public key. verified := signature.Verify(messageHash, pubKey) fmt.Printf("Signature Verified? %v\n", verified) // Output: // Signature Verified? true }
//Hardened child key derivation (private key parent and child) func (parent *ExtendedKey) HCKDpriv(index uint32) (*ExtendedKey, error) { //update w errors if len(parent.PrivateKey) != 32 { return nil, nil } //update w errors if len(parent.Chaincode) != 32 { return nil, nil } data := make([]byte, 37) copy(data[1:], parent.PrivateKey) binary.BigEndian.PutUint32(data[33:], index) hmac512 := hmac.New(sha512.New, parent.Chaincode) hmac512.Write(data) raw := hmac512.Sum(nil) //child Chaincode is the right 32 bytes of the result childChaincode := raw[32:] // child Private Key = parse256(left 32 bits) + parent key (mod n) // where n is the order of the curve // n is defined here on page 13: http://www.secg.org/sec2-v2.pdf leftInt := new(big.Int).SetBytes(raw[:32]) parentKeyInt := new(big.Int).SetBytes(parent.PrivateKey) leftInt.Add(leftInt, parentKeyInt) leftInt.Mod(leftInt, btcec.S256().N) ParentFingerPrint := parent.GetFingerPrint() depthBytes := []byte{parent.Depth} depthInt := new(big.Int).SetBytes(depthBytes) depthInt.Add(depthInt, big.NewInt(1)) depth := depthInt.Bytes() childExtendedKey := NewExtendedKey(depth[len(depth)-1], ParentFingerPrint, index, childChaincode, leftInt.Bytes()) return childExtendedKey, nil }
// This example demonstrates decrypting a message using a private key that is // first parsed from raw bytes. func Example_decryptMessage() { // Decode the hex-encoded private key. pkBytes, err := hex.DecodeString("a11b0a4e1a132305652ee7a8eb7848f6ad" + "5ea381e3ce20a2c086a2e388230811") if err != nil { fmt.Println(err) return } privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes) ciphertext, err := hex.DecodeString("35f644fbfb208bc71e57684c3c8b437402ca" + "002047a2f1b38aa1a8f1d5121778378414f708fe13ebf7b4a7bb74407288c1958969" + "00207cf4ac6057406e40f79961c973309a892732ae7a74ee96cd89823913b8b8d650" + "a44166dc61ea1c419d47077b748a9c06b8d57af72deb2819d98a9d503efc59fc8307" + "d14174f8b83354fac3ff56075162") // Try decrypting the message. plaintext, err := btcec.Decrypt(privKey, ciphertext) if err != nil { fmt.Println(err) return } fmt.Println(string(plaintext)) // Output: // test message }
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) } } }
func GenPrivKeySecp256k1() PrivKeySecp256k1 { privKeyBytes := [32]byte{} copy(privKeyBytes[:], CRandBytes(32)) priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKeyBytes[:]) copy(privKeyBytes[:], priv.Serialize()) return PrivKeySecp256k1(privKeyBytes) }
// createCipherConn.... func (l *Listener) createCipherConn(lnConn *LNDConn) (*btcec.PrivateKey, error) { var err error var theirEphPubBytes []byte // First, read and deserialize their ephemeral public key. theirEphPubBytes, err = readClear(lnConn.Conn) if err != nil { return nil, err } if len(theirEphPubBytes) != 33 { return nil, fmt.Errorf("Got invalid %d byte eph pubkey %x\n", len(theirEphPubBytes), theirEphPubBytes) } theirEphPub, err := btcec.ParsePubKey(theirEphPubBytes, btcec.S256()) if err != nil { return nil, err } // Once we've parsed and verified their key, generate, and send own // ephemeral key pair for use within this session. myEph, err := btcec.NewPrivateKey(btcec.S256()) if err != nil { return nil, err } if _, err := writeClear(lnConn.Conn, myEph.PubKey().SerializeCompressed()); err != nil { return nil, err } // Now that we have both keys, do non-interactive diffie with ephemeral // pubkeys, sha256 for good luck. sessionKey := fastsha256.Sum256( btcec.GenerateSharedSecret(myEph, theirEphPub), ) lnConn.chachaStream, err = chacha20poly1305.New(sessionKey[:]) // display private key for debug only fmt.Printf("made session key %x\n", sessionKey) lnConn.remoteNonceInt = 1 << 63 lnConn.myNonceInt = 0 lnConn.RemotePub = theirEphPub lnConn.Authed = false return myEph, nil }
//Returns a btec.Private key object if provided a correct secp256k1 encoded pem. func ExtractKeyFromPem(pm string) *btcec.PrivateKey { byta := []byte(pm) blck, _ := pem.Decode(byta) var ecp ecPrivateKey asn1.Unmarshal(blck.Bytes, &ecp) priv, _ := btcec.PrivKeyFromBytes(btcec.S256(), ecp.PrivateKey) return priv }
// ECPrivKey converts the extended key to a btcec private key and returns it. // As you might imagine this is only possible if the extended key is a private // extended key (as determined by the IsPrivate function). The ErrNotPrivExtKey // error will be returned if this function is called on a public extended key. func (k *ExtendedKey) ECPrivKey() (*btcec.PrivateKey, error) { if !k.isPrivate { return nil, ErrNotPrivExtKey } privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), k.key) return privKey, nil }
// Returns DER encoded signature from input hash func signECDSA(privateKey, hash []byte) ([]byte, error) { priv, _ := btcec.PrivKeyFromBytes(btcec.S256(), privateKey) sig, err := priv.Sign(hash) if err != nil { return nil, err } return sig.Serialize(), nil }
func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature { priv__, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) sig__, err := priv__.Sign(Sha256(msg)) if err != nil { PanicSanity(err) } return SignatureSecp256k1(sig__.Serialize()) }
func Sign(private, data []byte) ([]byte, error) { privkey, _ := btcec.PrivKeyFromBytes(btcec.S256(), private) sig, err := privkey.Sign(data) if err != nil { return nil, err } return sig.Serialize(), 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) } } }
// This example demonstrates encrypting a message for a public key that is first // parsed from raw bytes, then decrypting it using the corresponding private key. func Example_encryptMessage() { // Decode the hex-encoded pubkey of the recipient. pubKeyBytes, err := hex.DecodeString("04115c42e757b2efb7671c578530ec191a1" + "359381e6a71127a9d37c486fd30dae57e76dc58f693bd7e7010358ce6b165e483a29" + "21010db67ac11b1b51b651953d2") // uncompressed pubkey if err != nil { fmt.Println(err) return } pubKey, err := btcec.ParsePubKey(pubKeyBytes, btcec.S256()) if err != nil { fmt.Println(err) return } // Encrypt a message decryptable by the private key corresponding to pubKey message := "test message" ciphertext, err := btcec.Encrypt(pubKey, []byte(message)) if err != nil { fmt.Println(err) return } // Decode the hex-encoded private key. pkBytes, err := hex.DecodeString("a11b0a4e1a132305652ee7a8eb7848f6ad" + "5ea381e3ce20a2c086a2e388230811") if err != nil { fmt.Println(err) return } // note that we already have corresponding pubKey privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes) // Try decrypting and verify if it's the same message. plaintext, err := btcec.Decrypt(privKey, ciphertext) if err != nil { fmt.Println(err) return } fmt.Println(string(plaintext)) // Output: // test message }