Skip to content

Commit

Permalink
Add ParseSigningPayload for pallas
Browse files Browse the repository at this point in the history
  • Loading branch information
irisZhangCB committed Feb 17, 2022
1 parent a652a3a commit ce691c4
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 37 deletions.
110 changes: 103 additions & 7 deletions keys/signer_pallas.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
package keys

import (
"encoding/json"
"errors"
"fmt"
"strconv"

"github.com/coinbase/kryptology/pkg/signatures/schnorr/mina"

Expand Down Expand Up @@ -67,9 +69,10 @@ func (s *SignerPallas) Sign(
privKey := &mina.SecretKey{}
_ = privKey.UnmarshalBinary(privKeyBytes)

// Convert payload to transaction
tx := &mina.Transaction{}
_ = tx.UnmarshalBinary(payload.Bytes)
tx, err := ParseSigningPayload(payload)
if err != nil {
return nil, err
}

sig, err := privKey.SignTransaction(tx)
if err != nil {
Expand Down Expand Up @@ -110,17 +113,110 @@ func (s *SignerPallas) Verify(signature *types.Signature) error {
return fmt.Errorf("%w: %s", ErrVerifyFailed, err)
}

txnBytes := signature.SigningPayload.Bytes
txn := &mina.Transaction{}
err = txn.UnmarshalBinary(txnBytes)
transaction, err := ParseSigningPayload(signature.SigningPayload)
if err != nil {
return fmt.Errorf("%w: %s", ErrVerifyFailed, err)
}

verifyErr := pubKey.VerifyTransaction(sig, txn)
verifyErr := pubKey.VerifyTransaction(sig, transaction)
if verifyErr != nil {
return fmt.Errorf("%w: %s", ErrVerifyFailed, verifyErr)
}

return nil
}

type PayloadFields struct {
To string `json:"to"`
From string `json:"from"`
Fee string `json:"fee"`
Amount *string `json:"amount,omitempty"`
Nonce string `json:"nonce"`
ValidUntil *string `json:"valid_until,omitempty"`
Memo *string `json:"memo,omitempty"`
}

type SigningPayload struct {
Payment *PayloadFields `json:"payment"`
}

func ParseSigningPayload(rawPayload *types.SigningPayload) (*mina.Transaction, error){
var signingPayload SigningPayload
var payloadFields PayloadFields

err := json.Unmarshal(rawPayload.Bytes, &signingPayload)
if err != nil{
return nil,err
}

payloadFields = *signingPayload.Payment

transaction, err := constructTransaction(&payloadFields)
if err != nil{
return nil,err
}
return transaction, nil
}

func constructTransaction(p *PayloadFields) (*mina.Transaction, error){
var fromPublicKey mina.PublicKey
if err := fromPublicKey.ParseAddress(p.From); err != nil {
return nil, err
}

var toPublicKey mina.PublicKey
if err := toPublicKey.ParseAddress(p.To); err != nil {
return nil, err
}

fee, err := strconv.ParseUint(p.Fee, 10, 64)
if err != nil {
return nil, err
}

// amount is a field that only exists in a Payment transaction
amount := uint64(0)
if p.Amount != nil {
amount, err = strconv.ParseUint(*p.Amount, 10, 64)
if err != nil {
return nil, err
}
}

nonce, err := strconv.ParseUint(p.Nonce, 10, 32)
if err != nil {
return nil, err
}

validUntil := uint64(0)
if p.ValidUntil != nil {
validUntil, err = strconv.ParseUint(*p.ValidUntil, 10, 32)
if err != nil {
return nil, err
}
}

memo := ""
if p.Memo != nil {
memo = *p.Memo
}

txn := &mina.Transaction{
Fee: fee,
FeeToken: 1,
FeePayerPk: &fromPublicKey,
Nonce: uint32(nonce),
ValidUntil: uint32(validUntil),
Memo: memo,
// Tag is a forwards compatible API, at the moment it is set to an array of 3 false's
Tag: [3]bool{false, false, false},
SourcePk: &fromPublicKey,
ReceiverPk: &toPublicKey,
TokenId: 1,
Amount: amount,
Locked: false,
NetworkId: mina.TestNet,
}

return txn, nil
}
36 changes: 6 additions & 30 deletions keys/signer_pallas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package keys
import (
"testing"

"github.com/coinbase/kryptology/pkg/signatures/schnorr/mina"
"github.com/stretchr/testify/assert"

"github.com/coinbase/rosetta-sdk-go/types"
Expand All @@ -28,31 +27,11 @@ var keypair *KeyPair
var txnBytes []byte

func init() {
keypair, _ = GenerateKeypair(types.Pallas)
keypair, _ = ImportPrivateKey("A80F3DE13EE5AE01119E7D98A8F2317070BFB6D2A1EA712EE1B55EE7B938AD1D", "pallas")
signerPallas, _ = keypair.Signer()

privKey := &mina.SecretKey{}
_ = privKey.UnmarshalBinary(keypair.PrivateKey)
pubKey := privKey.GetPublicKey()

_, sourceSecretKey, _ := mina.NewKeys()

txn := &mina.Transaction{
Fee: 3,
FeeToken: 1,
Nonce: 200,
ValidUntil: 1000,
Memo: "this is a memo",
FeePayerPk: pubKey,
SourcePk: pubKey,
ReceiverPk: sourceSecretKey.GetPublicKey(),
TokenId: 1,
Amount: 42,
Locked: false,
Tag: [3]bool{false, false, false},
NetworkId: mina.TestNet,
}
txnBytes, _ = txn.MarshalBinary()
unsignedTxStr := "{\"randomOracleInput\":\"000000033769356015133A338518173BE9C263D6E463538ACDF11D523DDEB8C82467093E3769356015133A338518173BE9C263D6E463538ACDF11D523DDEB8C82467093E167031AAE689272378D05042083C66C593EF025060E4C8CA1CBD022E47C72D220000025701154880000000008000000000000000400000007FFFFFFFC0000000000000000000000000000000000000000000000000000000000000000000060000000000000001BC6CD9C400000000\",\"signerInput\":{\"prefix\":[\"3769356015133A338518173BE9C263D6E463538ACDF11D523DDEB8C82467093E\",\"3769356015133A338518173BE9C263D6E463538ACDF11D523DDEB8C82467093E\",\"167031AAE689272378D05042083C66C593EF025060E4C8CA1CBD022E47C72D22\"],\"suffix\":[\"0000000000000007FFFFFFFC0000000400000000000000020000000002255100\",\"0000000003000000000000000000000000000000000000000000000000000000\",\"000000000000000000000000000000000000000000000000047366C7B0000000\"]},\"payment\":{\"to\":\"B62qoLLD2LK2pL2dq2oDHh6ohdaYusgTEYRUZ43Y41Kk9Rgen4v643x\",\"from\":\"B62qooQQ952uaoUSTQP3sZCviGmsWeusBwhg3qVF1Ww662sgzimA25Q\",\"fee\":\"18000000\",\"token\":\"1\",\"nonce\":\"1\",\"memo\":null,\"amount\":\"2389498102\",\"valid_until\":\"4294967295\"},\"stakeDelegation\":null,\"createToken\":null,\"createTokenAccount\":null,\"mintTokens\":null}"
txnBytes = []byte(unsignedTxStr)
}

func TestSignPallas(t *testing.T) {
Expand Down Expand Up @@ -91,11 +70,7 @@ func TestVerifyPallas(t *testing.T) {
errMsg error
}

payload := &types.SigningPayload{
AccountIdentifier: &types.AccountIdentifier{Address: "test"},
Bytes: txnBytes,
SignatureType: types.SchnorrPoseidon,
}
payload := mockPayload(txnBytes, types.SchnorrPoseidon)
testSignature, err := signerPallas.Sign(payload, types.SchnorrPoseidon)
assert.NoError(t, err)

Expand Down Expand Up @@ -128,9 +103,10 @@ func TestVerifyPallas(t *testing.T) {
// happy path
goodSignature := mockSignature(
types.SchnorrPoseidon,
signerPallas.PublicKey(),
keypair.PublicKey,
txnBytes,
testSignature.Bytes,
)

assert.Equal(t, nil, signerPallas.Verify(goodSignature))
}

0 comments on commit ce691c4

Please sign in to comment.