Skip to content

Integration manual

Sergey Tolmachev edited this page Oct 24, 2018 · 20 revisions

Introduction

The integration of the application consists of several parts: the development of an application for the device and the protocol of interaction (check this repo) and the integration of the communication library, implementation of the protocol of interaction with the device in the final application.

Ledger Application

The source code for the application is contained in this repository. The build and install instructions is here.

Application protocol

At this moment (the application is in development), there are 2 commands: obtaining a public key (also returns a private key and the test message signature for debugging, in production it is necessary to remove) and the signature of the passed message.

Cryptography protocol

Waves uses ED25519 signature with X25519 keys (Montgomery form), but Ledger (like most of integrated cryptography devices) don't support X25519 keys. But there're the libraries with conversion functions from ED25519 keys to X25519 (Curve25519) crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk) for public key and crypto_sign_ed25519_sk_to_curve25519(curve25519_sk, ed25519_skpk) for private key:

I use the ED25519 keys and the signature inside the Ledger application, then you need to convert the keys from the device to X25519 format using that function on the client side. Looks like the ED25519 algo from Ledger SDK already installs 'sign' bit into the signature from the public key, so no any additional convertation for signature are needed (unlike the signature of libsodium).

Ledger app protocol

Service statuses:

SW_OK 0x9000
SW_USER_CANCELLED 0x9100
SW_CONDITIONS_NOT_SATISFIED 0x6985
SW_BUFFER_OVERFLOW 0x6990
SW_INCORRECT_P1_P2 0x6A86
SW_INS_NOT_SUPPORTED 0x6D00
SW_CLA_NOT_SUPPORTED  0x6E00
SW_SECURITY_STATUS_NOT_SATISFIED 0x6982

bip32 path

bip32 path bytes are the bytes of 5 int values. Waves bip32 path prefix is 5741564' = 0x80579bfc, so the bip32 path of first used address on the device is 44'/5741564'/0'/0'/1'. In bytes this is 0x8000002c80579bfc800000008000000080000001.

Getting a public key

hex message bytes

80 04 01 57 14 8000002c80579bfc800000008000000080000001

80 [command: 1 byte: 04 hex] [ask user confirmation: 1 byte: 01 hex] [chain id: 1 byte: 00 hex] [payload size: 1 byte: 14 hex: 20 bytes] [bip32 path bytes: 20 bytes: ...]

Chain ID for testnet is 'T' and 'W' for mainnet.

Answer

If request success:

[public key bytes: 32 bytes] [base58 address bytes: 35 bytes] [service status: 2 bytes: should be 9000 = SW_OK]

or

SW_USER_CANCELLED (9100) if user canceled the request

The error code will returns in error cause.

SW_CONDITIONS_NOT_SATISFIED (6985) if some required condition was failed SW_DEVICE_IS_LOCKED (6986) if device is locked

Example:

Approved request:

HID => 80040057148000002c80579bfc800000008000000080000001
HID <= 67e0088be66a1995b4b296df863d10389a2e4fd9369224290a134ec1a1aab0613350485a31676e63335a45467079335433655671597171414b45564577536a757433629000
publicKey (base58): 7zV8VPvP2Pz119hj2RcRm6HDz25hkrokYpw6CjRenMYt
address: 3PHZ1gnc3ZEFpy3T3eVqYqqAKEVEwSjut3b

Denied request:

HID => 80040157148000002c80579bfc800000008000000080000001
HID <= 9100
User denied signing request on Ledger Nano S device.

Sign message

Big message should be chunked by 128 bytes

hex message for first part

80 02 00 00 7b 8000 002c...

80 02 [not last command message: 1 byte: 00 hex] [unused: 1 byte: 00 hex] [payload size byte: 7b hex: 123 bytes] [bip32 path bytes: 20 bytes: ...] [amount decimals: 1 byte] [fee decimals: 1 byte] [data type: 1 byte] [data version: 1 byte] [tx chunk bytes: 98 bytes]

hex message for next parts

80 02 [not last command message: 1 byte: 00 hex] [unused: 1 byte: 00 hex] [payload size byte: 7b hex: 123 bytes] [tx chunk bytes: 123 bytes]

hex message for last part

80 02 80 00 18 3ed87...

80 02 [last command message: 1 byte: 80 hex] [chain id: 1 byte: 00 hex] [payload size byte: 18 hex: 24 bytes] [last 24 tx bytes]

For signing order add byte 252 as data type (and 0 for data version), for some data - 253, for request - 254, for message - 255. For different transactions set data type and version equals to tx type and version. This byte will not be signed, it tells the device what type of message it is sent to display in the user interface. Nothing needs to be transferred for transactions, the first byte of the tx body data is the transaction type and it will be signed as expected.

Answer

SW_OK (9000) after each chunk

[signature: 64 bytes] [service status: should be 9000 = SW_OK] after last one

or

SW_USER_CANCELLED (9100) if user canceled the request

The error code will returns in error cause.

SW_CONDITIONS_NOT_SATISFIED (6985) if some required condition was failed SW_BUFFER_OVERFLOW (6990) if max transaction size was reached (650 bytes for now) SW_DEVICE_IS_LOCKED (6986) if device is locked

Example:

HID => 800200577b8000002c80579bfc8000000080000000800000010808040204023897f7c45e11ef1e2ef9a6d70f378053c6a0e0a7b2f4cbb8d7eecebd585d237e0181121cb46877fbc5c8059919e2a9cf03dcf2fbb112020ec38b7d868b7dd742810000000163692c9e25000000000000000100000000000186a00157da1ca8737e
HID <= 9000
HID => 800280571b159b763ed87810231ea189c0bce5352d630abc0006707269766574
HID <= 823a32d95430e6c9884c99b96369a66e5bd119fc6d85254942512d8c2d75f372c003c888e773c8996a41ce6b209a270366ca80d9d1fb389340a5ee7abd940d0a9000
signature 3c1idAPkLtX3TUoXuMhLxFUHSLEq8AFY6y2SRjDxFZt99reXKkHHVJiGmfrBn5NXKSSxh5Ux1k7UHP3nS826qx3j
HID => 800200577b8000002c80579bfc8000000080000000800000010808040204023897f7c45e11ef1e2ef9a6d70f378053c6a0e0a7b2f4cbb8d7eecebd585d237e0181121cb46877fbc5c8059919e2a9cf03dcf2fbb112020ec38b7d868b7dd742810000000163692c9e25000000000000000100000000000186a00157da1ca8737e
HID <= 9000
HID => 800280571b159b763ed87810231ea189c0bce5352d630abc0006707269766574
HID <= 9100
User denied signing request on Ledger Nano S device.

App version

To get app version you need to send 8006 to the device, then it will return 3 bytes: [major version][minor version][patch version].

Communication library

You should pick one for your project language:

There is a test Python implementation of communication with ledger Waves app.

Clone this wiki locally
You can’t perform that action at this time.