From 87adff7e189ee0a1fd50a3ef30ba22482e60f314 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 10 Dec 2014 00:03:21 +0100 Subject: [PATCH] Added Encrypt & Decrypt using the ECIES w/ tests --- crypto/crypto.go | 42 ++++++++++++++++++++++++++++++++++ crypto/encrypt_decrypt_test.go | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 crypto/encrypt_decrypt_test.go diff --git a/crypto/crypto.go b/crypto/crypto.go index e10a9e81f9..87dd72dc79 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -1,14 +1,35 @@ package crypto import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" "crypto/sha256" "code.google.com/p/go.crypto/ripemd160" "github.com/ethereum/go-ethereum/ethutil" + "github.com/obscuren/ecies" "github.com/obscuren/secp256k1-go" "github.com/obscuren/sha3" ) +func init() { + // specify the params for the s256 curve + ecies.AddParamsForCurve(S256(), ecies.ECIES_AES128_SHA256) +} + +func ToECDSA(prv []byte) *ecdsa.PrivateKey { + priv := new(ecdsa.PrivateKey) + priv.PublicKey.Curve = S256() + priv.D = ethutil.BigD(prv) + priv.PublicKey.X, priv.PublicKey.Y = S256().ScalarBaseMult(prv) + return priv +} + +func FromECDSA(prv *ecdsa.PrivateKey) []byte { + return prv.D.Bytes() +} + // TODO refactor, remove (bin) func Sha3(data []byte) []byte { d := sha3.NewKeccak256() @@ -45,3 +66,24 @@ func Ecrecover(data []byte) []byte { return r } + +func SigToPub(hash, sig []byte) []byte { + return Ecrecover(append(hash, sig...)) +} + +func Sign(hash, prv []byte) (sig []byte, err error) { + sig, err = secp256k1.Sign(hash, prv) + return +} + +func Encrypt(pub, message []byte) ([]byte, error) { + x, y := elliptic.Unmarshal(S256(), pub) + epub := &ecdsa.PublicKey{S256(), x, y} + + return ecies.Encrypt(rand.Reader, ecies.ImportECDSAPublic(epub), message, nil, nil) +} + +func Decrypt(prv, ct []byte) ([]byte, error) { + key := ecies.ImportECDSA(ToECDSA(prv)) + return key.Decrypt(rand.Reader, ct, nil, nil) +} diff --git a/crypto/encrypt_decrypt_test.go b/crypto/encrypt_decrypt_test.go new file mode 100644 index 0000000000..44bb26f47a --- /dev/null +++ b/crypto/encrypt_decrypt_test.go @@ -0,0 +1,40 @@ +package crypto + +import ( + "bytes" + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/ethutil" +) + +func TestBox(t *testing.T) { + prv1 := ethutil.Hex2Bytes("4b50fa71f5c3eeb8fdc452224b2395af2fcc3d125e06c32c82e048c0559db03f") + prv2 := ethutil.Hex2Bytes("d0b043b4c5d657670778242d82d68a29d25d7d711127d17b8e299f156dad361a") + pub2 := ethutil.Hex2Bytes("04bd27a63c91fe3233c5777e6d3d7b39204d398c8f92655947eb5a373d46e1688f022a1632d264725cbc7dc43ee1cfebde42fa0a86d08b55d2acfbb5e9b3b48dc5") + + message := []byte("Hello, world.") + ct, err := Encrypt(pub2, message) + if err != nil { + fmt.Println(err.Error()) + t.FailNow() + } + + pt, err := Decrypt(prv2, ct) + if err != nil { + fmt.Println(err.Error()) + t.FailNow() + } + + if !bytes.Equal(pt, message) { + fmt.Println("ecies: plaintext doesn't match message") + t.FailNow() + } + + _, err = Decrypt(prv1, pt) + if err == nil { + fmt.Println("ecies: encryption should not have succeeded") + t.FailNow() + } + +}