Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
faa27478
Commit
faa27478
authored
Apr 13, 2015
by
Felix Lange
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #690 from karalabe/whisper-cleanup
Whisper cleanup, part 1
parents
61db7a71
5467e7b3
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
363 additions
and
179 deletions
+363
-179
whisper.go
ui/qt/qwhisper/whisper.go
+2
-2
envelope.go
whisper/envelope.go
+74
-65
main.go
whisper/main.go
+65
-12
message.go
whisper/message.go
+76
-45
message_test.go
whisper/message_test.go
+138
-0
messages_test.go
whisper/messages_test.go
+0
-50
whisper.go
whisper/whisper.go
+4
-1
whisper_test.go
whisper/whisper_test.go
+2
-2
whisper.go
xeth/whisper.go
+2
-2
No files found.
ui/qt/qwhisper/whisper.go
View file @
faa27478
...
@@ -37,8 +37,8 @@ func (self *Whisper) Post(payload []string, to, from string, topics []string, pr
...
@@ -37,8 +37,8 @@ func (self *Whisper) Post(payload []string, to, from string, topics []string, pr
pk
:=
crypto
.
ToECDSAPub
(
common
.
FromHex
(
from
))
pk
:=
crypto
.
ToECDSAPub
(
common
.
FromHex
(
from
))
if
key
:=
self
.
Whisper
.
GetIdentity
(
pk
);
key
!=
nil
{
if
key
:=
self
.
Whisper
.
GetIdentity
(
pk
);
key
!=
nil
{
msg
:=
whisper
.
NewMessage
(
data
)
msg
:=
whisper
.
NewMessage
(
data
)
envelope
,
err
:=
msg
.
Seal
(
time
.
Duration
(
priority
*
100000
),
whisper
.
Opt
s
{
envelope
,
err
:=
msg
.
Wrap
(
time
.
Duration
(
priority
*
100000
),
whisper
.
Option
s
{
T
tl
:
time
.
Duration
(
ttl
)
*
time
.
Second
,
T
TL
:
time
.
Duration
(
ttl
)
*
time
.
Second
,
To
:
crypto
.
ToECDSAPub
(
common
.
FromHex
(
to
)),
To
:
crypto
.
ToECDSAPub
(
common
.
FromHex
(
to
)),
From
:
key
,
From
:
key
,
Topics
:
whisper
.
TopicsFromString
(
topics
...
),
Topics
:
whisper
.
TopicsFromString
(
topics
...
),
...
...
whisper/envelope.go
View file @
faa27478
// Contains the Whisper protocol Envelope element. For formal details please see
// the specs at https://github.com/ethereum/wiki/wiki/Whisper-PoC-1-Protocol-Spec#envelopes.
package
whisper
package
whisper
import
(
import
(
...
@@ -12,10 +15,8 @@ import (
...
@@ -12,10 +15,8 @@ import (
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rlp"
)
)
const
(
// Envelope represents a clear-text data packet to transmit through the Whisper
DefaultPow
=
50
*
time
.
Millisecond
// network. Its contents may or may not be encrypted and signed.
)
type
Envelope
struct
{
type
Envelope
struct
{
Expiry
uint32
// Whisper protocol specifies int32, really should be int64
Expiry
uint32
// Whisper protocol specifies int32, really should be int64
TTL
uint32
// ^^^^^^
TTL
uint32
// ^^^^^^
...
@@ -26,96 +27,104 @@ type Envelope struct {
...
@@ -26,96 +27,104 @@ type Envelope struct {
hash
common
.
Hash
hash
common
.
Hash
}
}
func
(
self
*
Envelope
)
Hash
()
common
.
Hash
{
// NewEnvelope wraps a Whisper message with expiration and destination data
if
(
self
.
hash
==
common
.
Hash
{})
{
// included into an envelope for network forwarding.
enc
,
_
:=
rlp
.
EncodeToBytes
(
self
)
func
NewEnvelope
(
ttl
time
.
Duration
,
topics
[][]
byte
,
msg
*
Message
)
*
Envelope
{
self
.
hash
=
crypto
.
Sha3Hash
(
enc
)
}
return
self
.
hash
}
func
NewEnvelope
(
ttl
time
.
Duration
,
topics
[][]
byte
,
data
*
Message
)
*
Envelope
{
exp
:=
time
.
Now
()
.
Add
(
ttl
)
return
&
Envelope
{
return
&
Envelope
{
Expiry
:
uint32
(
exp
.
Unix
()),
Expiry
:
uint32
(
time
.
Now
()
.
Add
(
ttl
)
.
Unix
()),
TTL
:
uint32
(
ttl
.
Seconds
()),
TTL
:
uint32
(
ttl
.
Seconds
()),
Topics
:
topics
,
Topics
:
topics
,
Data
:
data
.
B
ytes
(),
Data
:
msg
.
b
ytes
(),
Nonce
:
0
,
Nonce
:
0
,
}
}
}
}
// Seal closes the envelope by spending the requested amount of time as a proof
// of work on hashing the data.
func
(
self
*
Envelope
)
Seal
(
pow
time
.
Duration
)
{
func
(
self
*
Envelope
)
Seal
(
pow
time
.
Duration
)
{
self
.
proveWork
(
pow
)
}
func
(
self
*
Envelope
)
Open
(
prv
*
ecdsa
.
PrivateKey
)
(
msg
*
Message
,
err
error
)
{
data
:=
self
.
Data
var
message
Message
dataStart
:=
1
if
data
[
0
]
>
0
{
if
len
(
data
)
<
66
{
return
nil
,
fmt
.
Errorf
(
"unable to open envelope. First bit set but len(data) < 66"
)
}
dataStart
=
66
message
.
Flags
=
data
[
0
]
message
.
Signature
=
data
[
1
:
66
]
}
payload
:=
data
[
dataStart
:
]
if
prv
!=
nil
{
message
.
Payload
,
err
=
crypto
.
Decrypt
(
prv
,
payload
)
switch
err
{
case
nil
:
// OK
case
ecies
.
ErrInvalidPublicKey
:
// Payload isn't encrypted
message
.
Payload
=
payload
return
&
message
,
err
default
:
return
nil
,
fmt
.
Errorf
(
"unable to open envelope. Decrypt failed: %v"
,
err
)
}
}
return
&
message
,
nil
}
func
(
self
*
Envelope
)
proveWork
(
dura
time
.
Duration
)
{
var
bestBit
int
d
:=
make
([]
byte
,
64
)
d
:=
make
([]
byte
,
64
)
enc
,
_
:=
rlp
.
EncodeToBytes
(
self
.
withoutNonce
())
copy
(
d
[
:
32
],
self
.
rlpWithoutNonce
())
copy
(
d
[
:
32
],
enc
)
then
:=
time
.
Now
()
.
Add
(
dura
)
.
UnixNano
()
finish
,
bestBit
:=
time
.
Now
()
.
Add
(
pow
)
.
UnixNano
(),
0
for
n
:=
uint32
(
0
);
time
.
Now
()
.
UnixNano
()
<
then
;
{
for
n
once
:=
uint32
(
0
);
time
.
Now
()
.
UnixNano
()
<
finish
;
{
for
i
:=
0
;
i
<
1024
;
i
++
{
for
i
:=
0
;
i
<
1024
;
i
++
{
binary
.
BigEndian
.
PutUint32
(
d
[
60
:
],
n
)
binary
.
BigEndian
.
PutUint32
(
d
[
60
:
],
n
once
)
fbs
:=
common
.
FirstBitSet
(
common
.
BigD
(
crypto
.
Sha3
(
d
)))
firstBit
:=
common
.
FirstBitSet
(
common
.
BigD
(
crypto
.
Sha3
(
d
)))
if
fbs
>
bestBit
{
if
firstBit
>
bestBit
{
bestBit
=
fbs
self
.
Nonce
,
bestBit
=
nonce
,
firstBit
self
.
Nonce
=
n
}
}
nonce
++
n
++
}
}
}
}
}
}
// valid checks whether the claimed proof of work was indeed executed.
// TODO: Is this really useful? Isn't this always true?
func
(
self
*
Envelope
)
valid
()
bool
{
func
(
self
*
Envelope
)
valid
()
bool
{
d
:=
make
([]
byte
,
64
)
d
:=
make
([]
byte
,
64
)
enc
,
_
:=
rlp
.
EncodeToBytes
(
self
.
withoutNonce
())
copy
(
d
[
:
32
],
self
.
rlpWithoutNonce
())
copy
(
d
[
:
32
],
enc
)
binary
.
BigEndian
.
PutUint32
(
d
[
60
:
],
self
.
Nonce
)
binary
.
BigEndian
.
PutUint32
(
d
[
60
:
],
self
.
Nonce
)
return
common
.
FirstBitSet
(
common
.
BigD
(
crypto
.
Sha3
(
d
)))
>
0
return
common
.
FirstBitSet
(
common
.
BigD
(
crypto
.
Sha3
(
d
)))
>
0
}
}
func
(
self
*
Envelope
)
withoutNonce
()
interface
{}
{
// rlpWithoutNonce returns the RLP encoded envelope contents, except the nonce.
return
[]
interface
{}{
self
.
Expiry
,
self
.
TTL
,
self
.
Topics
,
self
.
Data
}
func
(
self
*
Envelope
)
rlpWithoutNonce
()
[]
byte
{
enc
,
_
:=
rlp
.
EncodeToBytes
([]
interface
{}{
self
.
Expiry
,
self
.
TTL
,
self
.
Topics
,
self
.
Data
})
return
enc
}
// Open extracts the message contained within a potentially encrypted envelope.
func
(
self
*
Envelope
)
Open
(
key
*
ecdsa
.
PrivateKey
)
(
msg
*
Message
,
err
error
)
{
// Split open the payload into a message construct
data
:=
self
.
Data
message
:=
&
Message
{
Flags
:
data
[
0
],
}
data
=
data
[
1
:
]
if
message
.
Flags
&
128
==
128
{
if
len
(
data
)
<
65
{
return
nil
,
fmt
.
Errorf
(
"unable to open envelope. First bit set but len(data) < 65"
)
}
message
.
Signature
,
data
=
data
[
:
65
],
data
[
65
:
]
}
message
.
Payload
=
data
// Short circuit if the encryption was requested
if
key
==
nil
{
return
message
,
nil
}
// Otherwise try to decrypt the message
message
.
Payload
,
err
=
crypto
.
Decrypt
(
key
,
message
.
Payload
)
switch
err
{
case
nil
:
return
message
,
nil
case
ecies
.
ErrInvalidPublicKey
:
// Payload isn't encrypted
return
message
,
err
default
:
return
nil
,
fmt
.
Errorf
(
"unable to open envelope, decrypt failed: %v"
,
err
)
}
}
// Hash returns the SHA3 hash of the envelope, calculating it if not yet done.
func
(
self
*
Envelope
)
Hash
()
common
.
Hash
{
if
(
self
.
hash
==
common
.
Hash
{})
{
enc
,
_
:=
rlp
.
EncodeToBytes
(
self
)
self
.
hash
=
crypto
.
Sha3Hash
(
enc
)
}
return
self
.
hash
}
}
// rlpenv is an Envelope but is not an rlp.Decoder.
// rlpenv is an Envelope but is not an rlp.Decoder.
// It is used for decoding because we need to
// It is used for decoding because we need to
type
rlpenv
Envelope
type
rlpenv
Envelope
// DecodeRLP decodes an Envelope from an RLP data stream.
func
(
self
*
Envelope
)
DecodeRLP
(
s
*
rlp
.
Stream
)
error
{
func
(
self
*
Envelope
)
DecodeRLP
(
s
*
rlp
.
Stream
)
error
{
raw
,
err
:=
s
.
Raw
()
raw
,
err
:=
s
.
Raw
()
if
err
!=
nil
{
if
err
!=
nil
{
...
...
whisper/main.go
View file @
faa27478
// +build none
// +build none
// Contains a simple whisper peer setup and self messaging to allow playing
// around with the protocol and API without a fancy client implementation.
package
main
package
main
import
(
import
(
"fmt"
"fmt"
"log"
"log"
"os"
"os"
"time"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/nat"
"github.com/ethereum/go-ethereum/whisper"
"github.com/ethereum/go-ethereum/whisper"
)
)
func
main
()
{
func
main
()
{
logger
.
AddLogSystem
(
logger
.
NewStdLogSystem
(
os
.
Stdout
,
log
.
LstdFlags
,
logger
.
InfoLevel
))
logger
.
AddLogSystem
(
logger
.
NewStdLogSystem
(
os
.
Stdout
,
log
.
LstdFlags
,
logger
.
InfoLevel
))
pub
,
_
:=
secp256k1
.
GenerateKeyPair
()
// Generate the peer identity
key
,
err
:=
crypto
.
GenerateKey
()
whisper
:=
whisper
.
New
()
if
err
!=
nil
{
fmt
.
Printf
(
"Failed to generate peer key: %v.
\n
"
,
err
)
os
.
Exit
(
-
1
)
}
name
:=
common
.
MakeName
(
"whisper-go"
,
"1.0"
)
shh
:=
whisper
.
New
()
srv
:=
p2p
.
Server
{
// Create an Ethereum peer to communicate through
server
:=
p2p
.
Server
{
PrivateKey
:
key
,
MaxPeers
:
10
,
MaxPeers
:
10
,
Identity
:
p2p
.
NewSimpleClientIdentity
(
"whisper-go"
,
"1.0"
,
""
,
string
(
pub
)),
Name
:
name
,
Protocols
:
[]
p2p
.
Protocol
{
shh
.
Protocol
()},
ListenAddr
:
":30300"
,
ListenAddr
:
":30300"
,
NAT
:
p2p
.
UPNP
(),
NAT
:
nat
.
Any
(),
Protocols
:
[]
p2p
.
Protocol
{
whisper
.
Protocol
()},
}
}
if
err
:=
srv
.
Start
();
err
!=
nil
{
fmt
.
Println
(
"Starting Ethereum peer..."
)
fmt
.
Println
(
"could not start server:"
,
err
)
if
err
:=
server
.
Start
();
err
!=
nil
{
fmt
.
Printf
(
"Failed to start Ethereum peer: %v.
\n
"
,
err
)
os
.
Exit
(
1
)
os
.
Exit
(
1
)
}
}
select
{}
// Send a message to self to check that something works
payload
:=
fmt
.
Sprintf
(
"Hello world, this is %v. In case you're wondering, the time is %v"
,
name
,
time
.
Now
())
if
err
:=
selfSend
(
shh
,
[]
byte
(
payload
));
err
!=
nil
{
fmt
.
Printf
(
"Failed to self message: %v.
\n
"
,
err
)
os
.
Exit
(
-
1
)
}
}
// SendSelf wraps a payload into a Whisper envelope and forwards it to itself.
func
selfSend
(
shh
*
whisper
.
Whisper
,
payload
[]
byte
)
error
{
ok
:=
make
(
chan
struct
{})
// Start watching for self messages, output any arrivals
id
:=
shh
.
NewIdentity
()
shh
.
Watch
(
whisper
.
Filter
{
To
:
&
id
.
PublicKey
,
Fn
:
func
(
msg
*
whisper
.
Message
)
{
fmt
.
Printf
(
"Message received: %s, signed with 0x%x.
\n
"
,
string
(
msg
.
Payload
),
msg
.
Signature
)
close
(
ok
)
},
})
// Wrap the payload and encrypt it
msg
:=
whisper
.
NewMessage
(
payload
)
envelope
,
err
:=
msg
.
Wrap
(
whisper
.
DefaultProofOfWork
,
whisper
.
Options
{
From
:
id
,
To
:
&
id
.
PublicKey
,
TTL
:
whisper
.
DefaultTimeToLive
,
})
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to seal message: %v"
,
err
)
}
// Dump the message into the system and wait for it to pop back out
if
err
:=
shh
.
Send
(
envelope
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to send self-message: %v"
,
err
)
}
select
{
case
<-
ok
:
case
<-
time
.
After
(
time
.
Second
)
:
return
fmt
.
Errorf
(
"failed to receive message in time"
)
}
return
nil
}
}
whisper/message.go
View file @
faa27478
// Contains the Whisper protocol Message element. For formal details please see
// the specs at https://github.com/ethereum/wiki/wiki/Whisper-PoC-1-Protocol-Spec#messages.
package
whisper
package
whisper
import
(
import
(
"crypto/ecdsa"
"crypto/ecdsa"
"math/rand"
"time"
"time"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto"
...
@@ -9,8 +13,11 @@ import (
...
@@ -9,8 +13,11 @@ import (
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/logger/glog"
)
)
// Message represents an end-user data packet to trasmit through the Whisper
// protocol. These are wrapped into Envelopes that need not be understood by
// intermediate nodes, just forwarded.
type
Message
struct
{
type
Message
struct
{
Flags
byte
Flags
byte
// First bit is signature presence, rest reserved and should be random
Signature
[]
byte
Signature
[]
byte
Payload
[]
byte
Payload
[]
byte
Sent
int64
Sent
int64
...
@@ -18,71 +25,95 @@ type Message struct {
...
@@ -18,71 +25,95 @@ type Message struct {
To
*
ecdsa
.
PublicKey
To
*
ecdsa
.
PublicKey
}
}
// Options specifies the exact way a message should be wrapped into an Envelope.
type
Options
struct
{
From
*
ecdsa
.
PrivateKey
To
*
ecdsa
.
PublicKey
TTL
time
.
Duration
Topics
[][]
byte
}
// NewMessage creates and initializes a non-signed, non-encrypted Whisper message.
func
NewMessage
(
payload
[]
byte
)
*
Message
{
func
NewMessage
(
payload
[]
byte
)
*
Message
{
return
&
Message
{
Flags
:
0
,
Payload
:
payload
,
Sent
:
time
.
Now
()
.
Unix
()}
// Construct an initial flag set: bit #1 = 0 (no signature), rest random
flags
:=
byte
(
rand
.
Intn
(
128
))
// Assemble and return the message
return
&
Message
{
Flags
:
flags
,
Payload
:
payload
,
Sent
:
time
.
Now
()
.
Unix
(),
}
}
}
func
(
self
*
Message
)
hash
()
[]
byte
{
// Wrap bundles the message into an Envelope to transmit over the network.
return
crypto
.
Sha3
(
append
([]
byte
{
self
.
Flags
},
self
.
Payload
...
))
//
// pow (Proof Of Work) controls how much time to spend on hashing the message,
// inherently controlling its priority through the network (smaller hash, bigger
// priority).
//
// The user can control the amount of identity, privacy and encryption through
// the options parameter as follows:
// - options.From == nil && options.To == nil: anonymous broadcast
// - options.From != nil && options.To == nil: signed broadcast (known sender)
// - options.From == nil && options.To != nil: encrypted anonymous message
// - options.From != nil && options.To != nil: encrypted signed message
func
(
self
*
Message
)
Wrap
(
pow
time
.
Duration
,
options
Options
)
(
*
Envelope
,
error
)
{
// Use the default TTL if non was specified
if
options
.
TTL
==
0
{
options
.
TTL
=
DefaultTimeToLive
}
// Sign and encrypt the message if requested
if
options
.
From
!=
nil
{
if
err
:=
self
.
sign
(
options
.
From
);
err
!=
nil
{
return
nil
,
err
}
}
if
options
.
To
!=
nil
{
if
err
:=
self
.
encrypt
(
options
.
To
);
err
!=
nil
{
return
nil
,
err
}
}
// Wrap the processed message, seal it and return
envelope
:=
NewEnvelope
(
options
.
TTL
,
options
.
Topics
,
self
)
envelope
.
Seal
(
pow
)
return
envelope
,
nil
}
}
// sign calculates and sets the cryptographic signature for the message , also
// setting the sign flag.
func
(
self
*
Message
)
sign
(
key
*
ecdsa
.
PrivateKey
)
(
err
error
)
{
func
(
self
*
Message
)
sign
(
key
*
ecdsa
.
PrivateKey
)
(
err
error
)
{
self
.
Flags
=
1
self
.
Flags
|=
1
<<
7
self
.
Signature
,
err
=
crypto
.
Sign
(
self
.
hash
(),
key
)
self
.
Signature
,
err
=
crypto
.
Sign
(
self
.
hash
(),
key
)
return
return
}
}
// Recover retrieves the public key of the message signer.
func
(
self
*
Message
)
Recover
()
*
ecdsa
.
PublicKey
{
func
(
self
*
Message
)
Recover
()
*
ecdsa
.
PublicKey
{
defer
func
()
{
recover
()
}()
// in case of invalid sig
defer
func
()
{
recover
()
}()
// in case of invalid signature
pub
,
err
:=
crypto
.
SigToPub
(
self
.
hash
(),
self
.
Signature
)
pub
,
err
:=
crypto
.
SigToPub
(
self
.
hash
(),
self
.
Signature
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Could not get pub
key from signature:
"
,
err
)
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Could not get pub
lic key from signature: %v
"
,
err
)
return
nil
return
nil
}
}
return
pub
return
pub
}
}
func
(
self
*
Message
)
Encrypt
(
to
*
ecdsa
.
PublicKey
)
(
err
error
)
{
// encrypt encrypts a message payload with a public key.
func
(
self
*
Message
)
encrypt
(
to
*
ecdsa
.
PublicKey
)
(
err
error
)
{
self
.
Payload
,
err
=
crypto
.
Encrypt
(
to
,
self
.
Payload
)
self
.
Payload
,
err
=
crypto
.
Encrypt
(
to
,
self
.
Payload
)
if
err
!=
nil
{
return
return
err
}
return
nil
}
func
(
self
*
Message
)
Bytes
()
[]
byte
{
return
append
([]
byte
{
self
.
Flags
},
append
(
self
.
Signature
,
self
.
Payload
...
)
...
)
}
}
type
Opts
struct
{
// hash calculates the SHA3 checksum of the message flags and payload.
From
*
ecdsa
.
PrivateKey
func
(
self
*
Message
)
hash
()
[]
byte
{
To
*
ecdsa
.
PublicKey
return
crypto
.
Sha3
(
append
([]
byte
{
self
.
Flags
},
self
.
Payload
...
))
Ttl
time
.
Duration
Topics
[][]
byte
}
}
func
(
self
*
Message
)
Seal
(
pow
time
.
Duration
,
opts
Opts
)
(
*
Envelope
,
error
)
{
// bytes flattens the message contents (flags, signature and payload) into a
if
opts
.
From
!=
nil
{
// single binary blob.
err
:=
self
.
sign
(
opts
.
From
)
func
(
self
*
Message
)
bytes
()
[]
byte
{
if
err
!=
nil
{
return
append
([]
byte
{
self
.
Flags
},
append
(
self
.
Signature
,
self
.
Payload
...
)
...
)
return
nil
,
err
}
}
if
opts
.
To
!=
nil
{
err
:=
self
.
Encrypt
(
opts
.
To
)
if
err
!=
nil
{
return
nil
,
err
}
}
if
opts
.
Ttl
==
0
{
opts
.
Ttl
=
DefaultTtl
}
envelope
:=
NewEnvelope
(
opts
.
Ttl
,
opts
.
Topics
,
self
)
envelope
.
Seal
(
pow
)
return
envelope
,
nil
}
}
whisper/message_test.go
0 → 100644
View file @
faa27478
package
whisper
import
(
"bytes"
"crypto/elliptic"
"testing"
"github.com/ethereum/go-ethereum/crypto"
)
// Tests whether a message can be wrapped without any identity or encryption.
func
TestMessageSimpleWrap
(
t
*
testing
.
T
)
{
payload
:=
[]
byte
(
"hello world"
)
msg
:=
NewMessage
(
payload
)
if
_
,
err
:=
msg
.
Wrap
(
DefaultProofOfWork
,
Options
{});
err
!=
nil
{
t
.
Fatalf
(
"failed to wrap message: %v"
,
err
)
}
if
msg
.
Flags
&
128
!=
0
{
t
.
Fatalf
(
"signature flag mismatch: have %d, want %d"
,
(
msg
.
Flags
&
128
)
>>
7
,
0
)
}
if
len
(
msg
.
Signature
)
!=
0
{
t
.
Fatalf
(
"signature found for simple wrapping: 0x%x"
,
msg
.
Signature
)
}
if
bytes
.
Compare
(
msg
.
Payload
,
payload
)
!=
0
{
t
.
Fatalf
(
"payload mismatch after wrapping: have 0x%x, want 0x%x"
,
msg
.
Payload
,
payload
)
}
}
// Tests whether a message can be signed, and wrapped in plain-text.
func
TestMessageCleartextSignRecover
(
t
*
testing
.
T
)
{
key
,
err
:=
crypto
.
GenerateKey
()
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create crypto key: %v"
,
err
)
}
payload
:=
[]
byte
(
"hello world"
)
msg
:=
NewMessage
(
payload
)
if
_
,
err
:=
msg
.
Wrap
(
DefaultProofOfWork
,
Options
{
From
:
key
,
});
err
!=
nil
{
t
.
Fatalf
(
"failed to sign message: %v"
,
err
)
}
if
msg
.
Flags
&
128
!=
128
{
t
.
Fatalf
(
"signature flag mismatch: have %d, want %d"
,
(
msg
.
Flags
&
128
)
>>
7
,
1
)
}
if
bytes
.
Compare
(
msg
.
Payload
,
payload
)
!=
0
{
t
.
Fatalf
(
"payload mismatch after signing: have 0x%x, want 0x%x"
,
msg
.
Payload
,
payload
)
}
pubKey
:=
msg
.
Recover
()
if
pubKey
==
nil
{
t
.
Fatalf
(
"failed to recover public key"
)
}
p1
:=
elliptic
.
Marshal
(
crypto
.
S256
(),
key
.
PublicKey
.
X
,
key
.
PublicKey
.
Y
)
p2
:=
elliptic
.
Marshal
(
crypto
.
S256
(),
pubKey
.
X
,
pubKey
.
Y
)
if
!
bytes
.
Equal
(
p1
,
p2
)
{
t
.
Fatalf
(
"public key mismatch: have 0x%x, want 0x%x"
,
p2
,
p1
)
}
}
// Tests whether a message can be encrypted and decrypted using an anonymous
// sender (i.e. no signature).
func
TestMessageAnonymousEncryptDecrypt
(
t
*
testing
.
T
)
{
key
,
err
:=
crypto
.
GenerateKey
()
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create recipient crypto key: %v"
,
err
)
}
payload
:=
[]
byte
(
"hello world"
)
msg
:=
NewMessage
(
payload
)
envelope
,
err
:=
msg
.
Wrap
(
DefaultProofOfWork
,
Options
{
To
:
&
key
.
PublicKey
,
})
if
err
!=
nil
{
t
.
Fatalf
(
"failed to encrypt message: %v"
,
err
)
}
if
msg
.
Flags
&
128
!=
0
{
t
.
Fatalf
(
"signature flag mismatch: have %d, want %d"
,
(
msg
.
Flags
&
128
)
>>
7
,
0
)
}
if
len
(
msg
.
Signature
)
!=
0
{
t
.
Fatalf
(
"signature found for anonymous message: 0x%x"
,
msg
.
Signature
)
}
out
,
err
:=
envelope
.
Open
(
key
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to open encrypted message: %v"
,
err
)
}
if
!
bytes
.
Equal
(
out
.
Payload
,
payload
)
{
t
.
Error
(
"payload mismatch: have 0x%x, want 0x%x"
,
out
.
Payload
,
payload
)
}
}
// Tests whether a message can be properly signed and encrypted.
func
TestMessageFullCrypto
(
t
*
testing
.
T
)
{
fromKey
,
err
:=
crypto
.
GenerateKey
()
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create sender crypto key: %v"
,
err
)
}
toKey
,
err
:=
crypto
.
GenerateKey
()
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create recipient crypto key: %v"
,
err
)
}
payload
:=
[]
byte
(
"hello world"
)
msg
:=
NewMessage
(
payload
)
envelope
,
err
:=
msg
.
Wrap
(
DefaultProofOfWork
,
Options
{
From
:
fromKey
,
To
:
&
toKey
.
PublicKey
,
})
if
err
!=
nil
{
t
.
Fatalf
(
"failed to encrypt message: %v"
,
err
)
}
if
msg
.
Flags
&
128
!=
128
{
t
.
Fatalf
(
"signature flag mismatch: have %d, want %d"
,
(
msg
.
Flags
&
128
)
>>
7
,
1
)
}
if
len
(
msg
.
Signature
)
==
0
{
t
.
Fatalf
(
"no signature found for signed message"
)
}
out
,
err
:=
envelope
.
Open
(
toKey
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to open encrypted message: %v"
,
err
)
}
if
!
bytes
.
Equal
(
out
.
Payload
,
payload
)
{
t
.
Error
(
"payload mismatch: have 0x%x, want 0x%x"
,
out
.
Payload
,
payload
)
}
pubKey
:=
out
.
Recover
()
if
pubKey
==
nil
{
t
.
Fatalf
(
"failed to recover public key"
)
}
p1
:=
elliptic
.
Marshal
(
crypto
.
S256
(),
fromKey
.
PublicKey
.
X
,
fromKey
.
PublicKey
.
Y
)
p2
:=
elliptic
.
Marshal
(
crypto
.
S256
(),
pubKey
.
X
,
pubKey
.
Y
)
if
!
bytes
.
Equal
(
p1
,
p2
)
{
t
.
Fatalf
(
"public key mismatch: have 0x%x, want 0x%x"
,
p2
,
p1
)
}
}
whisper/messages_test.go
deleted
100644 → 0
View file @
61db7a71
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
{
t
.
Error
(
err
)
t
.
FailNow
()
}
if
!
bytes
.
Equal
(
msg1
.
Payload
,
data
)
{
t
.
Error
(
"encryption error. data did not match"
)
}
}
whisper/whisper.go
View file @
faa27478
...
@@ -28,7 +28,10 @@ type MessageEvent struct {
...
@@ -28,7 +28,10 @@ type MessageEvent struct {
Message
*
Message
Message
*
Message
}
}
const
DefaultTtl
=
50
*
time
.
Second
const
(
DefaultTimeToLive
=
50
*
time
.
Second
DefaultProofOfWork
=
50
*
time
.
Millisecond
)
type
Whisper
struct
{
type
Whisper
struct
{
protocol
p2p
.
Protocol
protocol
p2p
.
Protocol
...
...
whisper/whisper_test.go
View file @
faa27478
...
@@ -18,8 +18,8 @@ func TestEvent(t *testing.T) {
...
@@ -18,8 +18,8 @@ func TestEvent(t *testing.T) {
})
})
msg
:=
NewMessage
([]
byte
(
fmt
.
Sprintf
(
"Hello world. This is whisper-go. Incase you're wondering; the time is %v"
,
time
.
Now
())))
msg
:=
NewMessage
([]
byte
(
fmt
.
Sprintf
(
"Hello world. This is whisper-go. Incase you're wondering; the time is %v"
,
time
.
Now
())))
envelope
,
err
:=
msg
.
Seal
(
DefaultPow
,
Opt
s
{
envelope
,
err
:=
msg
.
Wrap
(
DefaultProofOfWork
,
Option
s
{
T
tl
:
DefaultTtl
,
T
TL
:
DefaultTimeToLive
,
From
:
id
,
From
:
id
,
To
:
&
id
.
PublicKey
,
To
:
&
id
.
PublicKey
,
})
})
...
...
xeth/whisper.go
View file @
faa27478
...
@@ -32,8 +32,8 @@ func (self *Whisper) Post(payload string, to, from string, topics []string, prio
...
@@ -32,8 +32,8 @@ func (self *Whisper) Post(payload string, to, from string, topics []string, prio
pk
:=
crypto
.
ToECDSAPub
(
common
.
FromHex
(
from
))
pk
:=
crypto
.
ToECDSAPub
(
common
.
FromHex
(
from
))
if
key
:=
self
.
Whisper
.
GetIdentity
(
pk
);
key
!=
nil
||
len
(
from
)
==
0
{
if
key
:=
self
.
Whisper
.
GetIdentity
(
pk
);
key
!=
nil
||
len
(
from
)
==
0
{
msg
:=
whisper
.
NewMessage
(
common
.
FromHex
(
payload
))
msg
:=
whisper
.
NewMessage
(
common
.
FromHex
(
payload
))
envelope
,
err
:=
msg
.
Seal
(
time
.
Duration
(
priority
*
100000
),
whisper
.
Opt
s
{
envelope
,
err
:=
msg
.
Wrap
(
time
.
Duration
(
priority
*
100000
),
whisper
.
Option
s
{
T
tl
:
time
.
Duration
(
ttl
)
*
time
.
Second
,
T
TL
:
time
.
Duration
(
ttl
)
*
time
.
Second
,
To
:
crypto
.
ToECDSAPub
(
common
.
FromHex
(
to
)),
To
:
crypto
.
ToECDSAPub
(
common
.
FromHex
(
to
)),
From
:
key
,
From
:
key
,
Topics
:
whisper
.
TopicsFromString
(
topics
...
),
Topics
:
whisper
.
TopicsFromString
(
topics
...
),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment