Skip to content

Commit

Permalink
Added example, more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mrz1836 committed Oct 30, 2020
1 parent 114a37f commit bfa0ae3
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 26 deletions.
20 changes: 17 additions & 3 deletions encryption.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,25 @@ func DecryptWithPrivateKeyString(privateKey, data string) (string, error) {
}

// EncryptShared will encrypt data and provide shared keys for decryption
func EncryptShared(u1priv *bsvec.PrivateKey, u2pub *bsvec.PublicKey, in []byte) (
func EncryptShared(user1PrivateKey *bsvec.PrivateKey, user2PubKey *bsvec.PublicKey, data []byte) (
*bsvec.PrivateKey, *bsvec.PublicKey, []byte, error) {

// Generate shared keys that can be decrypted by either user
sharedPrivKey, sharedPubKey := GenerateSharedKeyPair(u1priv, u2pub)
sharedPrivKey, sharedPubKey := GenerateSharedKeyPair(user1PrivateKey, user2PubKey)

// Encrypt data with shared key
encryptedData, err := bsvec.Encrypt(sharedPubKey, in)
encryptedData, err := bsvec.Encrypt(sharedPubKey, data)
return sharedPrivKey, sharedPubKey, encryptedData, err
}

// EncryptSharedString will encrypt data and provide shared keys for decryption
func EncryptSharedString(user1PrivateKey *bsvec.PrivateKey, user2PubKey *bsvec.PublicKey, data string) (
*bsvec.PrivateKey, *bsvec.PublicKey, string, error) {

// Generate shared keys that can be decrypted by either user
sharedPrivKey, sharedPubKey := GenerateSharedKeyPair(user1PrivateKey, user2PubKey)

// Encrypt data with shared key
encryptedData, err := bsvec.Encrypt(sharedPubKey, []byte(data))
return sharedPrivKey, sharedPubKey, hex.EncodeToString(encryptedData), err
}
107 changes: 95 additions & 12 deletions encryption_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package bitcoin

import (
"encoding/hex"
"fmt"
"testing"

"github.com/bitcoinsv/bsvd/bsvec"
)

const testEncryptionMessage = "testing 1, 2, 3..."

// TestEncryptWithPrivateKey will test the method EncryptWithPrivateKey()
func TestEncryptWithPrivateKey(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -411,32 +414,112 @@ func BenchmarkDecryptWithPrivateKeyString(b *testing.B) {
}
}

// TestEncryptShared will test the method EncryptShared()
func TestEncryptShared(t *testing.T) {

// This data will be encrypted / shared
testString := "testing 1, 2, 3..."
// User 1's private key
privKey1, _ := CreatePrivateKey()

// User 2's private key
privKey2, _ := CreatePrivateKey()

// User 1 encrypts using their private key and user 2's pubkey
_, _, encryptedData, err := EncryptShared(privKey1, privKey2.PubKey(), []byte(testEncryptionMessage))
if err != nil {
t.Fatalf("failed to encrypt data for sharing %s", err)
}

// Generate the shared key
user2SharedPrivKey, _ := GenerateSharedKeyPair(privKey2, privKey1.PubKey())

// User 2 can decrypt using the shared private key
var decryptedTestData []byte
decryptedTestData, err = bsvec.Decrypt(user2SharedPrivKey, encryptedData)
if err != nil {
t.Fatalf("failed to decrypt test data %s", err)
}

// Test the result
if string(decryptedTestData) != testEncryptionMessage {
t.Fatalf("decrypted string doesnt match %s", decryptedTestData)
}

// todo: test bad keys?
}

// TestEncryptSharedPanic tests for nil case in EncryptShared()
func TestEncryptSharedPanic(t *testing.T) {
t.Parallel()

defer func() {
if r := recover(); r == nil {
t.Errorf("the code did not panic")
}
}()

privateKey, _, _, err := EncryptShared(nil, nil, []byte(""))
if err == nil {
t.Fatalf("expected error")
} else if privateKey != nil {
t.Fatalf("expected privateKey to be nil")
}
}

// todo: examples and benchmark for EncryptShared()

// user 1
// TestEncryptSharedString will test the method EncryptSharedString()
func TestEncryptSharedString(t *testing.T) {

// User 1's private key
privKey1, _ := CreatePrivateKey()

// user 2
// User 2's private key
privKey2, _ := CreatePrivateKey()

// user 1 encrypts it
_, _, encryptedData, err := EncryptShared(privKey1, privKey2.PubKey(), []byte(testString))
// User 1 encrypts using their private key and user 2's pubkey
_, _, encryptedData, err := EncryptSharedString(privKey1, privKey2.PubKey(), testEncryptionMessage)
if err != nil {
t.Errorf("Failed to encrypt data for sharing %s", err)
t.Fatalf("failed to encrypt data for sharing %s", err)
}

// user 2 decrypts it
// Generate the shared key
user2SharedPrivKey, _ := GenerateSharedKeyPair(privKey2, privKey1.PubKey())

decryptedTestData, err := bsvec.Decrypt(user2SharedPrivKey, encryptedData)
// User 2 can decrypt using the shared private key
var decryptedTestData, decoded []byte
decoded, err = hex.DecodeString(encryptedData)
if err != nil {
t.Fatalf("failed to decoded %s", err)
}
decryptedTestData, err = bsvec.Decrypt(user2SharedPrivKey, decoded)
if err != nil {
t.Errorf("Failed to decrypt test data %s", err)
t.Fatalf("failed to decrypt test data %s", err)
}

// Test the result
if string(decryptedTestData) != testEncryptionMessage {
t.Fatalf("decrypted string doesnt match %s", decryptedTestData)
}

if string(decryptedTestData) != testString {
t.Errorf("Decrypted string doesnt match %s", decryptedTestData)
// todo: test bad keys?
}

// TestEncryptSharedStringPanic tests for nil case in EncryptSharedString()
func TestEncryptSharedStringPanic(t *testing.T) {
t.Parallel()

defer func() {
if r := recover(); r == nil {
t.Errorf("the code did not panic")
}
}()

privateKey, _, _, err := EncryptSharedString(nil, nil, "")
if err == nil {
t.Fatalf("expected error")
} else if privateKey != nil {
t.Fatalf("expected privateKey to be nil")
}
}

// todo: examples and benchmark for EncryptSharedString()
42 changes: 42 additions & 0 deletions examples/encrypt_shared_keys/encrypt_shared_keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package main

import (
"encoding/hex"
"log"

"github.com/bitcoinschema/go-bitcoin"
"github.com/bitcoinsv/bsvd/bsvec"
)

func main() {

// This data will be encrypted / shared
testString := "testing 1, 2, 3..."

// User 1's private key
privKey1, _ := bitcoin.CreatePrivateKey()

// User 2's private key
privKey2, _ := bitcoin.CreatePrivateKey()

// User 1 encrypts using their private key and user 2's pubkey
_, _, encryptedData, err := bitcoin.EncryptShared(privKey1, privKey2.PubKey(), []byte(testString))
if err != nil {
log.Fatalf("failed to encrypt data for sharing %s", err)
}

// Generate the shared key
user2SharedPrivKey, _ := bitcoin.GenerateSharedKeyPair(privKey2, privKey1.PubKey())

// User 2 can decrypt using the shared private key
var decryptedTestData []byte
decryptedTestData, err = bsvec.Decrypt(user2SharedPrivKey, encryptedData)
if err != nil {
log.Fatalf("failed to decrypt test data %s", err)
}

// Success
log.Printf("test string: %s", testString)
log.Printf("encrypted: %s", hex.EncodeToString(encryptedData))
log.Printf("decrypted: %s", decryptedTestData)
}
11 changes: 7 additions & 4 deletions private_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ import (
)

// GenerateSharedKeyPair creates shared keys that can be used to encrypt/decrypt data
// that can be decrypted by yourself (privkey) and also the owner of the given public key
func GenerateSharedKeyPair(privKey *bsvec.PrivateKey, pubKey *bsvec.PublicKey) (*bsvec.PrivateKey, *bsvec.PublicKey) {
sharedSecret := bsvec.GenerateSharedSecret(privKey, pubKey)
return bsvec.PrivKeyFromBytes(bsvec.S256(), sharedSecret)
// that can be decrypted by yourself (privateKey) and also the owner of the given public key
func GenerateSharedKeyPair(privateKey *bsvec.PrivateKey,
pubKey *bsvec.PublicKey) (*bsvec.PrivateKey, *bsvec.PublicKey) {
return bsvec.PrivKeyFromBytes(
bsvec.S256(),
bsvec.GenerateSharedSecret(privateKey, pubKey),
)
}

// PrivateKeyFromString turns a private key (hex encoded string) into an bsvec.PrivateKey
Expand Down
16 changes: 9 additions & 7 deletions private_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import (
"github.com/bitcoinsv/bsvd/bsvec"
)

// TestGenerateSharedKeyPair will test creating a shared key that can be used to encrypt data that can be decrypted by yourself (privkey) and also the owner of the given public key
// TestGenerateSharedKeyPair will test creating a shared key that can be used to
// encrypt data that can be decrypted by yourself (privkey) and also the owner
// of the given public key
func TestGenerateSharedKeyPair(t *testing.T) {

// The data that will be encrypted / shared
testString := "testing 1, 2, 3..."

// User 1
privKey1, _ := CreatePrivateKey()

Expand All @@ -23,24 +22,27 @@ func TestGenerateSharedKeyPair(t *testing.T) {
_, user1SharedPubKey := GenerateSharedKeyPair(privKey1, privKey2.PubKey())

// encrypt something with the shared public key
eciesTest, err := bsvec.Encrypt(user1SharedPubKey, []byte(testString))
encryptTest, err := bsvec.Encrypt(user1SharedPubKey, []byte(testEncryptionMessage))
if err != nil {
t.Errorf("Failed to encrypt test data %s", err)
}

// user 2 decrypts it
user2SharedPrivKey, _ := GenerateSharedKeyPair(privKey2, privKey1.PubKey())

decryptedTestData, err := bsvec.Decrypt(user2SharedPrivKey, eciesTest)
var decryptedTestData []byte
decryptedTestData, err = bsvec.Decrypt(user2SharedPrivKey, encryptTest)
if err != nil {
t.Errorf("Failed to decrypt test data %s", err)
}

if string(decryptedTestData) != testString {
if string(decryptedTestData) != testEncryptionMessage {
t.Errorf("Decrypted string doesnt match %s", decryptedTestData)
}
}

// todo: examples and benchmark for GenerateSharedKeyPair()

// TestCreatePrivateKey will test the method CreatePrivateKey()
func TestCreatePrivateKey(t *testing.T) {
rawKey, err := CreatePrivateKey()
Expand Down

0 comments on commit bfa0ae3

Please sign in to comment.