mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-26 03:01:42 +00:00
crypto byte arrays are fixed length
This commit is contained in:
@ -38,8 +38,8 @@ func GenPrivAccount() *PrivAccount {
|
|||||||
privKeyBytes := new([64]byte)
|
privKeyBytes := new([64]byte)
|
||||||
copy(privKeyBytes[:32], CRandBytes(32))
|
copy(privKeyBytes[:32], CRandBytes(32))
|
||||||
pubKeyBytes := ed25519.MakePublicKey(privKeyBytes)
|
pubKeyBytes := ed25519.MakePublicKey(privKeyBytes)
|
||||||
pubKey := PubKeyEd25519(pubKeyBytes[:])
|
pubKey := PubKeyEd25519(*pubKeyBytes)
|
||||||
privKey := PrivKeyEd25519(privKeyBytes[:])
|
privKey := PrivKeyEd25519(*privKeyBytes)
|
||||||
return &PrivAccount{
|
return &PrivAccount{
|
||||||
Address: pubKey.Address(),
|
Address: pubKey.Address(),
|
||||||
PubKey: pubKey,
|
PubKey: pubKey,
|
||||||
@ -53,8 +53,8 @@ func GenPrivAccountFromSecret(secret []byte) *PrivAccount {
|
|||||||
privKeyBytes := new([64]byte)
|
privKeyBytes := new([64]byte)
|
||||||
copy(privKeyBytes[:32], privKey32)
|
copy(privKeyBytes[:32], privKey32)
|
||||||
pubKeyBytes := ed25519.MakePublicKey(privKeyBytes)
|
pubKeyBytes := ed25519.MakePublicKey(privKeyBytes)
|
||||||
pubKey := PubKeyEd25519(pubKeyBytes[:])
|
pubKey := PubKeyEd25519(*pubKeyBytes)
|
||||||
privKey := PrivKeyEd25519(privKeyBytes[:])
|
privKey := PrivKeyEd25519(*privKeyBytes)
|
||||||
return &PrivAccount{
|
return &PrivAccount{
|
||||||
Address: pubKey.Address(),
|
Address: pubKey.Address(),
|
||||||
PubKey: pubKey,
|
PubKey: pubKey,
|
||||||
@ -62,15 +62,13 @@ func GenPrivAccountFromSecret(secret []byte) *PrivAccount {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenPrivAccountFromPrivKeyBytes(privKeyBytes []byte) *PrivAccount {
|
func GenPrivAccountFromPrivKeyBytes(privKeyBytes *[64]byte) *PrivAccount {
|
||||||
if len(privKeyBytes) != 64 {
|
if len(privKeyBytes) != 64 {
|
||||||
panic(Fmt("Expected 64 bytes but got %v", len(privKeyBytes)))
|
panic(Fmt("Expected 64 bytes but got %v", len(privKeyBytes)))
|
||||||
}
|
}
|
||||||
privKeyBytes64 := [64]byte{}
|
pubKeyBytes := ed25519.MakePublicKey(privKeyBytes)
|
||||||
copy(privKeyBytes64[:], privKeyBytes)
|
pubKey := PubKeyEd25519(*pubKeyBytes)
|
||||||
pubKeyBytes := ed25519.MakePublicKey(&privKeyBytes64)
|
privKey := PrivKeyEd25519(*privKeyBytes)
|
||||||
pubKey := PubKeyEd25519(pubKeyBytes[:])
|
|
||||||
privKey := PrivKeyEd25519(privKeyBytes)
|
|
||||||
return &PrivAccount{
|
return &PrivAccount{
|
||||||
Address: pubKey.Address(),
|
Address: pubKey.Address(),
|
||||||
PubKey: pubKey,
|
PubKey: pubKey,
|
||||||
|
@ -27,27 +27,23 @@ var _ = binary.RegisterInterface(
|
|||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
// Implements PrivKey
|
// Implements PrivKey
|
||||||
type PrivKeyEd25519 []byte
|
type PrivKeyEd25519 [64]byte
|
||||||
|
|
||||||
func (key PrivKeyEd25519) Sign(msg []byte) Signature {
|
func (key PrivKeyEd25519) Sign(msg []byte) Signature {
|
||||||
pubKey := key.PubKey().(PubKeyEd25519)
|
privKeyBytes := [64]byte(key)
|
||||||
keyBytes := new([64]byte)
|
signatureBytes := ed25519.Sign(&privKeyBytes, msg)
|
||||||
copy(keyBytes[:32], key[:])
|
return SignatureEd25519(*signatureBytes)
|
||||||
copy(keyBytes[32:], pubKey[:])
|
|
||||||
signatureBytes := ed25519.Sign(keyBytes, msg)
|
|
||||||
return SignatureEd25519(signatureBytes[:])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (privKey PrivKeyEd25519) PubKey() PubKey {
|
func (privKey PrivKeyEd25519) PubKey() PubKey {
|
||||||
privKeyBytes := new([64]byte)
|
privKeyBytes := [64]byte(privKey)
|
||||||
copy(privKeyBytes[:], privKey[:])
|
return PubKeyEd25519(*ed25519.MakePublicKey(&privKeyBytes))
|
||||||
return PubKeyEd25519(ed25519.MakePublicKey(privKeyBytes)[:])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte {
|
func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte {
|
||||||
keyEd25519, keyCurve25519 := new([64]byte), new([32]byte)
|
keyCurve25519 := new([32]byte)
|
||||||
copy(keyEd25519[:], privKey)
|
privKeyBytes := [64]byte(privKey)
|
||||||
extra25519.PrivateKeyToCurve25519(keyCurve25519, keyEd25519)
|
extra25519.PrivateKeyToCurve25519(keyCurve25519, &privKeyBytes)
|
||||||
return keyCurve25519
|
return keyCurve25519
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,15 +54,17 @@ func (privKey PrivKeyEd25519) String() string {
|
|||||||
// Deterministically generates new priv-key bytes from key.
|
// Deterministically generates new priv-key bytes from key.
|
||||||
func (key PrivKeyEd25519) Generate(index int) PrivKeyEd25519 {
|
func (key PrivKeyEd25519) Generate(index int) PrivKeyEd25519 {
|
||||||
newBytes := binary.BinarySha256(struct {
|
newBytes := binary.BinarySha256(struct {
|
||||||
PrivKey []byte
|
PrivKey [64]byte
|
||||||
Index int
|
Index int
|
||||||
}{key, index})
|
}{key, index})
|
||||||
return PrivKeyEd25519(newBytes)
|
var newKey [64]byte
|
||||||
|
copy(newKey[:], newBytes)
|
||||||
|
return PrivKeyEd25519(newKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenPrivKeyEd25519() PrivKeyEd25519 {
|
func GenPrivKeyEd25519() PrivKeyEd25519 {
|
||||||
privKeyBytes := new([64]byte)
|
privKeyBytes := new([64]byte)
|
||||||
copy(privKeyBytes[:32], CRandBytes(32))
|
copy(privKeyBytes[:32], CRandBytes(32))
|
||||||
ed25519.MakePublicKey(privKeyBytes)
|
ed25519.MakePublicKey(privKeyBytes)
|
||||||
return PrivKeyEd25519(privKeyBytes[:])
|
return PrivKeyEd25519(*privKeyBytes)
|
||||||
}
|
}
|
||||||
|
@ -31,12 +31,12 @@ var _ = binary.RegisterInterface(
|
|||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
// Implements PubKey
|
// Implements PubKey
|
||||||
type PubKeyEd25519 []byte
|
type PubKeyEd25519 [32]byte
|
||||||
|
|
||||||
func (pubKey PubKeyEd25519) IsNil() bool { return false }
|
func (pubKey PubKeyEd25519) IsNil() bool { return false }
|
||||||
|
|
||||||
// TODO: Or should this just be BinaryRipemd160(key)? (The difference is the TypeByte.)
|
// TODO: Or should this just be BinaryRipemd160(key)? (The difference is the TypeByte.)
|
||||||
func (pubKey PubKeyEd25519) Address() []byte { return binary.BinaryRipemd160(pubKey) }
|
func (pubKey PubKeyEd25519) Address() []byte { return binary.BinaryRipemd160(pubKey[:]) }
|
||||||
|
|
||||||
// TODO: Consider returning a reason for failure, or logging a runtime type mismatch.
|
// TODO: Consider returning a reason for failure, or logging a runtime type mismatch.
|
||||||
func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool {
|
func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool {
|
||||||
@ -44,25 +44,23 @@ func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
pubKeyBytes := new([32]byte)
|
pubKeyBytes := [32]byte(pubKey)
|
||||||
copy(pubKeyBytes[:], pubKey)
|
sigBytes := [64]byte(sig)
|
||||||
sigBytes := new([64]byte)
|
return ed25519.Verify(&pubKeyBytes, msg, &sigBytes)
|
||||||
copy(sigBytes[:], sig)
|
|
||||||
return ed25519.Verify(pubKeyBytes, msg, sigBytes)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For use with golang/crypto/nacl/box
|
// For use with golang/crypto/nacl/box
|
||||||
// If error, returns nil.
|
// If error, returns nil.
|
||||||
func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte {
|
func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte {
|
||||||
keyEd25519, keyCurve25519 := new([32]byte), new([32]byte)
|
keyCurve25519, pubKeyBytes := new([32]byte), [32]byte(pubKey)
|
||||||
copy(keyEd25519[:], pubKey)
|
ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes)
|
||||||
ok := extra25519.PublicKeyToCurve25519(keyCurve25519, keyEd25519)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return keyCurve25519
|
return keyCurve25519
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// redundant: compiler does it for us
|
||||||
func (pubKey PubKeyEd25519) ValidateBasic() error {
|
func (pubKey PubKeyEd25519) ValidateBasic() error {
|
||||||
if len(pubKey) != ed25519.PublicKeySize {
|
if len(pubKey) != ed25519.PublicKeySize {
|
||||||
return errors.New("Invalid PubKeyEd25519 key size")
|
return errors.New("Invalid PubKeyEd25519 key size")
|
||||||
@ -71,18 +69,18 @@ func (pubKey PubKeyEd25519) ValidateBasic() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pubKey PubKeyEd25519) String() string {
|
func (pubKey PubKeyEd25519) String() string {
|
||||||
return Fmt("PubKeyEd25519{%X}", []byte(pubKey))
|
return Fmt("PubKeyEd25519{%X}", pubKey[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must return the full bytes in hex.
|
// Must return the full bytes in hex.
|
||||||
// Used for map keying, etc.
|
// Used for map keying, etc.
|
||||||
func (pubKey PubKeyEd25519) KeyString() string {
|
func (pubKey PubKeyEd25519) KeyString() string {
|
||||||
return Fmt("%X", []byte(pubKey))
|
return Fmt("%X", pubKey[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pubKey PubKeyEd25519) Equals(other PubKey) bool {
|
func (pubKey PubKeyEd25519) Equals(other PubKey) bool {
|
||||||
if _, ok := other.(PubKeyEd25519); ok {
|
if otherEd, ok := other.(PubKeyEd25519); ok {
|
||||||
return bytes.Equal(pubKey, other.(PubKeyEd25519))
|
return bytes.Equal(pubKey[:], otherEd[:])
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,10 @@ var _ = binary.RegisterInterface(
|
|||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
// Implements Signature
|
// Implements Signature
|
||||||
type SignatureEd25519 []byte
|
type SignatureEd25519 [64]byte
|
||||||
|
|
||||||
func (sig SignatureEd25519) IsNil() bool { return false }
|
func (sig SignatureEd25519) IsNil() bool { return false }
|
||||||
|
|
||||||
func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 }
|
func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 }
|
||||||
|
|
||||||
func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig)) }
|
func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) }
|
||||||
|
@ -25,7 +25,9 @@ func TestSignAndValidate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mutate the signature, just one bit.
|
// Mutate the signature, just one bit.
|
||||||
sig.(SignatureEd25519)[0] ^= byte(0x01)
|
sigEd := sig.(SignatureEd25519)
|
||||||
|
sigEd[0] ^= byte(0x01)
|
||||||
|
sig = Signature(sigEd)
|
||||||
|
|
||||||
if pubKey.VerifyBytes(msg, sig) {
|
if pubKey.VerifyBytes(msg, sig) {
|
||||||
t.Errorf("Account message signature verification should have failed but passed instead")
|
t.Errorf("Account message signature verification should have failed but passed instead")
|
||||||
@ -48,8 +50,8 @@ func TestBinaryDecode(t *testing.T) {
|
|||||||
t.Fatalf("Failed to write Signature: %v", err)
|
t.Fatalf("Failed to write Signature: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(buf.Bytes()) != ed25519.SignatureSize+3 {
|
if len(buf.Bytes()) != ed25519.SignatureSize+1 {
|
||||||
// 1 byte TypeByte, 2 bytes length, 64 bytes signature bytes
|
// 1 byte TypeByte, 64 bytes signature bytes
|
||||||
t.Fatalf("Unexpected signature write size: %v", len(buf.Bytes()))
|
t.Fatalf("Unexpected signature write size: %v", len(buf.Bytes()))
|
||||||
}
|
}
|
||||||
if buf.Bytes()[0] != SignatureTypeEd25519 {
|
if buf.Bytes()[0] != SignatureTypeEd25519 {
|
||||||
|
@ -670,7 +670,8 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debug("Read bytearray", "bytes", buf)
|
log.Debug("Read bytearray", "bytes", buf)
|
||||||
rv.Set(reflect.ValueOf(buf))
|
|
||||||
|
reflect.Copy(rv, reflect.ValueOf(buf))
|
||||||
} else {
|
} else {
|
||||||
oSlice, ok := o.([]interface{})
|
oSlice, ok := o.([]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -864,8 +865,9 @@ func writeReflectJSON(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64,
|
|||||||
length := rt.Len()
|
length := rt.Len()
|
||||||
if elemRt.Kind() == reflect.Uint8 {
|
if elemRt.Kind() == reflect.Uint8 {
|
||||||
// Special case: Bytearray
|
// Special case: Bytearray
|
||||||
bytearray := rv.Interface()
|
bytearray := reflect.ValueOf(make([]byte, length))
|
||||||
WriteTo([]byte(Fmt("\"%X\"", bytearray)), w, n, err)
|
reflect.Copy(bytearray, rv)
|
||||||
|
WriteTo([]byte(Fmt("\"%X\"", bytearray.Interface())), w, n, err)
|
||||||
} else {
|
} else {
|
||||||
WriteTo([]byte("["), w, n, err)
|
WriteTo([]byte("["), w, n, err)
|
||||||
// Write elems
|
// Write elems
|
||||||
|
@ -16,6 +16,38 @@ type SimpleStruct struct {
|
|||||||
Time time.Time
|
Time time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SimpleArray [5]byte
|
||||||
|
|
||||||
|
func TestSimpleArray(t *testing.T) {
|
||||||
|
var foo SimpleArray
|
||||||
|
|
||||||
|
// Type of pointer to array
|
||||||
|
rt := reflect.TypeOf(&foo)
|
||||||
|
fmt.Printf("rt: %v\n", rt)
|
||||||
|
|
||||||
|
// Type of array itself.
|
||||||
|
// NOTE: normally this is acquired through other means
|
||||||
|
// like introspecting on method signatures, or struct fields.
|
||||||
|
rte := rt.Elem()
|
||||||
|
fmt.Printf("rte: %v\n", rte)
|
||||||
|
|
||||||
|
// Get a new pointer to the array
|
||||||
|
// NOTE: calling .Interface() is to get the actual value,
|
||||||
|
// instead of reflection values.
|
||||||
|
ptr := reflect.New(rte).Interface()
|
||||||
|
fmt.Printf("ptr: %v", ptr)
|
||||||
|
|
||||||
|
// Make a simple int aray
|
||||||
|
fooArray := SimpleArray([5]byte{1, 10, 50, 100, 200})
|
||||||
|
fooBytes := BinaryBytes(fooArray)
|
||||||
|
fooReader := bytes.NewReader(fooBytes)
|
||||||
|
|
||||||
|
// Now you can read it.
|
||||||
|
n, err := new(int64), new(error)
|
||||||
|
it := ReadBinary(foo, fooReader, n, err)
|
||||||
|
fmt.Println(it, reflect.TypeOf(it))
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
type Animal interface{}
|
type Animal interface{}
|
||||||
@ -265,6 +297,9 @@ func validateComplex2(o interface{}, t *testing.T) {
|
|||||||
|
|
||||||
type ComplexStructArray struct {
|
type ComplexStructArray struct {
|
||||||
Animals []Animal
|
Animals []Animal
|
||||||
|
Bytes [5]byte
|
||||||
|
Ints [5]int
|
||||||
|
Array SimpleArray
|
||||||
}
|
}
|
||||||
|
|
||||||
func constructComplexArray() interface{} {
|
func constructComplexArray() interface{} {
|
||||||
@ -287,6 +322,9 @@ func constructComplexArray() interface{} {
|
|||||||
Bytes: []byte("hizz"),
|
Bytes: []byte("hizz"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Bytes: [5]byte{1, 10, 50, 100, 200},
|
||||||
|
Ints: [5]int{1, 2, 3, 4, 5},
|
||||||
|
Array: SimpleArray([5]byte{1, 10, 50, 100, 200}),
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,9 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
root := acm.GenPrivAccountFromPrivKeyBytes(privKeyBytes)
|
var privKeyArray [64]byte
|
||||||
|
copy(privKeyArray[:], privKeyBytes)
|
||||||
|
root := acm.GenPrivAccountFromPrivKeyBytes(&privKeyArray)
|
||||||
fmt.Println("Computed address: %X", root.Address)
|
fmt.Println("Computed address: %X", root.Address)
|
||||||
|
|
||||||
// Get root account.
|
// Get root account.
|
||||||
|
@ -110,23 +110,23 @@ var defaultGenesis = `{
|
|||||||
"chain_id" : "tendermint_test",
|
"chain_id" : "tendermint_test",
|
||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"address": "E9B5D87313356465FAE33C406CE2C2979DE60BCB",
|
"address": "C3C1AF26C0CB2C1DB233D8936AD2C6335AAB6844",
|
||||||
"amount": 200000000
|
"amount": 200000000
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "DFE4AFFA4CEE17CD01CB9E061D77C3ECED29BD88",
|
"address": "C76F0E490A003FDB4A94B310C354F1650A6F97B7",
|
||||||
"amount": 200000000
|
"amount": 200000000
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "F60D30722E7B497FA532FB3207C3FB29C31B1992",
|
"address": "576C84059355CD3B8CBDD81C3FCBC5CE5B6632E0",
|
||||||
"amount": 200000000
|
"amount": 200000000
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "336CB40A5EB92E496E19B74FDFF2BA017C877FD6",
|
"address": "CD9AB051EDEA88E61ABDF2A1ACF10C3803F0972F",
|
||||||
"amount": 200000000
|
"amount": 200000000
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"address": "D218F0F439BF0384F6F5EF8D0F8B398D941BD1DC",
|
"address": "4EE2D93B0A1FBA4E9EBE20E088AA122002A2EB0C",
|
||||||
"amount": 200000000
|
"amount": 200000000
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -15,7 +15,6 @@ func TestProposalSignable(t *testing.T) {
|
|||||||
Round: 23456,
|
Round: 23456,
|
||||||
BlockPartsHeader: types.PartSetHeader{111, []byte("blockparts")},
|
BlockPartsHeader: types.PartSetHeader{111, []byte("blockparts")},
|
||||||
POLRound: -1,
|
POLRound: -1,
|
||||||
Signature: nil,
|
|
||||||
}
|
}
|
||||||
signBytes := account.SignBytes(config.GetString("chain_id"), proposal)
|
signBytes := account.SignBytes(config.GetString("chain_id"), proposal)
|
||||||
signStr := string(signBytes)
|
signStr := string(signBytes)
|
||||||
|
@ -22,7 +22,7 @@ const (
|
|||||||
flushThrottleMS = 50
|
flushThrottleMS = 50
|
||||||
idleTimeoutMinutes = 5
|
idleTimeoutMinutes = 5
|
||||||
updateStatsSeconds = 2
|
updateStatsSeconds = 2
|
||||||
pingTimeoutMinutes = 2
|
pingTimeoutSeconds = 40
|
||||||
defaultSendRate = 51200 // 5Kb/s
|
defaultSendRate = 51200 // 5Kb/s
|
||||||
defaultRecvRate = 51200 // 5Kb/s
|
defaultRecvRate = 51200 // 5Kb/s
|
||||||
defaultSendQueueCapacity = 1
|
defaultSendQueueCapacity = 1
|
||||||
@ -97,7 +97,7 @@ func NewMConnection(conn net.Conn, chDescs []*ChannelDescriptor, onReceive recei
|
|||||||
flushTimer: NewThrottleTimer("flush", flushThrottleMS*time.Millisecond),
|
flushTimer: NewThrottleTimer("flush", flushThrottleMS*time.Millisecond),
|
||||||
send: make(chan struct{}, 1),
|
send: make(chan struct{}, 1),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
pingTimer: NewRepeatTimer("ping", pingTimeoutMinutes*time.Minute),
|
pingTimer: NewRepeatTimer("ping", pingTimeoutSeconds*time.Second),
|
||||||
pong: make(chan struct{}),
|
pong: make(chan struct{}),
|
||||||
chStatsTimer: NewRepeatTimer("chStats", updateStatsSeconds*time.Second),
|
chStatsTimer: NewRepeatTimer("chStats", updateStatsSeconds*time.Second),
|
||||||
onReceive: onReceive,
|
onReceive: onReceive,
|
||||||
|
@ -30,6 +30,7 @@ const dataLenSize = 2 // uint16 to describe the length, is <= dataMaxSize
|
|||||||
const dataMaxSize = 1024
|
const dataMaxSize = 1024
|
||||||
const totalFrameSize = dataMaxSize + dataLenSize
|
const totalFrameSize = dataMaxSize + dataLenSize
|
||||||
const sealedFrameSize = totalFrameSize + secretbox.Overhead
|
const sealedFrameSize = totalFrameSize + secretbox.Overhead
|
||||||
|
const authSigMsgSize = (32 + 1) + (64 + 1) // fixed size (length prefixed) byte arrays
|
||||||
|
|
||||||
// Implements net.Conn
|
// Implements net.Conn
|
||||||
type SecretConnection struct {
|
type SecretConnection struct {
|
||||||
@ -78,7 +79,6 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey acm.PrivKeyEd25519
|
|||||||
recvBuffer: nil,
|
recvBuffer: nil,
|
||||||
recvNonce: recvNonce,
|
recvNonce: recvNonce,
|
||||||
sendNonce: sendNonce,
|
sendNonce: sendNonce,
|
||||||
remPubKey: nil,
|
|
||||||
shrSecret: shrSecret,
|
shrSecret: shrSecret,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,10 +86,11 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey acm.PrivKeyEd25519
|
|||||||
locSignature := signChallenge(challenge, locPrivKey)
|
locSignature := signChallenge(challenge, locPrivKey)
|
||||||
|
|
||||||
// Share (in secret) each other's pubkey & challenge signature
|
// Share (in secret) each other's pubkey & challenge signature
|
||||||
remPubKey, remSignature, err := shareAuthSignature(sc, locPubKey, locSignature)
|
authSigMsg, err := shareAuthSignature(sc, locPubKey, locSignature)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
remPubKey, remSignature := authSigMsg.Key, authSigMsg.Sig
|
||||||
if !remPubKey.VerifyBytes(challenge[:], remSignature) {
|
if !remPubKey.VerifyBytes(challenge[:], remSignature) {
|
||||||
return nil, errors.New("Challenge verification failed")
|
return nil, errors.New("Challenge verification failed")
|
||||||
}
|
}
|
||||||
@ -263,7 +264,7 @@ type authSigMessage struct {
|
|||||||
Sig acm.SignatureEd25519
|
Sig acm.SignatureEd25519
|
||||||
}
|
}
|
||||||
|
|
||||||
func shareAuthSignature(sc *SecretConnection, pubKey acm.PubKeyEd25519, signature acm.SignatureEd25519) (acm.PubKeyEd25519, acm.SignatureEd25519, error) {
|
func shareAuthSignature(sc *SecretConnection, pubKey acm.PubKeyEd25519, signature acm.SignatureEd25519) (*authSigMessage, error) {
|
||||||
var recvMsg authSigMessage
|
var recvMsg authSigMessage
|
||||||
var err1, err2 error
|
var err1, err2 error
|
||||||
|
|
||||||
@ -273,10 +274,8 @@ func shareAuthSignature(sc *SecretConnection, pubKey acm.PubKeyEd25519, signatur
|
|||||||
_, err1 = sc.Write(msgBytes)
|
_, err1 = sc.Write(msgBytes)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
// NOTE relies on atomicity of small data.
|
readBuffer := make([]byte, authSigMsgSize)
|
||||||
// XXX: isn't dataMaxSize twice the size of authSigMessage?
|
_, err2 = io.ReadFull(sc, readBuffer)
|
||||||
readBuffer := make([]byte, dataMaxSize)
|
|
||||||
_, err2 = sc.Read(readBuffer)
|
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -285,13 +284,13 @@ func shareAuthSignature(sc *SecretConnection, pubKey acm.PubKeyEd25519, signatur
|
|||||||
})
|
})
|
||||||
|
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
return nil, nil, err1
|
return nil, err1
|
||||||
}
|
}
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
return nil, nil, err2
|
return nil, err2
|
||||||
}
|
}
|
||||||
|
|
||||||
return recvMsg.Key, recvMsg.Sig, nil
|
return &recvMsg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyChallengeSignature(challenge *[32]byte, remPubKey acm.PubKeyEd25519, remSignature acm.SignatureEd25519) bool {
|
func verifyChallengeSignature(challenge *[32]byte, remPubKey acm.PubKeyEd25519, remSignature acm.SignatureEd25519) bool {
|
||||||
|
@ -32,9 +32,9 @@ func makeDummyConnPair() (fooConn, barConn dummyConn) {
|
|||||||
|
|
||||||
func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection) {
|
func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection) {
|
||||||
fooConn, barConn := makeDummyConnPair()
|
fooConn, barConn := makeDummyConnPair()
|
||||||
fooPrvKey := acm.PrivKeyEd25519(CRandBytes(32))
|
fooPrvKey := acm.GenPrivKeyEd25519()
|
||||||
fooPubKey := fooPrvKey.PubKey().(acm.PubKeyEd25519)
|
fooPubKey := fooPrvKey.PubKey().(acm.PubKeyEd25519)
|
||||||
barPrvKey := acm.PrivKeyEd25519(CRandBytes(32))
|
barPrvKey := acm.GenPrivKeyEd25519()
|
||||||
barPubKey := barPrvKey.PubKey().(acm.PubKeyEd25519)
|
barPubKey := barPrvKey.PubKey().(acm.PubKeyEd25519)
|
||||||
|
|
||||||
Parallel(
|
Parallel(
|
||||||
@ -45,7 +45,8 @@ func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection
|
|||||||
tb.Errorf("Failed to establish SecretConnection for foo: %v", err)
|
tb.Errorf("Failed to establish SecretConnection for foo: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !bytes.Equal(fooSecConn.RemotePubKey(), barPubKey) {
|
remotePubBytes := fooSecConn.RemotePubKey()
|
||||||
|
if !bytes.Equal(remotePubBytes[:], barPubKey[:]) {
|
||||||
tb.Errorf("Unexpected fooSecConn.RemotePubKey. Expected %v, got %v",
|
tb.Errorf("Unexpected fooSecConn.RemotePubKey. Expected %v, got %v",
|
||||||
barPubKey, fooSecConn.RemotePubKey())
|
barPubKey, fooSecConn.RemotePubKey())
|
||||||
}
|
}
|
||||||
@ -57,7 +58,8 @@ func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection
|
|||||||
tb.Errorf("Failed to establish SecretConnection for bar: %v", err)
|
tb.Errorf("Failed to establish SecretConnection for bar: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !bytes.Equal(barSecConn.RemotePubKey(), fooPubKey) {
|
remotePubBytes := barSecConn.RemotePubKey()
|
||||||
|
if !bytes.Equal(remotePubBytes[:], fooPubKey[:]) {
|
||||||
tb.Errorf("Unexpected barSecConn.RemotePubKey. Expected %v, got %v",
|
tb.Errorf("Unexpected barSecConn.RemotePubKey. Expected %v, got %v",
|
||||||
fooPubKey, barSecConn.RemotePubKey())
|
fooPubKey, barSecConn.RemotePubKey())
|
||||||
}
|
}
|
||||||
@ -87,7 +89,7 @@ func TestSecretConnectionReadWrite(t *testing.T) {
|
|||||||
genNodeRunner := func(nodeConn dummyConn, nodeWrites []string, nodeReads *[]string) func() {
|
genNodeRunner := func(nodeConn dummyConn, nodeWrites []string, nodeReads *[]string) func() {
|
||||||
return func() {
|
return func() {
|
||||||
// Node handskae
|
// Node handskae
|
||||||
nodePrvKey := acm.PrivKeyEd25519(CRandBytes(32))
|
nodePrvKey := acm.GenPrivKeyEd25519()
|
||||||
nodeSecretConn, err := MakeSecretConnection(nodeConn, nodePrvKey)
|
nodeSecretConn, err := MakeSecretConnection(nodeConn, nodePrvKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to establish SecretConnection for node: %v", err)
|
t.Errorf("Failed to establish SecretConnection for node: %v", err)
|
||||||
|
@ -60,7 +60,7 @@ var (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
peerDialTimeoutSeconds = 3 // TODO make this configurable
|
peerDialTimeoutSeconds = 3 // TODO make this configurable
|
||||||
handshakeTimeoutSeconds = 5 // TODO make this configurable
|
handshakeTimeoutSeconds = 20 // TODO make this configurable
|
||||||
maxNumPeers = 50 // TODO make this configurable
|
maxNumPeers = 50 // TODO make this configurable
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -73,7 +73,6 @@ func NewSwitch() *Switch {
|
|||||||
dialing: NewCMap(),
|
dialing: NewCMap(),
|
||||||
running: 0,
|
running: 0,
|
||||||
nodeInfo: nil,
|
nodeInfo: nil,
|
||||||
nodePrivKey: nil,
|
|
||||||
}
|
}
|
||||||
return sw
|
return sw
|
||||||
}
|
}
|
||||||
@ -178,7 +177,7 @@ func (sw *Switch) Stop() {
|
|||||||
// NOTE: This performs a blocking handshake before the peer is added.
|
// NOTE: This performs a blocking handshake before the peer is added.
|
||||||
// CONTRACT: Iff error is returned, peer is nil, and conn is immediately closed.
|
// CONTRACT: Iff error is returned, peer is nil, and conn is immediately closed.
|
||||||
func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, error) {
|
func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, error) {
|
||||||
// Set deadline so we don't block forever on conn.ReadFull
|
// Set deadline for handshake so we don't block forever on conn.ReadFull
|
||||||
conn.SetDeadline(time.Now().Add(handshakeTimeoutSeconds * time.Second))
|
conn.SetDeadline(time.Now().Add(handshakeTimeoutSeconds * time.Second))
|
||||||
|
|
||||||
// First, encrypt the connection.
|
// First, encrypt the connection.
|
||||||
@ -229,6 +228,8 @@ func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, er
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove deadline and start peer
|
||||||
|
conn.SetDeadline(time.Time{})
|
||||||
if atomic.LoadUint32(&sw.running) == 1 {
|
if atomic.LoadUint32(&sw.running) == 1 {
|
||||||
sw.startInitPeer(peer)
|
sw.startInitPeer(peer)
|
||||||
}
|
}
|
||||||
|
@ -55,8 +55,8 @@ func GenPrivValidator() *PrivValidator {
|
|||||||
privKeyBytes := new([64]byte)
|
privKeyBytes := new([64]byte)
|
||||||
copy(privKeyBytes[:32], CRandBytes(32))
|
copy(privKeyBytes[:32], CRandBytes(32))
|
||||||
pubKeyBytes := ed25519.MakePublicKey(privKeyBytes)
|
pubKeyBytes := ed25519.MakePublicKey(privKeyBytes)
|
||||||
pubKey := account.PubKeyEd25519(pubKeyBytes[:])
|
pubKey := account.PubKeyEd25519(*pubKeyBytes)
|
||||||
privKey := account.PrivKeyEd25519(privKeyBytes[:])
|
privKey := account.PrivKeyEd25519(*privKeyBytes)
|
||||||
return &PrivValidator{
|
return &PrivValidator{
|
||||||
Address: pubKey.Address(),
|
Address: pubKey.Address(),
|
||||||
PubKey: pubKey,
|
PubKey: pubKey,
|
||||||
|
@ -9,10 +9,16 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func randPubKey() account.PubKeyEd25519 {
|
||||||
|
var pubKey [32]byte
|
||||||
|
copy(pubKey[:], RandBytes(32))
|
||||||
|
return account.PubKeyEd25519(pubKey)
|
||||||
|
}
|
||||||
|
|
||||||
func randValidator_() *Validator {
|
func randValidator_() *Validator {
|
||||||
return &Validator{
|
return &Validator{
|
||||||
Address: RandBytes(20),
|
Address: RandBytes(20),
|
||||||
PubKey: account.PubKeyEd25519(RandBytes(64)),
|
PubKey: randPubKey(),
|
||||||
BondHeight: RandInt(),
|
BondHeight: RandInt(),
|
||||||
VotingPower: RandInt64(),
|
VotingPower: RandInt64(),
|
||||||
Accum: RandInt64(),
|
Accum: RandInt64(),
|
||||||
@ -46,21 +52,21 @@ func TestProposerSelection(t *testing.T) {
|
|||||||
vset := NewValidatorSet([]*Validator{
|
vset := NewValidatorSet([]*Validator{
|
||||||
&Validator{
|
&Validator{
|
||||||
Address: []byte("foo"),
|
Address: []byte("foo"),
|
||||||
PubKey: account.PubKeyEd25519(RandBytes(64)),
|
PubKey: randPubKey(),
|
||||||
BondHeight: RandInt(),
|
BondHeight: RandInt(),
|
||||||
VotingPower: 1000,
|
VotingPower: 1000,
|
||||||
Accum: 0,
|
Accum: 0,
|
||||||
},
|
},
|
||||||
&Validator{
|
&Validator{
|
||||||
Address: []byte("bar"),
|
Address: []byte("bar"),
|
||||||
PubKey: account.PubKeyEd25519(RandBytes(64)),
|
PubKey: randPubKey(),
|
||||||
BondHeight: RandInt(),
|
BondHeight: RandInt(),
|
||||||
VotingPower: 300,
|
VotingPower: 300,
|
||||||
Accum: 0,
|
Accum: 0,
|
||||||
},
|
},
|
||||||
&Validator{
|
&Validator{
|
||||||
Address: []byte("baz"),
|
Address: []byte("baz"),
|
||||||
PubKey: account.PubKeyEd25519(RandBytes(64)),
|
PubKey: randPubKey(),
|
||||||
BondHeight: RandInt(),
|
BondHeight: RandInt(),
|
||||||
VotingPower: 330,
|
VotingPower: 330,
|
||||||
Accum: 0,
|
Accum: 0,
|
||||||
|
@ -70,7 +70,10 @@ func TestCallTxSignable(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBondTxSignable(t *testing.T) {
|
func TestBondTxSignable(t *testing.T) {
|
||||||
privAccount := account.GenPrivAccountFromPrivKeyBytes(make([]byte, 64))
|
privKeyBytes := make([]byte, 64)
|
||||||
|
var privKeyArray [64]byte
|
||||||
|
copy(privKeyArray[:], privKeyBytes)
|
||||||
|
privAccount := account.GenPrivAccountFromPrivKeyBytes(&privKeyArray)
|
||||||
bondTx := &BondTx{
|
bondTx := &BondTx{
|
||||||
PubKey: privAccount.PubKey.(account.PubKeyEd25519),
|
PubKey: privAccount.PubKey.(account.PubKeyEd25519),
|
||||||
Inputs: []*TxInput{
|
Inputs: []*TxInput{
|
||||||
@ -101,7 +104,7 @@ func TestBondTxSignable(t *testing.T) {
|
|||||||
expected := Fmt(`{"chain_id":"%s","tx":[17,{"inputs":[{"address":"696E70757431","amount":12345,"sequence":67890},{"address":"696E70757432","amount":111,"sequence":222}],"pub_key":[1,"3B6A27BCCEB6A42D62A3A8D02A6F0D73653215771DE243A63AC048A18B59DA29"],"unbond_to":[{"address":"6F757470757431","amount":333},{"address":"6F757470757432","amount":444}]}]}`,
|
expected := Fmt(`{"chain_id":"%s","tx":[17,{"inputs":[{"address":"696E70757431","amount":12345,"sequence":67890},{"address":"696E70757432","amount":111,"sequence":222}],"pub_key":[1,"3B6A27BCCEB6A42D62A3A8D02A6F0D73653215771DE243A63AC048A18B59DA29"],"unbond_to":[{"address":"6F757470757431","amount":333},{"address":"6F757470757432","amount":444}]}]}`,
|
||||||
config.GetString("chain_id"))
|
config.GetString("chain_id"))
|
||||||
if signStr != expected {
|
if signStr != expected {
|
||||||
t.Errorf("Got unexpected sign string for BondTx")
|
t.Errorf("Unexpected sign string for BondTx. \nGot %s\nExpected %s", signStr, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user