Updated whisper messages to new crypto api + added tests

pull/207/head
obscuren 10 years ago
parent 0f5c6c5e2d
commit dda778eda7
  1. 20
      whisper/envelope.go
  2. 2
      whisper/main.go
  3. 18
      whisper/message.go
  4. 51
      whisper/messages_test.go
  5. 9
      whisper/whisper.go

@ -2,7 +2,9 @@ package whisper
import ( import (
"bytes" "bytes"
"crypto/ecdsa"
"encoding/binary" "encoding/binary"
"fmt"
"io" "io"
"time" "time"
@ -59,6 +61,24 @@ func (self *Envelope) Seal(pow time.Duration) {
self.proveWork(pow) 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) { func (self *Envelope) proveWork(dura time.Duration) {
var bestBit int var bestBit int
d := make([]byte, 64) d := make([]byte, 64)

@ -19,7 +19,7 @@ func main() {
pub, sec := secp256k1.GenerateKeyPair() pub, sec := secp256k1.GenerateKeyPair()
whisper := whisper.New(pub, sec) whisper := whisper.New(sec)
srv := p2p.Server{ srv := p2p.Server{
MaxPeers: 10, MaxPeers: 10,

@ -1,6 +1,7 @@
package whisper package whisper
import ( import (
"crypto/ecdsa"
"time" "time"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
@ -20,13 +21,17 @@ func (self *Message) hash() []byte {
return crypto.Sha3(append([]byte{self.Flags}, self.Payload...)) 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.Flags = 1
self.Signature, err = crypto.Sign(self.hash(), key) self.Signature, err = crypto.Sign(self.hash(), key)
return 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) err = self.sign(from)
if err != nil { if err != nil {
return err return err
@ -45,13 +50,14 @@ func (self *Message) Bytes() []byte {
} }
type Opts struct { type Opts struct {
From, To []byte // private(sender), public(receiver) key From *ecdsa.PrivateKey
Ttl time.Duration To *ecdsa.PublicKey
Topics [][]byte Ttl time.Duration
Topics [][]byte
} }
func (self *Message) Seal(pow time.Duration, opts Opts) (*Envelope, error) { 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 { if err := self.Encrypt(opts.From, opts.To); err != nil {
return nil, err return nil, err
} }

@ -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()
}
}

@ -2,11 +2,13 @@ package whisper
import ( import (
"bytes" "bytes"
"crypto/ecdsa"
"errors" "errors"
"fmt" "fmt"
"sync" "sync"
"time" "time"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
"gopkg.in/fatih/set.v0" "gopkg.in/fatih/set.v0"
) )
@ -39,7 +41,7 @@ const (
const DefaultTtl = 50 * time.Second const DefaultTtl = 50 * time.Second
type Whisper struct { type Whisper struct {
pub, sec []byte key *ecdsa.PrivateKey
protocol p2p.Protocol protocol p2p.Protocol
mmu sync.RWMutex mmu sync.RWMutex
@ -49,10 +51,9 @@ type Whisper struct {
quit chan struct{} quit chan struct{}
} }
func New(pub, sec []byte) *Whisper { func New(sec []byte) *Whisper {
whisper := &Whisper{ whisper := &Whisper{
pub: pub, key: crypto.ToECDSA(sec),
sec: sec,
messages: make(map[Hash]*Envelope), messages: make(map[Hash]*Envelope),
expiry: make(map[uint32]*set.SetNonTS), expiry: make(map[uint32]*set.SetNonTS),
quit: make(chan struct{}), quit: make(chan struct{}),

Loading…
Cancel
Save