forked from cerc-io/plugeth
Updated whisper messages to new crypto api + added tests
This commit is contained in:
parent
0f5c6c5e2d
commit
dda778eda7
@ -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)
|
||||
|
@ -19,7 +19,7 @@ func main() {
|
||||
|
||||
pub, sec := secp256k1.GenerateKeyPair()
|
||||
|
||||
whisper := whisper.New(pub, sec)
|
||||
whisper := whisper.New(sec)
|
||||
|
||||
srv := p2p.Server{
|
||||
MaxPeers: 10,
|
||||
|
@ -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
|
||||
}
|
||||
|
51
whisper/messages_test.go
Normal file
51
whisper/messages_test.go
Normal file
@ -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 (
|
||||
"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{}),
|
||||
|
Loading…
Reference in New Issue
Block a user