Skip to content

Commit

Permalink
Return to having sessionId = pubKey/sessAdddr
Browse files Browse the repository at this point in the history
  • Loading branch information
marino39 committed Feb 6, 2024
1 parent d578188 commit cd4ea13
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 64 deletions.
72 changes: 43 additions & 29 deletions intents/intent.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ var (
ErrInvalidSignature = fmt.Errorf("invalid signature")
)

type IntentVerifierGetter func(sessionId string) (string, error)
type KeyType int

const (
KeyTypeSECP256K1 KeyType = iota
KeyTypeSECP256R1
)

type Intent struct {
Version string `json:"version"`
Expand Down Expand Up @@ -78,24 +83,19 @@ func (intent *Intent) Hash() ([]byte, error) {
return crypto.Keccak256(packetBytes), nil
}

func (intent *Intent) Signers(verifierGetter IntentVerifierGetter) []string {
func (intent *Intent) Signers() []string {
var signers []string

for _, signature := range intent.signatures {
sessionVerifier, err := verifierGetter(signature.SessionId)
if err != nil {
continue
}

if intent.isValidSignature(sessionVerifier, signature.Signature) {
signers = append(signers, sessionVerifier)
if intent.isValidSignature(signature.SessionId, signature.Signature) {
signers = append(signers, signature.SessionId)
}
}

return signers
}

func (intent *Intent) IsValid(verifierGetter IntentVerifierGetter) (bool, error) {
func (intent *Intent) IsValid() (bool, error) {
// Check if the packet is valid
var packet packets.BasePacket
err := json.Unmarshal(intent.Packet, &packet)
Expand All @@ -118,12 +118,7 @@ func (intent *Intent) IsValid(verifierGetter IntentVerifierGetter) (bool, error)

// Check if all signatures are valid
for _, signature := range intent.signatures {
sessionVerifier, err := verifierGetter(signature.SessionId)
if err != nil {
return false, fmt.Errorf("intent: %w", err)
}

if !intent.isValidSignature(sessionVerifier, signature.Signature) {
if !intent.isValidSignature(signature.SessionId, signature.Signature) {
return false, fmt.Errorf("intent: %w", ErrInvalidSignature)
}
}
Expand All @@ -135,20 +130,40 @@ func (intent *Intent) IsValid(verifierGetter IntentVerifierGetter) (bool, error)
return true, nil
}

func (intent *Intent) isValidSECP256R1Session(session string, signature string) bool {
return strings.HasPrefix(session, "r1:") && strings.HasPrefix(signature, "r1:")
func (intent *Intent) isValidP256R1Session(sessionId string, signature string) bool {
// handle old session ids
if len(sessionId) <= 42 {
return false
}

// handle key typed session ids
sessionIdBytes := common.FromHex(sessionId)
switch KeyType(sessionIdBytes[0]) {
case KeyTypeSECP256K1:
return false
case KeyTypeSECP256R1:
return true
default:
return false
}
}

func (intent *Intent) isValidSignature(session string, signature string) bool {
if intent.isValidSECP256R1Session(session, signature) {
return intent.isValidSignatureSECP256R1(session, signature)
if intent.isValidP256R1Session(session, signature) {
return intent.isValidSignatureP256R1(session, signature)
} else {
return intent.isValidSignatureSPECP256K1(session, signature)
return intent.isValidSignatureP256K1(session, signature)
}
}

// isValidSignatureSPECP256K1 checks if the signature is valid for the given secp256k1 session
func (intent *Intent) isValidSignatureSPECP256K1(session string, signature string) bool {
// isValidSignatureP256K1 checks if the signature is valid for the given secp256k1 session
func (intent *Intent) isValidSignatureP256K1(sessionAddress string, signature string) bool {
// handle typed session address
if len(sessionAddress) > 42 {
sessionAddressBytes := common.FromHex(sessionAddress)
sessionAddress = fmt.Sprintf("0x%s", common.Bytes2Hex(sessionAddressBytes[1:]))
}

// Get hash of the packet
hash, err := intent.Hash()
if err != nil {
Expand All @@ -173,18 +188,17 @@ func (intent *Intent) isValidSignatureSPECP256K1(session string, signature strin
addr := common.BytesToAddress(crypto.Keccak256(pubKey[1:])[12:])

// Check if the recovered address matches the session address
return strings.ToLower(addr.Hex()) == strings.ToLower(session)
return strings.ToLower(addr.Hex()) == strings.ToLower(sessionAddress)
}

// isValidSignatureSPECP256K1 checks if the signature is valid for the given secp256r1 session
func (intent *Intent) isValidSignatureSECP256R1(session string, signature string) bool {
// session
sessionBuff := common.FromHex(session[3:])
// isValidSignatureP256R1 checks if the signature is valid for the given secp256r1 session
func (intent *Intent) isValidSignatureP256R1(publicKey string, signature string) bool {
publicKeyBuff := common.FromHex(publicKey)[1:]

// public key
// TODO: check if can use ecdh instead of unmarshal
// NOTE: no way to convert ecdh pub key into elliptic pub key?
x, y := elliptic.Unmarshal(elliptic.P256(), sessionBuff)
x, y := elliptic.Unmarshal(elliptic.P256(), publicKeyBuff)
if x == nil || y == nil {
return false
}
Expand Down
11 changes: 1 addition & 10 deletions intents/intent_send_transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package intents

import (
"encoding/json"
"fmt"
"math/big"
"testing"

Expand Down Expand Up @@ -102,15 +101,7 @@ func TestRecoverTransactionIntent(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, common.Bytes2Hex(hash), "2feb22d5631075041c5aaafce98da8950d706a9eca8d9ea2b28ea95142d8e890")

getSessionVerifier := func(sessionId string) (string, error) {
if sessionId == "afaf60c0-67ba-4c9b-89ae-b115c78026a4" {
return "0x1111BD4F3233e7a7f552AdAf32C910fD30de598B", nil
} else {
return "", fmt.Errorf("invalid session id")
}
}

signers := intent.Signers(getSessionVerifier)
signers := intent.Signers()
assert.Equal(t, 1, len(signers))
assert.Equal(t, "0x1111BD4F3233e7a7f552AdAf32C910fD30de598B", signers[0])

Expand Down
13 changes: 2 additions & 11 deletions intents/intent_sign_message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package intents

import (
"encoding/json"
"fmt"
"math/big"
"testing"

Expand All @@ -24,7 +23,7 @@ func TestRecoverMessageIntent(t *testing.T) {
"message": "0xdeadbeef"
},
"signatures": [{
"sessionId": "afaf60c0-67ba-4c9b-89ae-b115c78026a4",
"sessionId": "0x1111BD4F3233e7a7f552AdAf32C910fD30de598B",
"signature": "0x827b2a2afbf4a8a79e761fdb26e567b519a56a06e897dce5517b3ccfb408b55f20aaba276c1dade28112f51fe7262fbd0508da0019c0f8582c41b2be451ddede1b"
}]
}`
Expand All @@ -40,15 +39,7 @@ func TestRecoverMessageIntent(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, common.Bytes2Hex(hash), "5b15538a25716e951630dde1cf38ae056d764976145d1134576461203a621ddb")

getSessionVerifier := func(sessionId string) (string, error) {
if sessionId == "afaf60c0-67ba-4c9b-89ae-b115c78026a4" {
return "0x1111BD4F3233e7a7f552AdAf32C910fD30de598B", nil
} else {
return "", fmt.Errorf("invalid session id")
}
}

signers := intent.Signers(getSessionVerifier)
signers := intent.Signers()
assert.Equal(t, 1, len(signers))
assert.Equal(t, "0x1111BD4F3233e7a7f552AdAf32C910fD30de598B", signers[0])

Expand Down
89 changes: 75 additions & 14 deletions intents/intent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,10 @@ import (

"github.com/0xsequence/ethkit/go-ethereum/common"
"github.com/davecgh/go-spew/spew"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
)

func TestParseAndRecoverIntent(t *testing.T) {
fmt.Println(uuid.New().String())

data := `{
"version": "1.0.0",
"packet": {
Expand All @@ -35,7 +32,7 @@ func TestParseAndRecoverIntent(t *testing.T) {
}]
},
"signatures": [{
"sessionId": "afaf60c0-67ba-4c9b-89ae-b115c78026a4",
"sessionId": "0x1111BD4F3233e7a7f552AdAf32C910fD30de598B",
"signature": "0xcca6253c4fd281247ddd0fa487252ef91932eaec8d68b61f0901ccaa70345bf66fdbbd98ed3e3c9752f9e35ef2a7bc88dd9c8ae23c594241b476fe988824ab881c"
}]
}`
Expand All @@ -51,15 +48,7 @@ func TestParseAndRecoverIntent(t *testing.T) {
assert.NotNil(t, hash)
assert.Equal(t, common.Bytes2Hex(hash), "893060f818437f8e3d9b4d8e103c5eb3c325fa25dd0221fb7b61cca6dd03a79e")

getSessionVerifier := func(sessionId string) (string, error) {
if sessionId == "afaf60c0-67ba-4c9b-89ae-b115c78026a4" {
return "0x1111BD4F3233e7a7f552AdAf32C910fD30de598B", nil
} else {
return "", fmt.Errorf("invalid session id")
}
}

signers := intent.Signers(getSessionVerifier)
signers := intent.Signers()
assert.Equal(t, 1, len(signers))
assert.Equal(t, "0x1111BD4F3233e7a7f552AdAf32C910fD30de598B", signers[0])
assert.Equal(t, intent.PacketCode(), "sendTransactions")
Expand All @@ -79,7 +68,77 @@ func TestParseAndRecoverIntent(t *testing.T) {
assert.NotEqual(t, common.Bytes2Hex(hash), "893060f818437f8e3d9b4d8e103c5eb3c325fa25dd0221fb7b61cca6dd03a79e")
assert.Equal(t, intent.PacketCode(), "sendTransactions2")

signers = intent.Signers(getSessionVerifier)
signers = intent.Signers()
assert.Equal(t, 0, len(signers))

// Parsing the JSON without tabs, spaces, newlines, etc. should still work
// and produce the same hash
data2 := `{"signatures":[{"signature":"0xcca6253c4fd281247ddd0fa487252ef91932eaec8d68b61f0901ccaa70345bf66fdbbd98ed3e3c9752f9e35ef2a7bc88dd9c8ae23c594241b476fe988824ab881c","session":"0x1111BD4F3233e7a7f552AdAf32C910fD30de598B"}],"version":"1.0.0","packet":{"transactions":[{"token":"0x0000000000000000000000000000000000000000","value":"0","type":"erc20send","to":"0x0dc9603d4da53841C1C83f3B550C6143e60e0425"}],"wallet":"0xD67FC48b298B09Ed3D03403d930769C527186c4e","expires":1600086400,"code":"sendTransactions","network":"1","identifier":"test-identifier","issued":1600000000}}`
intent2 := &Intent{}
err = json.Unmarshal([]byte(data2), intent2)
assert.Nil(t, err)

hash2, err := intent2.Hash()
assert.Nil(t, err)
assert.NotNil(t, hash2)
assert.Equal(t, common.Bytes2Hex(hash2), "893060f818437f8e3d9b4d8e103c5eb3c325fa25dd0221fb7b61cca6dd03a79e")
}

func TestParseAndRecoverIntent_SessionKeyP256K1Typed(t *testing.T) {
data := `{
"version": "1.0.0",
"packet": {
"code": "sendTransactions",
"identifier": "test-identifier",
"issued": 1600000000,
"expires": 1600086400,
"wallet": "0xD67FC48b298B09Ed3D03403d930769C527186c4e",
"network": "1",
"transactions": [{
"type": "erc20send",
"token": "0x0000000000000000000000000000000000000000",
"to": "0x0dc9603d4da53841C1C83f3B550C6143e60e0425",
"value": "0"
}]
},
"signatures": [{
"sessionId": "0x001111BD4F3233e7a7f552AdAf32C910fD30de598B",
"signature": "0xcca6253c4fd281247ddd0fa487252ef91932eaec8d68b61f0901ccaa70345bf66fdbbd98ed3e3c9752f9e35ef2a7bc88dd9c8ae23c594241b476fe988824ab881c"
}]
}`

intent := &Intent{}
err := json.Unmarshal([]byte(data), intent)
assert.Nil(t, err)

assert.Equal(t, "1.0.0", intent.Version)

hash, err := intent.Hash()
assert.Nil(t, err)
assert.NotNil(t, hash)
assert.Equal(t, common.Bytes2Hex(hash), "893060f818437f8e3d9b4d8e103c5eb3c325fa25dd0221fb7b61cca6dd03a79e")

signers := intent.Signers()
assert.Equal(t, 1, len(signers))
assert.Equal(t, "0x001111BD4F3233e7a7f552AdAf32C910fD30de598B", signers[0])
assert.Equal(t, intent.PacketCode(), "sendTransactions")

// Changing the version should not affect the hash
intent.Version = "2.0.0"
hash, err = intent.Hash()
assert.Nil(t, err)
assert.NotNil(t, hash)
assert.Equal(t, common.Bytes2Hex(hash), "893060f818437f8e3d9b4d8e103c5eb3c325fa25dd0221fb7b61cca6dd03a79e")

// Changing the packet code SHOULD affect the hash (and make Signers() return empty)
intent.Packet = json.RawMessage(`{"code": "sendTransactions2"}`)
hash, err = intent.Hash()
assert.Nil(t, err)
assert.NotNil(t, hash)
assert.NotEqual(t, common.Bytes2Hex(hash), "893060f818437f8e3d9b4d8e103c5eb3c325fa25dd0221fb7b61cca6dd03a79e")
assert.Equal(t, intent.PacketCode(), "sendTransactions2")

signers = intent.Signers()
assert.Equal(t, 0, len(signers))

// Parsing the JSON without tabs, spaces, newlines, etc. should still work
Expand All @@ -104,6 +163,8 @@ func TestECDSAP256SessionSig(t *testing.T) {
message := "0x7a7e5a0913e63cac5886afcafedba93b17baae3eb4066534ffdd5e3da3e8c714"
signature := "r1:0x4038376385b045c19754bb69fa6cde925674778e6a1a78b8fa3135ec96b695aef5b8126c78dc17a2cc0be522a4e6154bf5152c908d763fb1c28e47cf419a3ea5"

fmt.Println(len(sessionId))

// get public key from sessionId
sessionIdBuff := common.FromHex(sessionId[3:])

Expand Down

0 comments on commit cd4ea13

Please sign in to comment.