Skip to content

Commit

Permalink
Merge pull request #122 from oasisprotocol/matevz/fix/sr25519-ledger-…
Browse files Browse the repository at this point in the history
…address

fix(wallet/ledger): Derivation of sr25519 addresses
  • Loading branch information
matevz authored Sep 26, 2023
2 parents b924ef8 + 30c9422 commit 517ad46
Show file tree
Hide file tree
Showing 13 changed files with 55 additions and 40 deletions.
2 changes: 1 addition & 1 deletion examples/account/amend-commission-schedule.y.in
Original file line number Diff line number Diff line change
@@ -1 +1 @@
oasis account amend-commission-schedule --bounds 29000/1000/2000,35000/900/1900 --rates 29000/1500
oasis account amend-commission-schedule --bounds 329000/1000/2000,335000/900/1900 --rates 329000/1500
8 changes: 4 additions & 4 deletions examples/account/amend-commission-schedule.y.out
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ Method: staking.AmendCommissionSchedule
Body:
Amendment:
Rates:
(1) start: epoch 29000
(1) start: epoch 329000
rate: 1.5%
Rate Bounds:
(1) start: epoch 29000
(1) start: epoch 329000
minimum rate: 1.0%
maximum rate: 2.0%
(2) start: epoch 35000
(2) start: epoch 335000
minimum rate: 0.9%
maximum rate: 1.9%
Nonce: 1
Fee:
Amount: 0.0 TEST
Gas limit: 1355
Gas limit: 1361
(gas price: 0.0 TEST per gas unit)

Network: testnet
Expand Down
4 changes: 2 additions & 2 deletions examples/account/delegate-paratime.y.out
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Authorized signer(s):
1. Bx6gOixnxy15tCs09ua5DcKyX9uo2Forb32O6Hyjoc8= (ed25519)
Nonce: 0
Fee:
Amount: 0.0011312 TEST
Gas limit: 11312
Amount: 0.0061312 TEST
Gas limit: 61312
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
Expand Down
2 changes: 1 addition & 1 deletion examples/account/deposit-eth.y.out
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Authorized signer(s):
Nonce: 0
Fee:
Amount: 0.0 TEST
Gas limit: 11310
Gas limit: 61310
(gas price: 0.0 TEST per gas unit)

Network: testnet
Expand Down
2 changes: 1 addition & 1 deletion examples/account/deposit-named.y.out
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Authorized signer(s):
Nonce: 0
Fee:
Amount: 0.0 TEST
Gas limit: 11310
Gas limit: 61310
(gas price: 0.0 TEST per gas unit)

Network: testnet
Expand Down
2 changes: 1 addition & 1 deletion examples/account/deposit-oasis.y.out
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Authorized signer(s):
Nonce: 0
Fee:
Amount: 0.0 TEST
Gas limit: 11310
Gas limit: 61310
(gas price: 0.0 TEST per gas unit)

Network: testnet
Expand Down
2 changes: 1 addition & 1 deletion examples/account/deposit.y.out
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Authorized signer(s):
Nonce: 0
Fee:
Amount: 0.0 TEST
Gas limit: 11285
Gas limit: 61285
(gas price: 0.0 TEST per gas unit)

Network: testnet
Expand Down
4 changes: 2 additions & 2 deletions examples/account/undelegate-paratime.y.out
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Authorized signer(s):
1. Bx6gOixnxy15tCs09ua5DcKyX9uo2Forb32O6Hyjoc8= (ed25519)
Nonce: 0
Fee:
Amount: 0.003131 TEST
Gas limit: 31310
Amount: 0.012131 TEST
Gas limit: 121310
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
Expand Down
4 changes: 2 additions & 2 deletions examples/account/withdraw-named.y.out
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Authorized signer(s):
1. Bx6gOixnxy15tCs09ua5DcKyX9uo2Forb32O6Hyjoc8= (ed25519)
Nonce: 0
Fee:
Amount: 0.0011311 TEST
Gas limit: 11311
Amount: 0.0061311 TEST
Gas limit: 61311
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
Expand Down
4 changes: 2 additions & 2 deletions examples/account/withdraw-oasis.y.out
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Authorized signer(s):
1. Bx6gOixnxy15tCs09ua5DcKyX9uo2Forb32O6Hyjoc8= (ed25519)
Nonce: 0
Fee:
Amount: 0.0011311 TEST
Gas limit: 11311
Amount: 0.0061311 TEST
Gas limit: 61311
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
Expand Down
4 changes: 2 additions & 2 deletions examples/account/withdraw.y.out
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Authorized signer(s):
1. Bx6gOixnxy15tCs09ua5DcKyX9uo2Forb32O6Hyjoc8= (ed25519)
Nonce: 0
Fee:
Amount: 0.0011286 TEST
Gas limit: 11286
Amount: 0.0061286 TEST
Gas limit: 61286
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
Expand Down
53 changes: 34 additions & 19 deletions wallet/ledger/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ import (
"golang.org/x/crypto/sha3"

"github.com/oasisprotocol/oasis-core/go/common/cbor"
coreSignature "github.com/oasisprotocol/oasis-core/go/common/crypto/signature"
staking "github.com/oasisprotocol/oasis-core/go/staking/api"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/crypto/signature"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/crypto/signature/ed25519"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/crypto/signature/sr25519"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/types"

"github.com/oasisprotocol/cli/wallet"
)

