Use status-protocol-go/bridge/geth (#1638)

* Use status-protocol-go/bridge/geth
This commit is contained in:
Pedro Pombeiro 2019-10-14 09:53:38 +02:00 committed by GitHub
parent 4fe317917e
commit c874960215
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 195 additions and 45 deletions

View File

@ -21,7 +21,7 @@ import (
"github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/services/shhext"
"github.com/status-im/status-go/t/helpers"
"github.com/status-im/status-protocol-go/transport/whisper/gethbridge"
gethbridge "github.com/status-im/status-protocol-go/bridge/geth"
statusproto "github.com/status-im/status-protocol-go/types"
"golang.org/x/crypto/sha3"
"golang.org/x/crypto/ssh/terminal"

4
go.mod
View File

@ -9,7 +9,7 @@ replace github.com/NaySoftware/go-fcm => github.com/status-im/go-fcm v1.0.0-stat
require (
github.com/NaySoftware/go-fcm v0.0.0-00010101000000-000000000000
github.com/beevik/ntp v0.2.0
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3
github.com/btcsuite/btcd v0.0.0-20191011042131-c3151ef50de9
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
github.com/ethereum/go-ethereum v1.9.5
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
@ -31,7 +31,7 @@ require (
github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48 // indirect
github.com/status-im/migrate/v4 v4.3.1-status.0.20190822050738-a9d340ec8fb7
github.com/status-im/rendezvous v1.3.0
github.com/status-im/status-protocol-go v0.2.3-0.20191010161351-fd48aa752717
github.com/status-im/status-protocol-go v0.3.1
github.com/status-im/whisper v1.5.1
github.com/stretchr/testify v1.4.0
github.com/syndtr/goleveldb v1.0.0

6
go.sum
View File

@ -49,6 +49,8 @@ github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dm
github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3 h1:A/EVblehb75cUgXA5njHPn0kLAsykn6mJGz7rnmW5W0=
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btcd v0.0.0-20191011042131-c3151ef50de9 h1:wYYywOGk2jIXV+yt1zIiKl64c/4WLKMh4KET7K8FXFY=
github.com/btcsuite/btcd v0.0.0-20191011042131-c3151ef50de9/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
@ -558,8 +560,8 @@ github.com/status-im/migrate/v4 v4.3.1-status.0.20190822050738-a9d340ec8fb7 h1:g
github.com/status-im/migrate/v4 v4.3.1-status.0.20190822050738-a9d340ec8fb7/go.mod h1:r8HggRBZ/k7TRwByq/Hp3P/ubFppIna0nvyavVK0pjA=
github.com/status-im/rendezvous v1.3.0 h1:7RK/MXXW+tlm0asKm1u7Qp7Yni6AO29a7j8+E4Lbjg4=
github.com/status-im/rendezvous v1.3.0/go.mod h1:+hzjuP+j/XzLPeF6E50b88pWOTLdTcwjvNYt+Gh1W1s=
github.com/status-im/status-protocol-go v0.2.3-0.20191010161351-fd48aa752717 h1:ever+LncsKCx0eV/I0zix9Sp3m0dL7HVnl+k016LdWk=
github.com/status-im/status-protocol-go v0.2.3-0.20191010161351-fd48aa752717/go.mod h1:z4P5yngpR7aB6N6uYtJnhOkHzDHAHlqxTbIbaSX72Jg=
github.com/status-im/status-protocol-go v0.3.1 h1:UrYdxKeW1GlFDtXWLyR66ebhUxmH1yWy46kal7gaSZ0=
github.com/status-im/status-protocol-go v0.3.1/go.mod h1:GyEipgAnT0gBMF57gN1yPAicFMM66VZEe2E8M5ktErI=
github.com/status-im/whisper v1.5.1 h1:87/XIg0Wjua7lXBGiEXgAfTOqlt2Q1dMDuxugTyZbbA=
github.com/status-im/whisper v1.5.1/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s=
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE=

View File

@ -32,7 +32,7 @@ import (
"github.com/status-im/status-go/services/status"
"github.com/status-im/status-go/static"
"github.com/status-im/status-go/timesource"
"github.com/status-im/status-protocol-go/transport/whisper/gethbridge"
gethbridge "github.com/status-im/status-protocol-go/bridge/geth"
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
whisper "github.com/status-im/whisper/whisperv6"
"github.com/syndtr/goleveldb/leveldb"

View File

@ -21,9 +21,9 @@ import (
whisper "github.com/status-im/whisper/whisperv6"
statusproto "github.com/status-im/status-protocol-go"
gethbridge "github.com/status-im/status-protocol-go/bridge/geth"
"github.com/status-im/status-protocol-go/encryption/multidevice"
statustransp "github.com/status-im/status-protocol-go/transport/whisper"
"github.com/status-im/status-protocol-go/transport/whisper/gethbridge"
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
statusproto_types "github.com/status-im/status-protocol-go/types"
)

View File

@ -23,7 +23,7 @@ import (
"github.com/status-im/status-go/sqlite"
"github.com/status-im/status-go/t/helpers"
"github.com/status-im/status-go/t/utils"
"github.com/status-im/status-protocol-go/transport/whisper/gethbridge"
gethbridge "github.com/status-im/status-protocol-go/bridge/geth"
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
statusproto "github.com/status-im/status-protocol-go/types"
whisper "github.com/status-im/whisper/whisperv6"

View File

@ -10,7 +10,7 @@ import (
"github.com/ethereum/go-ethereum/node"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/services/shhext"
"github.com/status-im/status-protocol-go/transport/whisper/gethbridge"
gethbridge "github.com/status-im/status-protocol-go/bridge/geth"
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
whisper "github.com/status-im/whisper/whisperv6"
"github.com/stretchr/testify/require"

View File

@ -36,10 +36,17 @@ var (
// interface from crypto/elliptic.
type KoblitzCurve struct {
*elliptic.CurveParams
q *big.Int
// q is the value (P+1)/4 used to compute the square root of field
// elements.
q *big.Int
H int // cofactor of the curve.
halfOrder *big.Int // half the order N
// fieldB is the constant B of the curve as a fieldVal.
fieldB *fieldVal
// byteSize is simply the bit size / 8 and is provided for convenience
// since it is calculated repeatedly.
byteSize int
@ -879,12 +886,22 @@ func (curve *KoblitzCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
return curve.fieldJacobianToBigAffine(qx, qy, qz)
}
// QPlus1Div4 returns the Q+1/4 constant for the curve for use in calculating
// square roots via exponention.
// QPlus1Div4 returns the (P+1)/4 constant for the curve for use in calculating
// square roots via exponentiation.
//
// DEPRECATED: The actual value returned is (P+1)/4, where as the original
// method name implies that this value is (((P+1)/4)+1)/4. This method is kept
// to maintain backwards compatibility of the API. Use Q() instead.
func (curve *KoblitzCurve) QPlus1Div4() *big.Int {
return curve.q
}
// Q returns the (P+1)/4 constant for the curve for use in calculating square
// roots via exponentiation.
func (curve *KoblitzCurve) Q() *big.Int {
return curve.q
}
var initonce sync.Once
var secp256k1 KoblitzCurve
@ -917,6 +934,7 @@ func initS256() {
big.NewInt(1)), big.NewInt(4))
secp256k1.H = 1
secp256k1.halfOrder = new(big.Int).Rsh(secp256k1.N, 1)
secp256k1.fieldB = new(fieldVal).SetByteSlice(secp256k1.B.Bytes())
// Provided for convenience since this gets computed repeatedly.
secp256k1.byteSize = secp256k1.BitSize / 8

View File

@ -102,6 +102,20 @@ const (
fieldPrimeWordOne = 0x3ffffbf
)
var (
// fieldQBytes is the value Q = (P+1)/4 for the secp256k1 prime P. This
// value is used to efficiently compute the square root of values in the
// field via exponentiation. The value of Q in hex is:
//
// Q = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff0c
fieldQBytes = []byte{
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x0c,
}
)
// fieldVal implements optimized fixed-precision arithmetic over the
// secp256k1 finite field. This means all arithmetic is performed modulo
// 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f. It
@ -1221,3 +1235,118 @@ func (f *fieldVal) Inverse() *fieldVal {
f.Square().Square().Square().Square().Square() // f = a^(2^256 - 4294968320)
return f.Mul(&a45) // f = a^(2^256 - 4294968275) = a^(p-2)
}
// SqrtVal computes the square root of x modulo the curve's prime, and stores
// the result in f. The square root is computed via exponentiation of x by the
// value Q = (P+1)/4 using the curve's precomputed big-endian representation of
// the Q. This method uses a modified version of square-and-multiply
// exponentiation over secp256k1 fieldVals to operate on bytes instead of bits,
// which offers better performance over both big.Int exponentiation and bit-wise
// square-and-multiply.
//
// NOTE: This method only works when P is intended to be the secp256k1 prime and
// is not constant time. The returned value is of magnitude 1, but is
// denormalized.
func (f *fieldVal) SqrtVal(x *fieldVal) *fieldVal {
// The following computation iteratively computes x^((P+1)/4) = x^Q
// using the recursive, piece-wise definition:
//
// x^n = (x^2)^(n/2) mod P if n is even
// x^n = x(x^2)^(n-1/2) mod P if n is odd
//
// Given n in its big-endian representation b_k, ..., b_0, x^n can be
// computed by defining the sequence r_k+1, ..., r_0, where:
//
// r_k+1 = 1
// r_i = (r_i+1)^2 * x^b_i for i = k, ..., 0
//
// The final value r_0 = x^n.
//
// See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more
// details.
//
// This can be further optimized, by observing that the value of Q in
// secp256k1 has the value:
//
// Q = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff0c
//
// We can unroll the typical bit-wise interpretation of the
// exponentiation algorithm above to instead operate on bytes.
// This reduces the number of comparisons by an order of magnitude,
// reducing the overhead of failed branch predictions and additional
// comparisons in this method.
//
// Since there there are only 4 unique bytes of Q, this keeps the jump
// table small without the need to handle all possible 8-bit values.
// Further, we observe that 29 of the 32 bytes are 0xff; making the
// first case handle 0xff therefore optimizes the hot path.
f.SetInt(1)
for _, b := range fieldQBytes {
switch b {
// Most common case, where all 8 bits are set.
case 0xff:
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
// First byte of Q (0x3f), where all but the top two bits are
// set. Note that this case only applies six operations, since
// the highest bit of Q resides in bit six of the first byte. We
// ignore the first two bits, since squaring for these bits will
// result in an invalid result. We forgo squaring f before the
// first multiply, since 1^2 = 1.
case 0x3f:
f.Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
// Byte 28 of Q (0xbf), where only bit 7 is unset.
case 0xbf:
f.Square().Mul(x)
f.Square()
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
f.Square().Mul(x)
// Byte 31 of Q (0x0c), where only bits 3 and 4 are set.
default:
f.Square()
f.Square()
f.Square()
f.Square()
f.Square().Mul(x)
f.Square().Mul(x)
f.Square()
f.Square()
}
}
return f
}
// Sqrt computes the square root of f modulo the curve's prime, and stores the
// result in f. The square root is computed via exponentiation of x by the value
// Q = (P+1)/4 using the curve's precomputed big-endian representation of the Q.
// This method uses a modified version of square-and-multiply exponentiation
// over secp256k1 fieldVals to operate on bytes instead of bits, which offers
// better performance over both big.Int exponentiation and bit-wise
// square-and-multiply.
//
// NOTE: This method only works when P is intended to be the secp256k1 prime and
// is not constant time. The returned value is of magnitude 1, but is
// denormalized.
func (f *fieldVal) Sqrt() *fieldVal {
return f.SqrtVal(f)
}

View File

@ -22,41 +22,40 @@ func isOdd(a *big.Int) bool {
return a.Bit(0) == 1
}
// decompressPoint decompresses a point on the given curve given the X point and
// decompressPoint decompresses a point on the secp256k1 curve given the X point and
// the solution to use.
func decompressPoint(curve *KoblitzCurve, x *big.Int, ybit bool) (*big.Int, error) {
// TODO: This will probably only work for secp256k1 due to
// optimizations.
func decompressPoint(curve *KoblitzCurve, bigX *big.Int, ybit bool) (*big.Int, error) {
var x fieldVal
x.SetByteSlice(bigX.Bytes())
// Y = +-sqrt(x^3 + B)
x3 := new(big.Int).Mul(x, x)
x3.Mul(x3, x)
x3.Add(x3, curve.Params().B)
x3.Mod(x3, curve.Params().P)
// Compute x^3 + B mod p.
var x3 fieldVal
x3.SquareVal(&x).Mul(&x)
x3.Add(curve.fieldB).Normalize()
// Now calculate sqrt mod p of x^3 + B
// This code used to do a full sqrt based on tonelli/shanks,
// but this was replaced by the algorithms referenced in
// https://bitcointalk.org/index.php?topic=162805.msg1712294#msg1712294
y := new(big.Int).Exp(x3, curve.QPlus1Div4(), curve.Params().P)
if ybit != isOdd(y) {
y.Sub(curve.Params().P, y)
var y fieldVal
y.SqrtVal(&x3).Normalize()
if ybit != y.IsOdd() {
y.Negate(1).Normalize()
}
// Check that y is a square root of x^3 + B.
y2 := new(big.Int).Mul(y, y)
y2.Mod(y2, curve.Params().P)
if y2.Cmp(x3) != 0 {
var y2 fieldVal
y2.SquareVal(&y).Normalize()
if !y2.Equals(&x3) {
return nil, fmt.Errorf("invalid square root")
}
// Verify that y-coord has expected parity.
if ybit != isOdd(y) {
if ybit != y.IsOdd() {
return nil, fmt.Errorf("ybit doesn't match oddness")
}
return y, nil
return new(big.Int).SetBytes(y.Bytes()[:]), nil
}
const (
@ -102,6 +101,17 @@ func ParsePubKey(pubKeyStr []byte, curve *KoblitzCurve) (key *PublicKey, err err
if format == pubkeyHybrid && ybit != isOdd(pubkey.Y) {
return nil, fmt.Errorf("ybit doesn't match oddness")
}
if pubkey.X.Cmp(pubkey.Curve.Params().P) >= 0 {
return nil, fmt.Errorf("pubkey X parameter is >= to P")
}
if pubkey.Y.Cmp(pubkey.Curve.Params().P) >= 0 {
return nil, fmt.Errorf("pubkey Y parameter is >= to P")
}
if !pubkey.Curve.IsOnCurve(pubkey.X, pubkey.Y) {
return nil, fmt.Errorf("pubkey isn't on secp256k1 curve")
}
case PubKeyBytesLenCompressed:
// format is 0x2 | solution, <X coordinate>
// solution determines which solution of the curve we use.
@ -115,20 +125,12 @@ func ParsePubKey(pubKeyStr []byte, curve *KoblitzCurve) (key *PublicKey, err err
if err != nil {
return nil, err
}
default: // wrong!
return nil, fmt.Errorf("invalid pub key length %d",
len(pubKeyStr))
}
if pubkey.X.Cmp(pubkey.Curve.Params().P) >= 0 {
return nil, fmt.Errorf("pubkey X parameter is >= to P")
}
if pubkey.Y.Cmp(pubkey.Curve.Params().P) >= 0 {
return nil, fmt.Errorf("pubkey Y parameter is >= to P")
}
if !pubkey.Curve.IsOnCurve(pubkey.X, pubkey.Y) {
return nil, fmt.Errorf("pubkey isn't on secp256k1 curve")
}
return &pubkey, nil
}

View File

@ -276,7 +276,7 @@ func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
}
// recoverKeyFromSignature recovers a public key from the signature "sig" on the
// given message hash "msg". Based on the algorithm found in section 5.1.5 of
// given message hash "msg". Based on the algorithm found in section 4.1.6 of
// SEC 1 Ver 2.0, page 47-48 (53 and 54 in the pdf). This performs the details
// in the inner loop in Step 1. The counter provided is actually the j parameter
// of the loop * 2 - on the first iteration of j we do the R case, else the -R

View File

@ -1,6 +1,6 @@
module github.com/status-im/status-protocol-go
go 1.12
go 1.13
require (
github.com/aristanetworks/goarista v0.0.0-20190704150520-f44d68189fd7 // indirect

View File

@ -141,7 +141,6 @@ func (m *EnvelopesMonitor) handleEnvelopeEvents() {
for {
select {
case <-m.quit:
close(events)
return
case event := <-events:
m.handleEvent(event)

6
vendor/modules.txt vendored
View File

@ -9,7 +9,7 @@ github.com/allegro/bigcache/queue
github.com/aristanetworks/goarista/monotime
# github.com/beevik/ntp v0.2.0
github.com/beevik/ntp
# github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3
# github.com/btcsuite/btcd v0.0.0-20191011042131-c3151ef50de9
github.com/btcsuite/btcd/btcec
github.com/btcsuite/btcd/chaincfg
github.com/btcsuite/btcd/chaincfg/chainhash
@ -348,9 +348,10 @@ github.com/status-im/migrate/v4/source/go_bindata
github.com/status-im/rendezvous
github.com/status-im/rendezvous/protocol
github.com/status-im/rendezvous/server
# github.com/status-im/status-protocol-go v0.2.3-0.20191010161351-fd48aa752717
# github.com/status-im/status-protocol-go v0.3.1
github.com/status-im/status-protocol-go
github.com/status-im/status-protocol-go/applicationmetadata
github.com/status-im/status-protocol-go/bridge/geth
github.com/status-im/status-protocol-go/crypto
github.com/status-im/status-protocol-go/datasync
github.com/status-im/status-protocol-go/datasync/peer
@ -364,7 +365,6 @@ github.com/status-im/status-protocol-go/identity/identicon
github.com/status-im/status-protocol-go/migrations
github.com/status-im/status-protocol-go/sqlite
github.com/status-im/status-protocol-go/transport/whisper
github.com/status-im/status-protocol-go/transport/whisper/gethbridge
github.com/status-im/status-protocol-go/transport/whisper/migrations
github.com/status-im/status-protocol-go/transport/whisper/types
github.com/status-im/status-protocol-go/types