aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-12-10 21:17:32 +0800
committerobscuren <geffobscura@gmail.com>2014-12-10 21:17:32 +0800
commitdda778eda7ad9b94acf14c3c91c1c29e711e170f (patch)
treedfbb71a45399455fd2c2bb77ce72c8ce9d79ba45
parent0f5c6c5e2daa9fbf3a0bb753debd8989a872823c (diff)
downloadgo-tangerine-dda778eda7ad9b94acf14c3c91c1c29e711e170f.tar.gz
go-tangerine-dda778eda7ad9b94acf14c3c91c1c29e711e170f.tar.zst
go-tangerine-dda778eda7ad9b94acf14c3c91c1c29e711e170f.zip
Updated whisper messages to new crypto api + added tests
-rw-r--r--whisper/envelope.go20
-rw-r--r--whisper/main.go2
-rw-r--r--whisper/message.go18
-rw-r--r--whisper/messages_test.go51
-rw-r--r--whisper/whisper.go9
5 files changed, 89 insertions, 11 deletions
diff --git a/whisper/envelope.go b/whisper/envelope.go
index eb80098ad..359fa1568 100644
--- a/whisper/envelope.go
+++ b/whisper/envelope.go
@@ -2,7 +2,9 @@ package whisper
import (
"bytes"
+ "crypto/ecdsa"
"encoding/binary"
+ "fmt"
"io"
"time"
@@ -59,6 +61,24 @@ func (self *Envelope) Seal(pow time.Duration) {
self.proveWork(pow)
}
+func (self *Envelope) Open(prv *ecdsa.PrivateKey) (*Message, error) {
+ data := self.Data
+ if data[0] > 0 && len(data) < 66 {
+ return nil, fmt.Errorf("unable to open envelope. First bit set but len(data) < 66")
+ }
+
+ if data[0] > 0 {
+ payload, err := crypto.Decrypt(prv, data[66:])
+ if err != nil {
+ return nil, fmt.Errorf("unable to open envelope. Decrypt failed: %v", err)
+ }
+
+ return NewMessage(payload), nil
+ }
+
+ return NewMessage(data[1:]), nil
+}
+
func (self *Envelope) proveWork(dura time.Duration) {
var bestBit int
d := make([]byte, 64)
diff --git a/whisper/main.go b/whisper/main.go
index 3868f604f..80050d899 100644
--- a/whisper/main.go
+++ b/whisper/main.go
@@ -19,7 +19,7 @@ func main() {
pub, sec := secp256k1.GenerateKeyPair()
- whisper := whisper.New(pub, sec)
+ whisper := whisper.New(sec)
srv := p2p.Server{
MaxPeers: 10,
diff --git a/whisper/message.go b/whisper/message.go
index 408b9f7df..8ce5d880b 100644
--- a/whisper/message.go
+++ b/whisper/message.go
@@ -1,6 +1,7 @@
package whisper
import (
+ "crypto/ecdsa"
"time"
"github.com/ethereum/go-ethereum/crypto"
@@ -20,13 +21,17 @@ func (self *Message) hash() []byte {
return crypto.Sha3(append([]byte{self.Flags}, self.Payload...))
}
-func (self *Message) sign(key []byte) (err error) {
+func (self *Message) sign(key *ecdsa.PrivateKey) (err error) {
self.Flags = 1
self.Signature, err = crypto.Sign(self.hash(), key)
return
}
-func (self *Message) Encrypt(from, to []byte) (err error) {
+func (self *Message) Recover() *ecdsa.PublicKey {
+ return crypto.SigToPub(self.hash(), self.Signature)
+}
+
+func (self *Message) Encrypt(from *ecdsa.PrivateKey, to *ecdsa.PublicKey) (err error) {
err = self.sign(from)
if err != nil {
return err
@@ -45,13 +50,14 @@ func (self *Message) Bytes() []byte {
}
type Opts struct {
- From, To []byte // private(sender), public(receiver) key
- Ttl time.Duration
- Topics [][]byte
+ From *ecdsa.PrivateKey
+ To *ecdsa.PublicKey
+ Ttl time.Duration
+ Topics [][]byte
}
func (self *Message) Seal(pow time.Duration, opts Opts) (*Envelope, error) {
- if len(opts.To) > 0 && len(opts.From) > 0 {
+ if opts.To != nil && opts.From != nil {
if err := self.Encrypt(opts.From, opts.To); err != nil {
return nil, err
}
diff --git a/whisper/messages_test.go b/whisper/messages_test.go
new file mode 100644
index 000000000..cba103011
--- /dev/null
+++ b/whisper/messages_test.go
@@ -0,0 +1,51 @@
+package whisper
+
+import (
+ "bytes"
+ "crypto/elliptic"
+ "fmt"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+func TestSign(t *testing.T) {
+ prv, _ := crypto.GenerateKey()
+ msg := NewMessage([]byte("hello world"))
+ msg.sign(prv)
+
+ pubKey := msg.Recover()
+ p1 := elliptic.Marshal(crypto.S256(), prv.PublicKey.X, prv.PublicKey.Y)
+ p2 := elliptic.Marshal(crypto.S256(), pubKey.X, pubKey.Y)
+
+ if !bytes.Equal(p1, p2) {
+ t.Error("recovered pub key did not match")
+ }
+}
+
+func TestMessageEncryptDecrypt(t *testing.T) {
+ prv1, _ := crypto.GenerateKey()
+ prv2, _ := crypto.GenerateKey()
+
+ data := []byte("hello world")
+ msg := NewMessage(data)
+ envelope, err := msg.Seal(DefaultPow, Opts{
+ From: prv1,
+ To: &prv2.PublicKey,
+ })
+ if err != nil {
+ fmt.Println(err)
+ t.FailNow()
+ }
+
+ msg1, err := envelope.Open(prv2)
+ if err != nil {
+ fmt.Println(err)
+ t.FailNow()
+ }
+
+ if !bytes.Equal(msg1.Payload, data) {
+ fmt.Println("encryption error. data did not match")
+ t.FailNow()
+ }
+}
diff --git a/whisper/whisper.go b/whisper/whisper.go
index b4e37b959..4d7a2a23e 100644
--- a/whisper/whisper.go
+++ b/whisper/whisper.go
@@ -2,11 +2,13 @@ package whisper
import (
"bytes"
+ "crypto/ecdsa"
"errors"
"fmt"
"sync"
"time"
+ "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/p2p"
"gopkg.in/fatih/set.v0"
)
@@ -39,7 +41,7 @@ const (
const DefaultTtl = 50 * time.Second
type Whisper struct {
- pub, sec []byte
+ key *ecdsa.PrivateKey
protocol p2p.Protocol
mmu sync.RWMutex
@@ -49,10 +51,9 @@ type Whisper struct {
quit chan struct{}
}
-func New(pub, sec []byte) *Whisper {
+func New(sec []byte) *Whisper {
whisper := &Whisper{
- pub: pub,
- sec: sec,
+ key: crypto.ToECDSA(sec),
messages: make(map[Hash]*Envelope),
expiry: make(map[uint32]*set.SetNonTS),
quit: make(chan struct{}),