// NOTE: Some of this is lifted from https://github.com/oasisprotocol/oasis-core-ledger but updated
Expand Down Expand Up @@ -75,24 +78,24 @@ func (ld *ledgerDevice) GetVersion() (*VersionInfo, error) {
}, nil
}

// GetPublicKeyEd25519 returns the Ed25519 public key associated with the given derivation path.
// If the requireConfirmation flag is set, this will require confirmation from the user.
func (ld *ledgerDevice) GetPublicKeyEd25519(path []uint32, requireConfirmation bool) ([]byte, error) {
return ld.getPublicKey25519(path, insGetAddrEd25519, requireConfirmation)
}

// GetPublicKeySr25519 returns the Sr25519 public key associated with the given derivation path.
// GetPublicKey25519 returns the Ed25519 or Sr25519 public key associated with the given derivation path.
// If the requireConfirmation flag is set, this will require confirmation from the user.
func (ld *ledgerDevice) GetPublicKeySr25519(path []uint32, requireConfirmation bool) ([]byte, error) {
return ld.getPublicKey25519(path, insGetAddrSr25519, requireConfirmation)
}

func (ld *ledgerDevice) getPublicKey25519(path []uint32, ins byte, requireConfirmation bool) ([]byte, error) {
func (ld *ledgerDevice) GetPublicKey25519(path []uint32, algorithm string, requireConfirmation bool) ([]byte, error) {
pathBytes, err := getSerializedPath(path)
if err != nil {
return nil, fmt.Errorf("ledger: failed to get serialized path bytes: %w", err)
}

var ins byte
switch algorithm {
case wallet.AlgorithmEd25519Adr8:
ins = insGetAddrEd25519
case wallet.AlgorithmSr25519Adr8:
ins = insGetAddrSr25519
default:
return nil, fmt.Errorf("ledger: unknown provided algorithm %s", algorithm)
}

response, err := ld.getPublicKeyRaw(pathBytes, ins, requireConfirmation)
if err != nil {
return nil, err
Expand All @@ -105,16 +108,28 @@ func (ld *ledgerDevice) getPublicKey25519(path []uint32, ins byte, requireConfir
rawPubkey := response[0:32]
rawAddr := string(response[32:])

var pubkey coreSignature.PublicKey
if err = pubkey.UnmarshalBinary(rawPubkey); err != nil {
return nil, fmt.Errorf("ledger: device returned malformed public key: %w", err)
// Sanity check, if the public key matches the expected address shown on Ledger.
var addrSpec types.SignatureAddressSpec
switch algorithm {
case wallet.AlgorithmEd25519Adr8:
addrSpec.Ed25519 = &ed25519.PublicKey{}
if err = addrSpec.Ed25519.UnmarshalBinary(rawPubkey); err != nil {
return nil, fmt.Errorf("ledger: device returned malformed public key: %w", err)
}
case wallet.AlgorithmSr25519Adr8:
addrSpec.Sr25519 = &sr25519.PublicKey{}
if err = addrSpec.Sr25519.UnmarshalBinary(rawPubkey); err != nil {
return nil, fmt.Errorf("ledger: device returned malformed public key: %w", err)
}
default:
return nil, fmt.Errorf("ledger: unknown provided algorithm %s", algorithm)
}

var addrFromDevice staking.Address
var addrFromDevice types.Address
if err = addrFromDevice.UnmarshalText([]byte(rawAddr)); err != nil {
return nil, fmt.Errorf("ledger: device returned malformed account address: %w", err)
}
addrFromPubkey := staking.NewAddress(pubkey)
addrFromPubkey := types.NewAddress(addrSpec)
if !addrFromDevice.Equal(addrFromPubkey) {
return nil, fmt.Errorf(
"ledger: account address computed on device (%s) doesn't match internally computed account address (%s)",
Expand Down
4 changes: 2 additions & 2 deletions wallet/ledger/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func newAccount(cfg *accountConfig) (wallet.Account, error) {
if cfg.Algorithm == wallet.AlgorithmEd25519Legacy {
path = getLegacyPath(cfg.Number)
}
rawPk, err := dev.GetPublicKeyEd25519(path, false)
rawPk, err := dev.GetPublicKey25519(path, wallet.AlgorithmEd25519Adr8, false)
if err != nil {
_ = dev.Close()
return nil, err
Expand Down Expand Up @@ -219,7 +219,7 @@ func newAccount(cfg *accountConfig) (wallet.Account, error) {
pk = secp256k1pk
case wallet.AlgorithmSr25519Adr8:
path = getAdr0008Path(cfg.Number)
rawPk, err := dev.GetPublicKeySr25519(path, false)
rawPk, err := dev.GetPublicKey25519(path, wallet.AlgorithmSr25519Adr8, false)
if err != nil {
_ = dev.Close()
return nil, err
Expand Down

0 comments on commit 517ad46

Please sign in to comment.