// Test 1: Encryption and decryption func TestCipheringBasic(t *testing.T) { c := secp256k1.S256() privkey, err := secp256k1.GeneratePrivateKey(secp256k1.S256()) if err != nil { t.Fatal("failed to generate private key") } in := []byte("Hey there dude. How are you doing? This is a test.") pk1x, pk1y := privkey.Public() pk1 := secp256k1.NewPublicKey(c, pk1x, pk1y) out, err := secp256k1.Encrypt(pk1, in) if err != nil { t.Fatal("failed to encrypt:", err) } dec, err := secp256k1.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") } }
// 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, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), pkBytes) ciphertext, err := hex.DecodeString("35f644fbfb208bc71e57684c3c8b437402ca" + "002047a2f1b38aa1a8f1d5121778378414f708fe13ebf7b4a7bb74407288c1958969" + "00207cf4ac6057406e40f79961c973309a892732ae7a74ee96cd89823913b8b8d650" + "a44166dc61ea1c419d47077b748a9c06b8d57af72deb2819d98a9d503efc59fc8307" + "d14174f8b83354fac3ff56075162") // Try decrypting the message. plaintext, err := secp256k1.Decrypt(privKey, ciphertext) if err != nil { fmt.Println(err) return } fmt.Println(string(plaintext)) // Output: // test message }
// 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 := secp256k1.ParsePubKey(pubKeyBytes, secp256k1.S256()) if err != nil { fmt.Println(err) return } // Encrypt a message decryptable by the private key corresponding to pubKey message := "test message" ciphertext, err := secp256k1.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, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), pkBytes) // Try decrypting and verify if it's the same message. plaintext, err := secp256k1.Decrypt(privKey, ciphertext) if err != nil { fmt.Println(err) return } fmt.Println(string(plaintext)) // Output: // test message }
// Test 2: Byte compatibility with Pyelliptic func TestCiphering(t *testing.T) { pb, _ := hex.DecodeString("fe38240982f313ae5afb3e904fb8215fb11af1200592b" + "fca26c96c4738e4bf8f") privkey, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), pb) in := []byte("This is just a test.") out, _ := hex.DecodeString("b0d66e5adaa5ed4e2f0ca68e17b8f2fc02ca002009e3" + "3487e7fa4ab505cf34d98f131be7bd258391588ca7804acb30251e71a04e0020ecf" + "df0f84608f8add82d7353af780fbb28868c713b7813eb4d4e61f7b75d7534dd9856" + "9b0ba77cf14348fcff80fee10e11981f1b4be372d93923e9178972f69937ec850ed" + "6c3f11ff572ddd5b2bedf9f9c0b327c54da02a28fcdce1f8369ffec") dec, err := secp256k1.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 TestCipheringErrors(t *testing.T) { privkey, err := secp256k1.GeneratePrivateKey(secp256k1.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 = secp256k1.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 = secp256k1.TstRemovePKCSPadding(test.in) if err == nil { t.Errorf("removePKCSPadding #%d did not get error", i) } } }
// newSecSchnorrDSA instatiates a function DSA subsystem over the secp256k1 // curve. A caveat for the functions below is that they're all routed through // interfaces, and nil returns from the library itself for interfaces must // ALWAYS be checked by checking the return value by attempted dereference // (== nil). func newSecSchnorrDSA() DSA { var secp DSA = &secSchnorrDSA{ // Constants getP: func() *big.Int { return secp256k1Curve.P }, getN: func() *big.Int { return secp256k1Curve.N }, // EC Math add: func(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { return secp256k1Curve.Add(x1, y1, x2, y2) }, isOnCurve: func(x, y *big.Int) bool { return secp256k1Curve.IsOnCurve(x, y) }, scalarMult: func(x, y *big.Int, k []byte) (*big.Int, *big.Int) { return secp256k1Curve.ScalarMult(x, y, k) }, scalarBaseMult: func(k []byte) (*big.Int, *big.Int) { return secp256k1Curve.ScalarBaseMult(k) }, // Private keys newPrivateKey: func(d *big.Int) PrivateKey { pk := secp256k1.NewPrivateKey(secp256k1Curve, d) if pk != nil { return PrivateKey(pk) } return nil }, privKeyFromBytes: func(pk []byte) (PrivateKey, PublicKey) { priv, pub := secp256k1.PrivKeyFromBytes(secp256k1Curve, pk) if priv == nil { return nil, nil } if pub == nil { return nil, nil } tpriv := PrivateKey(priv) tpub := PublicKey(pub) return tpriv, tpub }, privKeyFromScalar: func(pk []byte) (PrivateKey, PublicKey) { priv, pub := secp256k1.PrivKeyFromScalar(secp256k1Curve, pk) if priv == nil { return nil, nil } if pub == nil { return nil, nil } tpriv := PrivateKey(priv) tpub := PublicKey(pub) return tpriv, tpub }, privKeyBytesLen: func() int { return secp256k1.PrivKeyBytesLen }, // Public keys // Note that Schnorr only allows 33 byte public keys, however // as they are secp256k1 you still have access to the other // serialization types. newPublicKey: func(x *big.Int, y *big.Int) PublicKey { pk := secp256k1.NewPublicKey(secp256k1Curve, x, y) tpk := PublicKey(pk) return tpk }, parsePubKey: func(pubKeyStr []byte) (PublicKey, error) { pk, err := schnorr.ParsePubKey(secp256k1Curve, pubKeyStr) if err != nil { return nil, err } tpk := PublicKey(pk) return tpk, err }, pubKeyBytesLen: func() int { return schnorr.PubKeyBytesLen }, pubKeyBytesLenUncompressed: func() int { return schnorr.PubKeyBytesLen }, pubKeyBytesLenCompressed: func() int { return schnorr.PubKeyBytesLen }, pubKeyBytesLenHybrid: func() int { return schnorr.PubKeyBytesLen }, // Signatures newSignature: func(r *big.Int, s *big.Int) Signature { sig := schnorr.NewSignature(r, s) ts := Signature(sig) return ts }, parseDERSignature: func(sigStr []byte) (Signature, error) { sig, err := schnorr.ParseSignature(sigStr) ts := Signature(sig) return ts, err }, parseSignature: func(sigStr []byte) (Signature, error) { sig, err := schnorr.ParseSignature(sigStr) ts := Signature(sig) return ts, err }, recoverCompact: func(signature, hash []byte) (PublicKey, bool, error) { pk, bl, err := schnorr.RecoverPubkey(secp256k1Curve, signature, hash) tpk := PublicKey(pk) return tpk, bl, err }, // ECDSA generateKey: func(rand io.Reader) ([]byte, *big.Int, *big.Int, error) { return secp256k1.GenerateKey(secp256k1Curve, rand) }, sign: func(priv PrivateKey, hash []byte) (r, s *big.Int, err error) { spriv := secp256k1.NewPrivateKey(secp256k1Curve, priv.GetD()) return schnorr.Sign(secp256k1Curve, spriv, hash) }, verify: func(pub PublicKey, hash []byte, r, s *big.Int) bool { spub := secp256k1.NewPublicKey(secp256k1Curve, pub.GetX(), pub.GetY()) return schnorr.Verify(secp256k1Curve, spub, hash, r, s) }, // Symmetric cipher encryption generateSharedSecret: func(privkey []byte, x, y *big.Int) []byte { sprivkey, _ := secp256k1.PrivKeyFromBytes(secp256k1Curve, privkey) if sprivkey == nil { return nil } spubkey := secp256k1.NewPublicKey(secp256k1Curve, x, y) return secp256k1.GenerateSharedSecret(sprivkey, spubkey) }, encrypt: func(x, y *big.Int, in []byte) ([]byte, error) { spubkey := secp256k1.NewPublicKey(secp256k1Curve, x, y) return secp256k1.Encrypt(spubkey, in) }, decrypt: func(privkey []byte, in []byte) ([]byte, error) { sprivkey, _ := secp256k1.PrivKeyFromBytes(secp256k1Curve, privkey) if sprivkey == nil { return nil, fmt.Errorf("failure deserializing privkey") } return secp256k1.Decrypt(sprivkey, in) }, } return secp.(DSA) }
// newSecp256k1DSA instatiates a function DSA subsystem over the secp256k1 // curve. A caveat for the functions below is that they're all routed through // interfaces, and nil returns from the library itself for interfaces must // ALWAYS be checked by checking the return value by attempted dereference // (== nil). func newSecp256k1DSA() DSA { var secp DSA = &secp256k1DSA{ // Constants getP: func() *big.Int { return secp256k1Curve.P }, getN: func() *big.Int { return secp256k1Curve.N }, // EC Math add: func(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { return secp256k1Curve.Add(x1, y1, x2, y2) }, isOnCurve: func(x, y *big.Int) bool { return secp256k1Curve.IsOnCurve(x, y) }, scalarMult: func(x, y *big.Int, k []byte) (*big.Int, *big.Int) { return secp256k1Curve.ScalarMult(x, y, k) }, scalarBaseMult: func(k []byte) (*big.Int, *big.Int) { return secp256k1Curve.ScalarBaseMult(k) }, // Private keys newPrivateKey: func(d *big.Int) PrivateKey { if d == nil { return nil } pk := secp256k1.NewPrivateKey(secp256k1Curve, d) if pk != nil { return PrivateKey(pk) } return nil }, privKeyFromBytes: func(pk []byte) (PrivateKey, PublicKey) { priv, pub := secp256k1.PrivKeyFromBytes(secp256k1Curve, pk) if priv == nil { return nil, nil } if pub == nil { return nil, nil } tpriv := PrivateKey(priv) tpub := PublicKey(pub) return tpriv, tpub }, privKeyFromScalar: func(pk []byte) (PrivateKey, PublicKey) { priv, pub := secp256k1.PrivKeyFromScalar(secp256k1Curve, pk) if priv == nil { return nil, nil } if pub == nil { return nil, nil } tpriv := PrivateKey(priv) tpub := PublicKey(pub) return tpriv, tpub }, privKeyBytesLen: func() int { return secp256k1.PrivKeyBytesLen }, // Public keys newPublicKey: func(x *big.Int, y *big.Int) PublicKey { pk := secp256k1.NewPublicKey(secp256k1Curve, x, y) tpk := PublicKey(pk) return tpk }, parsePubKey: func(pubKeyStr []byte) (PublicKey, error) { pk, err := secp256k1.ParsePubKey(pubKeyStr, secp256k1Curve) if err != nil { return nil, err } tpk := PublicKey(pk) return tpk, err }, pubKeyBytesLen: func() int { return secp256k1.PubKeyBytesLenCompressed }, pubKeyBytesLenUncompressed: func() int { return secp256k1.PubKeyBytesLenUncompressed }, pubKeyBytesLenCompressed: func() int { return secp256k1.PubKeyBytesLenCompressed }, pubKeyBytesLenHybrid: func() int { return secp256k1.PubKeyBytesLenHybrid }, // Signatures newSignature: func(r *big.Int, s *big.Int) Signature { sig := secp256k1.NewSignature(r, s) ts := Signature(sig) return ts }, parseDERSignature: func(sigStr []byte) (Signature, error) { sig, err := secp256k1.ParseDERSignature(sigStr, secp256k1Curve) if err != nil { return nil, err } ts := Signature(sig) return ts, err }, parseSignature: func(sigStr []byte) (Signature, error) { sig, err := secp256k1.ParseSignature(sigStr, secp256k1Curve) if err != nil { return nil, err } ts := Signature(sig) return ts, err }, recoverCompact: func(signature, hash []byte) (PublicKey, bool, error) { pk, bl, err := secp256k1.RecoverCompact(secp256k1Curve, signature, hash) tpk := PublicKey(pk) return tpk, bl, err }, // ECDSA generateKey: func(rand io.Reader) ([]byte, *big.Int, *big.Int, error) { return secp256k1.GenerateKey(secp256k1Curve, rand) }, sign: func(priv PrivateKey, hash []byte) (r, s *big.Int, err error) { if priv.GetType() != ECTypeSecp256k1 { return nil, nil, errors.New("wrong type") } spriv, ok := priv.(*secp256k1.PrivateKey) if !ok { return nil, nil, errors.New("wrong type") } sig, err := spriv.Sign(hash) if sig != nil { r = sig.GetR() s = sig.GetS() } return }, verify: func(pub PublicKey, hash []byte, r, s *big.Int) bool { spub := secp256k1.NewPublicKey(secp256k1Curve, pub.GetX(), pub.GetY()) ssig := secp256k1.NewSignature(r, s) return ssig.Verify(hash, spub) }, // Symmetric cipher encryption generateSharedSecret: func(privkey []byte, x, y *big.Int) []byte { sprivkey, _ := secp256k1.PrivKeyFromBytes(secp256k1Curve, privkey) if sprivkey == nil { return nil } spubkey := secp256k1.NewPublicKey(secp256k1Curve, x, y) return secp256k1.GenerateSharedSecret(sprivkey, spubkey) }, encrypt: func(x, y *big.Int, in []byte) ([]byte, error) { spubkey := secp256k1.NewPublicKey(secp256k1Curve, x, y) return secp256k1.Encrypt(spubkey, in) }, decrypt: func(privkey []byte, in []byte) ([]byte, error) { sprivkey, _ := secp256k1.PrivKeyFromBytes(secp256k1Curve, privkey) if sprivkey == nil { return nil, fmt.Errorf("failure deserializing privkey") } return secp256k1.Decrypt(sprivkey, in) }, } return secp.(DSA) }