Skip to content

Commit 403e54e

Browse files
kortatunolash
authored andcommitted
pss: Modularize crypto and remove Whisper. Step 1 - isolate whisper code (ethersphere#1698)
* pss: new temporary CryptoBackend interface and make Whisper default pluggable implementation
1 parent 9c8262f commit 403e54e

File tree

13 files changed

+424
-203
lines changed

13 files changed

+424
-203
lines changed

pss/api.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"fmt"
2323

2424
"github.com/ethereum/go-ethereum/common/hexutil"
25-
"github.com/ethereum/go-ethereum/crypto"
2625
"github.com/ethereum/go-ethereum/p2p"
2726
"github.com/ethereum/go-ethereum/rpc"
2827
"github.com/ethersphere/swarm/log"
@@ -118,13 +117,13 @@ func (pssapi *API) BaseAddr() (PssAddress, error) {
118117
// Retrieves the node's public key in hex form
119118
func (pssapi *API) GetPublicKey() (keybytes hexutil.Bytes) {
120119
key := pssapi.Pss.PublicKey()
121-
keybytes = crypto.FromECDSAPub(key)
120+
keybytes = pssapi.Pss.Crypto.FromECDSAPub(key)
122121
return keybytes
123122
}
124123

125124
// Set Public key to associate with a particular Pss peer
126125
func (pssapi *API) SetPeerPublicKey(pubkey hexutil.Bytes, topic Topic, addr PssAddress) error {
127-
pk, err := crypto.UnmarshalPubkey(pubkey)
126+
pk, err := pssapi.Pss.Crypto.UnmarshalPubkey(pubkey)
128127
if err != nil {
129128
return fmt.Errorf("Cannot unmarshal pubkey: %x", pubkey)
130129
}

pss/client/client_test.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import (
3434
"github.com/ethereum/go-ethereum/p2p/simulations"
3535
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
3636
"github.com/ethereum/go-ethereum/rpc"
37-
whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
3837
"github.com/ethersphere/swarm/network"
3938
"github.com/ethersphere/swarm/pss"
4039
"github.com/ethersphere/swarm/state"
@@ -49,8 +48,7 @@ type protoCtrl struct {
4948
var (
5049
debugdebugflag = flag.Bool("vv", false, "veryverbose")
5150
debugflag = flag.Bool("v", false, "verbose")
52-
w *whisper.Whisper
53-
wapi *whisper.PublicWhisperAPI
51+
cryptoUtils pss.CryptoUtils
5452
// custom logging
5553
psslogmain log.Logger
5654
pssprotocols map[string]*protoCtrl
@@ -78,8 +76,7 @@ func init() {
7876
h := log.CallerFileHandler(hf)
7977
log.Root().SetHandler(h)
8078

81-
w = whisper.New(&whisper.DefaultConfig)
82-
wapi = whisper.NewPublicWhisperAPI(w)
79+
cryptoUtils = pss.NewCryptoUtils()
8380

8481
pssprotocols = make(map[string]*protoCtrl)
8582
}
@@ -250,11 +247,11 @@ func newServices() adapters.Services {
250247
"pss": func(ctx *adapters.ServiceContext) (node.Service, error) {
251248
ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second)
252249
defer cancel()
253-
keys, err := wapi.NewKeyPair(ctxlocal)
250+
keys, err := cryptoUtils.NewKeyPair(ctxlocal)
254251
if err != nil {
255252
return nil, err
256253
}
257-
privkey, err := w.GetPrivateKey(keys)
254+
privkey, err := cryptoUtils.GetPrivateKey(keys)
258255
if err != nil {
259256
return nil, err
260257
}

pss/crypto.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright 2019 The Swarm Authors
2+
// This file is part of the Swarm library.
3+
//
4+
// The Swarm library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The Swarm library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the Swarm library. If not, see <http://www.gnu.org/licenses/>.
16+
package pss
17+
18+
import (
19+
"context"
20+
"crypto/ecdsa"
21+
22+
ethCrypto "github.com/ethereum/go-ethereum/crypto"
23+
whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
24+
)
25+
26+
var cryptoBackend defaultCryptoBackend
27+
28+
type CryptoBackend interface {
29+
GetSymKey(id string) ([]byte, error)
30+
GenerateSymKey() (string, error)
31+
AddSymKeyDirect(bytes []byte) (string, error)
32+
FromECDSAPub(pub *ecdsa.PublicKey) []byte
33+
UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error)
34+
CompressPubkey(pubkey *ecdsa.PublicKey) []byte
35+
}
36+
37+
//Used only in tests
38+
type CryptoUtils interface {
39+
GenerateKey() (*ecdsa.PrivateKey, error)
40+
NewKeyPair(ctx context.Context) (string, error)
41+
GetPrivateKey(id string) (*ecdsa.PrivateKey, error)
42+
}
43+
44+
type defaultCryptoBackend struct {
45+
whisper *whisper.Whisper
46+
wapi *whisper.PublicWhisperAPI
47+
}
48+
49+
func NewCryptoBackend() CryptoBackend {
50+
w := whisper.New(&whisper.DefaultConfig)
51+
cryptoBackend = defaultCryptoBackend{
52+
whisper: w,
53+
wapi: whisper.NewPublicWhisperAPI(w),
54+
}
55+
return &cryptoBackend
56+
}
57+
58+
func NewCryptoUtils() CryptoUtils {
59+
if cryptoBackend.whisper == nil {
60+
NewCryptoBackend()
61+
}
62+
return &cryptoBackend
63+
}
64+
65+
func (crypto *defaultCryptoBackend) GetSymKey(id string) ([]byte, error) {
66+
return crypto.whisper.GetSymKey(id)
67+
}
68+
69+
func (crypto *defaultCryptoBackend) GenerateSymKey() (string, error) {
70+
return crypto.whisper.GenerateSymKey()
71+
}
72+
73+
func (crypto *defaultCryptoBackend) AddSymKeyDirect(bytes []byte) (string, error) {
74+
return crypto.whisper.AddSymKeyDirect(bytes)
75+
}
76+
77+
// FromECDSA exports a public key into a binary dump.
78+
func (crypto *defaultCryptoBackend) FromECDSAPub(pub *ecdsa.PublicKey) []byte {
79+
return ethCrypto.FromECDSAPub(pub)
80+
}
81+
82+
// CompressPubkey encodes a public key to the 33-byte compressed format.
83+
func (crypto *defaultCryptoBackend) CompressPubkey(pubkey *ecdsa.PublicKey) []byte {
84+
return ethCrypto.CompressPubkey(pubkey)
85+
}
86+
87+
// UnmarshalPubkey converts bytes to a secp256k1 public key.
88+
func (crypto *defaultCryptoBackend) UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) {
89+
return ethCrypto.UnmarshalPubkey(pub)
90+
}
91+
92+
// CryptoUtils
93+
94+
func (crypto *defaultCryptoBackend) GenerateKey() (*ecdsa.PrivateKey, error) {
95+
return ethCrypto.GenerateKey()
96+
}
97+
98+
func (crypto *defaultCryptoBackend) NewKeyPair(ctx context.Context) (string, error) {
99+
return crypto.wapi.NewKeyPair(ctx)
100+
}
101+
102+
func (crypto *defaultCryptoBackend) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
103+
return crypto.whisper.GetPrivateKey(id)
104+
}

pss/forwarding_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@ import (
66
"testing"
77
"time"
88

9-
"github.com/ethereum/go-ethereum/crypto"
109
"github.com/ethereum/go-ethereum/p2p"
1110
"github.com/ethereum/go-ethereum/p2p/enode"
12-
whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
1311
"github.com/ethersphere/swarm/network"
1412
"github.com/ethersphere/swarm/p2p/protocols"
1513
"github.com/ethersphere/swarm/pot"
@@ -26,6 +24,8 @@ type testCase struct {
2624
errors string
2725
}
2826

27+
var crypto CryptoUtils = NewCryptoUtils()
28+
2929
// the purpose of this test is to see that pss.forward() function correctly
3030
// selects the peers for message forwarding, depending on the message address
3131
// and kademlia constellation.
@@ -351,7 +351,7 @@ func newTestMsg(addr []byte) *PssMsg {
351351
msg := newPssMsg(&msgParams{})
352352
msg.To = addr[:]
353353
msg.Expire = uint32(time.Now().Add(time.Second * 60).Unix())
354-
msg.Payload = &whisper.Envelope{
354+
msg.Payload = &envelope{
355355
Topic: [4]byte{},
356356
Data: []byte("i have nothing to hide"),
357357
}

pss/handshake.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727

2828
"github.com/ethereum/go-ethereum/common"
2929
"github.com/ethereum/go-ethereum/common/hexutil"
30-
"github.com/ethereum/go-ethereum/crypto"
3130
"github.com/ethereum/go-ethereum/p2p"
3231
"github.com/ethereum/go-ethereum/rlp"
3332
"github.com/ethereum/go-ethereum/rpc"
@@ -325,7 +324,7 @@ func (ctl *HandshakeController) registerSymKeyUse(symkeyid string) error {
325324
}
326325
symKey.count++
327326

328-
receiver := common.ToHex(crypto.FromECDSAPub(ctl.pss.PublicKey()))
327+
receiver := common.ToHex(ctl.pss.Crypto.FromECDSAPub(ctl.pss.PublicKey()))
329328
log.Trace("increment symkey recv use", "symsymkeyid", symkeyid, "count", symKey.count, "limit", symKey.limit, "receiver", receiver)
330329

331330
return nil

0 commit comments

Comments
 (0)