Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miscellaneous Fixes Before Release #63

Merged
merged 5 commits into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ generated from the [rosetta-specifications](https://github.com/coinbase/rosetta-
Before diving into the SDK, we recommend taking a look at the Rosetta API Docs:

* [Overview](https://www.rosetta-api.org/docs/welcome.html)
* [Node API](https://www.rosetta-api.org/docs/node_api_introduction.html)
* [Wallet API (coming soon!)](https://www.rosetta-api.org/docs/wallet_api_introduction.html)
* [Data API](https://www.rosetta-api.org/docs/data_api_introduction.html)
* [Construction API](https://www.rosetta-api.org/docs/construction_api_introduction.html)

## Packages
* [Types](types): Auto-generated Rosetta types
* [Client](client): Low-level communication with any Rosetta server
* [Server](server): Simplified Rosetta Node API server development
* [Server](server): Simplified Rosetta API server development
* [Asserter](asserter): Validation of Rosetta types
* [Fetcher](fetcher): Simplified and validated communication with
any Rosetta server
Expand Down
62 changes: 24 additions & 38 deletions keys/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ const PrivKeyBytesLen = 32

// GenerateKeypair returns a Keypair of a specified CurveType
func GenerateKeypair(curve types.CurveType) (*KeyPair, error) {
var keyPair *KeyPair

switch curve {
case types.Secp256k1:
rawPrivKey, err := btcec.NewPrivateKey(btcec.S256())
Expand All @@ -43,16 +41,13 @@ func GenerateKeypair(curve types.CurveType) (*KeyPair, error) {
Bytes: rawPubKey.SerializeCompressed(),
CurveType: curve,
}
privKey := &PrivateKey{
Bytes: rawPrivKey.Serialize(),
CurveType: curve,
}

keyPair = &KeyPair{
keyPair := &KeyPair{
PublicKey: pubKey,
PrivateKey: privKey,
PrivateKey: rawPrivKey.Serialize(),
}

return keyPair, nil
case types.Edwards25519:
rawPubKey, rawPrivKey, err := ed25519.GenerateKey(nil)
if err != nil {
Expand All @@ -64,54 +59,45 @@ func GenerateKeypair(curve types.CurveType) (*KeyPair, error) {
CurveType: curve,
}

privKey := &PrivateKey{
Bytes: rawPrivKey.Seed(),
CurveType: curve,
}

keyPair = &KeyPair{
keyPair := &KeyPair{
PublicKey: pubKey,
PrivateKey: privKey,
PrivateKey: rawPrivKey.Seed(),
}

return keyPair, nil
default:
return nil, fmt.Errorf("%s is not supported", curve)
}

return keyPair, nil
}

// IsValid checks the validity of a keypair
func (k *KeyPair) IsValid() error {
sk := k.PrivateKey.Bytes
pkCurve := k.PublicKey.CurveType
skCurve := k.PrivateKey.CurveType

// Checks if valid Public Key
// Checks if valid PublicKey and CurveType
err := asserter.PublicKey(k.PublicKey)
if err != nil {
return err
}

// Checks if valid CurveType
err = asserter.CurveType(pkCurve)
if err != nil {
return err
}

// Checks if pk and sk have the same CurveType
if pkCurve != skCurve {
// Will change if we support more CurveTypes with different privkey sizes
if len(k.PrivateKey) != PrivKeyBytesLen {
return fmt.Errorf(
"private key curve %s and public key curve %s do not match",
skCurve,
pkCurve,
"invalid privkey length %v. Expected 32 bytes",
len(k.PrivateKey),
)
}

// Will change if we support more CurveTypes with different privkey sizes
if len(sk) != PrivKeyBytesLen {
return fmt.Errorf("invalid privkey length %v. Expected 32 bytes", len(sk))
}

return nil
}

// Signer returns the constructs a Signer
// for the KeyPair.
func (k *KeyPair) Signer() (Signer, error) {
switch k.PublicKey.CurveType {
case types.Secp256k1:
return &SignerSecp256k1{k}, nil
case types.Edwards25519:
return &SignerEdwards25519{k}, nil
default:
return nil, fmt.Errorf("curve %s not supported", k.PublicKey.CurveType)
}
}
35 changes: 20 additions & 15 deletions keys/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,27 @@ import (
)

func TestJSONEncoding(t *testing.T) {
secpKeypair, _ := GenerateKeypair(types.Secp256k1)
ed25519Keypair, _ := GenerateKeypair(types.Secp256k1)
secp256k1Keypair, err := GenerateKeypair(types.Secp256k1)
assert.NoError(t, err)

edwards25519Keypair, err := GenerateKeypair(types.Edwards25519)
assert.NoError(t, err)

var keyPairs = []*KeyPair{secpKeypair, ed25519Keypair}
var keyPairs = []*KeyPair{secp256k1Keypair, edwards25519Keypair}
for _, keypair := range keyPairs {
privKeyJSON, err := json.Marshal(keypair.PrivateKey)
kpb, err := json.Marshal(keypair)
assert.NoError(t, err)

// Simple Hex Check
simpleType := struct {
HexBytes string `json:"hex_bytes"`
HexBytes string `json:"private_key"`
}{}
err = json.Unmarshal(privKeyJSON, &simpleType)
err = json.Unmarshal(kpb, &simpleType)
assert.NoError(t, err)

b, err := hex.DecodeString(simpleType.HexBytes)
assert.NoError(t, err)
assert.Equal(t, keypair.PrivateKey.Bytes, b)
assert.Equal(t, keypair.PrivateKey, b)
}
}

Expand All @@ -52,7 +55,7 @@ func TestGenerateKeypairSecp256k1(t *testing.T) {

assert.NoError(t, err)
assert.Equal(t, keypair.PublicKey.CurveType, curve)
assert.Equal(t, keypair.PrivateKey.CurveType, curve)
assert.Len(t, keypair.PrivateKey, PrivKeyBytesLen)
}

func TestGenerateKeypairEdwards25519(t *testing.T) {
Expand All @@ -61,21 +64,23 @@ func TestGenerateKeypairEdwards25519(t *testing.T) {

assert.NoError(t, err)
assert.Equal(t, keypair.PublicKey.CurveType, curve)
assert.Equal(t, keypair.PrivateKey.CurveType, curve)
assert.Len(t, keypair.PrivateKey, PrivKeyBytesLen)
}

func mockKeyPair(privKey []byte, curveType types.CurveType) *KeyPair {
keypair, _ := GenerateKeypair(curveType)
keypair.PrivateKey.Bytes = privKey
keypair.PrivateKey = privKey
return keypair
}

func TestKeypairValidity(t *testing.T) {
// Non matching curves
keyPair, _ := GenerateKeypair(types.Edwards25519)
keyPair.PublicKey.CurveType = types.Secp256k1
err := keyPair.IsValid()
assert.Contains(t, err.Error(), "do not match")
// invalid CurveType
keyPair, err := GenerateKeypair(types.Edwards25519)
assert.NoError(t, err)

keyPair.PublicKey.CurveType = "blah"
err = keyPair.IsValid()
assert.Contains(t, err.Error(), "blah is not a supported CurveType")

type privKeyTest struct {
keypair *KeyPair
Expand Down
16 changes: 8 additions & 8 deletions keys/signer_ed25519.go → keys/signer_edwards25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@ import (
"github.com/coinbase/rosetta-sdk-go/types"
)

// SignerEd25519 is initialized from a keypair
type SignerEd25519 struct {
// SignerEdwards25519 is initialized from a keypair
type SignerEdwards25519 struct {
KeyPair *KeyPair
}

var _ Signer = (*SignerEd25519)(nil)
var _ Signer = (*SignerEdwards25519)(nil)

// PublicKey returns the PublicKey of the signer
func (s *SignerEd25519) PublicKey() *types.PublicKey {
func (s *SignerEdwards25519) PublicKey() *types.PublicKey {
return s.KeyPair.PublicKey
}

// Signs arbitrary payloads using a KeyPair
func (s *SignerEd25519) Sign(
// Sign arbitrary payloads using a KeyPair
func (s *SignerEdwards25519) Sign(
payload *types.SigningPayload,
sigType types.SignatureType,
) (*types.Signature, error) {
Expand All @@ -53,7 +53,7 @@ func (s *SignerEd25519) Sign(
return nil, fmt.Errorf("sign: signature type is not %v", types.Ed25519)
}

privKeyBytes := s.KeyPair.PrivateKey.Bytes
privKeyBytes := s.KeyPair.PrivateKey
privKey := ed25519.NewKeyFromSeed(privKeyBytes)
sig := ed25519.Sign(privKey, payload.Bytes)

Expand All @@ -67,7 +67,7 @@ func (s *SignerEd25519) Sign(

// Verify verifies a Signature, by checking the validity of a Signature,
// the SigningPayload, and the PublicKey of the Signature.
func (s *SignerEd25519) Verify(signature *types.Signature) error {
func (s *SignerEdwards25519) Verify(signature *types.Signature) error {
if signature.SignatureType != types.Ed25519 {
return fmt.Errorf("verify: payload signature type is not %v", types.Ed25519)
}
Expand Down
25 changes: 13 additions & 12 deletions keys/signer_ed25519_test.go → keys/signer_edwards25519_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ import (
"github.com/stretchr/testify/assert"
)

var signerEd25519 Signer
var signerEdwards25519 Signer

func init() {
keypair, _ := GenerateKeypair(types.Edwards25519)
signerEd25519 = &SignerEd25519{keypair}
signerEdwards25519, _ = keypair.Signer()
}

func mockPayload(msg []byte, signatureType types.SignatureType) *types.SigningPayload {
Expand All @@ -39,7 +39,7 @@ func mockPayload(msg []byte, signatureType types.SignatureType) *types.SigningPa
return payload
}

func TestSignEd25519(t *testing.T) {
func TestSignEdwards25519(t *testing.T) {
type payloadTest struct {
payload *types.SigningPayload
err bool
Expand All @@ -54,7 +54,7 @@ func TestSignEd25519(t *testing.T) {
}

for _, test := range payloadTests {
signature, err := signerEd25519.Sign(test.payload, types.Ed25519)
signature, err := signerEdwards25519.Sign(test.payload, types.Ed25519)

if !test.err {
assert.NoError(t, err)
Expand Down Expand Up @@ -85,7 +85,7 @@ func mockSignature(
return mockSig
}

func TestVerifyEd25519(t *testing.T) {
func TestVerifyEdwards25519(t *testing.T) {
type signatureTest struct {
signature *types.Signature
errMsg string
Expand All @@ -96,36 +96,37 @@ func TestVerifyEd25519(t *testing.T) {
Bytes: make([]byte, 32),
SignatureType: types.Ed25519,
}
testSignature, _ := signerEd25519.Sign(payload, types.Ed25519)
testSignature, err := signerEdwards25519.Sign(payload, types.Ed25519)
assert.NoError(t, err)

var signatureTests = []signatureTest{
{mockSignature(
types.Ecdsa,
signerEd25519.PublicKey(),
signerEdwards25519.PublicKey(),
make([]byte, 32),
make([]byte, 32)), "payload signature type is not ed25519"},
{mockSignature(
types.EcdsaRecovery,
signerEd25519.PublicKey(),
signerEdwards25519.PublicKey(),
make([]byte, 32),
make([]byte, 32)), "payload signature type is not ed25519"},
{mockSignature(
types.Ed25519,
signerEd25519.PublicKey(),
signerEdwards25519.PublicKey(),
make([]byte, 40),
testSignature.Bytes), "verify returned false"},
}

for _, test := range signatureTests {
err := signerEd25519.Verify(test.signature)
err := signerEdwards25519.Verify(test.signature)
assert.Contains(t, err.Error(), test.errMsg)
}

goodSignature := mockSignature(
types.Ed25519,
signerEd25519.PublicKey(),
signerEdwards25519.PublicKey(),
make([]byte, 32),
testSignature.Bytes,
)
assert.Equal(t, nil, signerEd25519.Verify(goodSignature))
assert.Equal(t, nil, signerEdwards25519.Verify(goodSignature))
}
4 changes: 2 additions & 2 deletions keys/signer_secp256k1.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (s *SignerSecp256k1) PublicKey() *types.PublicKey {
return s.KeyPair.PublicKey
}

// Signs arbitrary payloads using a KeyPair
// Sign arbitrary payloads using a KeyPair
func (s *SignerSecp256k1) Sign(
payload *types.SigningPayload,
sigType types.SignatureType,
Expand All @@ -48,7 +48,7 @@ func (s *SignerSecp256k1) Sign(
if err != nil {
return nil, err
}
privKeyBytes := s.KeyPair.PrivateKey.Bytes
privKeyBytes := s.KeyPair.PrivateKey

if !(payload.SignatureType == sigType || payload.SignatureType == "") {
return nil, fmt.Errorf("sign: invalid payload signaturetype %v", payload.SignatureType)
Expand Down
2 changes: 1 addition & 1 deletion keys/signer_secp256k1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ var signerSecp256k1 Signer

func init() {
keypair, _ := GenerateKeypair(types.Secp256k1)
signerSecp256k1 = &SignerSecp256k1{keypair}
signerSecp256k1, _ = keypair.Signer()
}

func TestSignSecp256k1(t *testing.T) {
Expand Down
Loading