Skip to content

Commit

Permalink
Merge branch 'develop' into feat/change-Ed25519-address-derivation
Browse files Browse the repository at this point in the history
  • Loading branch information
Thoralf-M authored Jun 12, 2024
2 parents ae356c1 + 79c427b commit 7f2561b
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 88 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,19 +149,19 @@ Then, one can use `generic-cli` like this:

- Get a public key for a BIP-32 derivation without prompting the user:
```shell-session
$ generic-cli getAddress --use-block "44'/784'/0'/0'/0'"
$ generic-cli getAddress --use-block "44'/4218'/0'/0'/0'"
a42e71c004770d1a48956090248a8d7d86ee02726b5aab2a5cd15ca9f57cbd71
```

- Show the address on device for a BIP-32 derivation and obtain the public key:
```shell-session
$ generic-cli getAddress --use-block --verify "44'/535348'/0'/0/0"
$ generic-cli getAddress --use-block --verify "44'/4218'/0'/0'/0'"
a42e71c004770d1a48956090248a8d7d86ee02726b5aab2a5cd15ca9f57cbd71
```

- Sign a transaction:
```shell-session
$ generic-cli sign --use-block "44'/784'/0'/0'/0'" '00000000050205546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e1284af431cf032b5d85324135bf9a3073e920d7f5020000000000000020a06f410c175e828c24cee84cb3bd95cff25c33fbbdcb62c6596e8e423784ffe701d08074075c7097f361e8b443e2075a852a2292e80180969800000000001643fb2578ff7191c643079a62c1cca8ec2752bc05546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e101000000000000002c01000000000000'
$ generic-cli sign --use-block "44'/4218'/0'/0'/0'" '00000000050205546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e1284af431cf032b5d85324135bf9a3073e920d7f5020000000000000020a06f410c175e828c24cee84cb3bd95cff25c33fbbdcb62c6596e8e423784ffe701d08074075c7097f361e8b443e2075a852a2292e80180969800000000001643fb2578ff7191c643079a62c1cca8ec2752bc05546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e101000000000000002c01000000000000'
Signing: <Buffer 1f 41 2f 22 53 11 f5 89 eb 3e a8 fd 05 d3 de 9e 1f 41 2f 22 53 11 f5 89 eb 3e a8 fd 05 d3 de 9e 1f 41 2f 22 53 11 f5 89 eb 3e a8 fd 05 d3 de 9e f8 f2 ... 14 more bytes>
906a1d402aa17b32e96903b1a42ba0df9b690157e6b9a974a36b81ee023a7e6bd39eeaa40cab270e6451dff4d820044c982bfd12a6fa88c0f5b758c0d8b67201
```
Expand Down
2 changes: 1 addition & 1 deletion guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Install the Sui app on your Ledger device to manage SUI Tokens with the [Sui Wal

- Open the Sui wallet and select "Connect to Ledger device".

- Enter the derivation path (default `m/44'/784'/0'/0/0`).
- Enter the derivation path (default `m/44'/4218'/0'/0/0`).

- You can use this account to receive Sui tokens.

Expand Down
2 changes: 1 addition & 1 deletion rust-app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ overflow-checks = false

[package.metadata.ledger]
name = "Sui"
path = ["44'/784'"]
path = ["44'/4218'"]
curve = ["ed25519"]
flags = "0"

Expand Down
2 changes: 1 addition & 1 deletion rust-app/src/implementation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub const BIP_PATH_PARSER: BipParserImplT = SubInterp(DefaultInterp);

// Need a path of length 5, as make_bip32_path panics with smaller paths
pub const BIP32_PREFIX: [u32; 5] =
ledger_device_sdk::ecc::make_bip32_path(b"m/44'/784'/123'/0'/0'");
ledger_device_sdk::ecc::make_bip32_path(b"m/44'/4218'/123'/0'/0'");

pub async fn get_address_apdu(io: HostIO, prompt: bool) {
let input = match io.get_params::<1>() {
Expand Down
12 changes: 6 additions & 6 deletions ts-tests/public-key-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import type Sui from "./Sui";

describe('public key tests', () => {

afterEach( async function() {
await Axios.post(BASE_URL + "/automation", {version: 1, rules: []});
afterEach(async function () {
await Axios.post(BASE_URL + "/automation", { version: 1, rules: [] });
await Axios.delete(BASE_URL + "/events");
});

it('provides a public key', async () => {

await sendCommandAndAccept(async (client : Sui) => {
const rv = await client.getPublicKey("44'/784'/0'");
await sendCommandAndAccept(async (client: Sui) => {
const rv = await client.getPublicKey("44'/4218'/0'");
expect(new Buffer(rv.publicKey).toString('hex')).to.equal("6fc6f39448ad7af0953b78b16d0f840e6fe718ba4a89384239ff20ed088da2fa");
expect(new Buffer(rv.address).toString('hex')).to.equal("56b19e720f3bfa8caaef806afdd5dfaffd0d6ec9476323a14d1638ad734b2ba5");
return;
Expand All @@ -23,8 +23,8 @@ describe('public key tests', () => {

it('does address verification', async () => {

await sendCommandAndAccept(async (client : Sui) => {
const rv = await client.verifyAddress("44'/784'/0'");
await sendCommandAndAccept(async (client: Sui) => {
const rv = await client.verifyAddress("44'/4218'/0'");
expect(new Buffer(rv.publicKey).toString('hex')).to.equal("6fc6f39448ad7af0953b78b16d0f840e6fe718ba4a89384239ff20ed088da2fa");
expect(new Buffer(rv.address).toString('hex')).to.equal("56b19e720f3bfa8caaef806afdd5dfaffd0d6ec9476323a14d1638ad734b2ba5");
return;
Expand Down
152 changes: 76 additions & 76 deletions ts-tests/signing-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import type Sui from "./Sui";
import * as blake2b from "blake2b";
import { instantiate, Nacl } from "js-nacl";

let nacl : Nacl =null;
let nacl: Nacl = null;

instantiate(n => { nacl=n; });
instantiate(n => { nacl = n; });

function testTransaction(path: string, txn: Buffer, prompts: any[]) {
return async () => {
await sendCommandAndAccept(async (client : Sui) => {
await sendCommandAndAccept(async (client: Sui) => {

const { publicKey } = await client.getPublicKey(path);

Expand All @@ -22,84 +22,84 @@ function testTransaction(path: string, txn: Buffer, prompts: any[]) {
const sig = await client.signTransaction(path, txn);
expect(sig.signature.length).to.equal(64);
const pass = nacl.crypto_sign_verify_detached(
sig.signature,
blake2b(32).update(txn).digest(),
publicKey,
sig.signature,
blake2b(32).update(txn).digest(),
publicKey,
);
expect(pass).to.equal(true);
}, prompts);
}
}

describe("Signing tests", function() {
before( async function() {
while(!nacl) await new Promise(r => setTimeout(r, 100));
describe("Signing tests", function () {
before(async function () {
while (!nacl) await new Promise(r => setTimeout(r, 100));
})

it("can sign a transaction",
testTransaction(
"44'/784'/0'",
Buffer.from("000000000002000840420f000000000000204f2370b2a4810ad6c8e1cfd92cc8c8818fef8f59e3a80cea17871f78d850ba4b0202000101000001010200000101006fb21feead027da4873295affd6c4f3618fe176fa2fbf3e7b5ef1d9463b31e210112a6d0c44edc630d2724b1f57fea4f93308b1d22164402c65778bd99379c4733070000000000000020f2fd3c87b227f1015182fe4348ed680d7ed32bcd3269704252c03e1d0b13d30d6fb21feead027da4873295affd6c4f3618fe176fa2fbf3e7b5ef1d9463b31e2101000000000000000c0400000000000000", "hex"),
[
{
"header": "Transfer",
"prompt": "SUI"
},
{
"header": "From",
"prompt": "0x56b19e720f3bfa8caaef806afdd5dfaffd0d6ec9476323a14d1638ad734b2ba5",
"paginate": true
},
{
"header": "To",
"prompt": "0x4f2370b2a4810ad6c8e1cfd92cc8c8818fef8f59e3a80cea17871f78d850ba4b",
"paginate": true
},
{
"header": "Amount",
"prompt": "SUI 0.001"
},
{
"header": "Max Gas",
"prompt": "SUI 0.000001036"
},
{
"text": "Sign Transaction?",
"x": 19,
"y": 11
},
{
"text": "Confirm",
"x": 43,
"y": 11,
}
]
));
testTransaction(
"44'/4218'/0'",
Buffer.from("000000000002000840420f000000000000204f2370b2a4810ad6c8e1cfd92cc8c8818fef8f59e3a80cea17871f78d850ba4b0202000101000001010200000101006fb21feead027da4873295affd6c4f3618fe176fa2fbf3e7b5ef1d9463b31e210112a6d0c44edc630d2724b1f57fea4f93308b1d22164402c65778bd99379c4733070000000000000020f2fd3c87b227f1015182fe4348ed680d7ed32bcd3269704252c03e1d0b13d30d6fb21feead027da4873295affd6c4f3618fe176fa2fbf3e7b5ef1d9463b31e2101000000000000000c0400000000000000", "hex"),
[
{
"header": "Transfer",
"prompt": "SUI"
},
{
"header": "From",
"prompt": "0x56b19e720f3bfa8caaef806afdd5dfaffd0d6ec9476323a14d1638ad734b2ba5",
"paginate": true
},
{
"header": "To",
"prompt": "0x4f2370b2a4810ad6c8e1cfd92cc8c8818fef8f59e3a80cea17871f78d850ba4b",
"paginate": true
},
{
"header": "Amount",
"prompt": "SUI 0.001"
},
{
"header": "Max Gas",
"prompt": "SUI 0.000001036"
},
{
"text": "Sign Transaction?",
"x": 19,
"y": 11
},
{
"text": "Confirm",
"x": 43,
"y": 11,
}
]
));

it("can blind sign an unknown transaction", async function () {
const path = "44'/784'/0'";
const path = "44'/4218'/0'";
const txn = Buffer.from("00000000050205546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e1284af431cf032b5d85324135bf9a3073e920d7f5020000000000000020a06f410c175e828c24cee84cb3bd95cff25c33fbbdcb62c6596e8e423784ffe702d08074075c7097f361e8b443e2075a852a2292e8a08074075c7097f361e8b443e2075a852a2292e80180969800000000001643fb2578ff7191c643079a62c1cca8ec2752bc05546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e101000000000000002c01000000000000", "hex");
const prompts =
[
{
"header": "WARNING",
"prompt": "Transaction not recognized"
},
{
"header": "Transaction Hash",
"prompt": "0xfc2bce70e1cb980a6d49a32ff770a782ee13dabdecee085b82e0fdad5e92fcdd"
},
{
"text": "Blind Sign Transaction?",
"x": 4,
"y": 11
},
{
"text": "Confirm",
"x": 43,
"y": 11,
}
];
[
{
"header": "WARNING",
"prompt": "Transaction not recognized"
},
{
"header": "Transaction Hash",
"prompt": "0xfc2bce70e1cb980a6d49a32ff770a782ee13dabdecee085b82e0fdad5e92fcdd"
},
{
"text": "Blind Sign Transaction?",
"x": 4,
"y": 11
},
{
"text": "Confirm",
"x": 43,
"y": 11,
}
];

await toggleBlindSigningSettings();
await Axios.delete(BASE_URL + "/events");
Expand All @@ -110,33 +110,33 @@ describe("Signing tests", function() {
});

it("should reject signing a non-SUI coin transaction, if blind signing is not enabled", async function () {
const path = "44'/784'/0'";
const path = "44'/4218'/0'";
const txn = Buffer.from("AAAAAAADAQAe2uv1Mds+xCVK5Jv/Dv5cgEl/9DthDcpbjWcsmFpzbs6BNQAAAAAAIKPD8GQqgBpJZRV+nFDRE7rqR0Za8x0pyfLusVdpPPVRAAgADl+jHAAAAAAg5y3MHATlk+Ik5cPIdEz5iPANs1jcXZHVGjh4Mb16lwkCAgEAAAEBAQABAQIAAAECAF/sd27xyQe/W+gY4WRtPlQro1siWQu79s0pxbbCSRafAfnjaU5yJSFFDJznsAaBqbkiR9CB8DJqWki8fn8AUZeQz4E1AAAAAAAgTRU/MsawTJirpVwjDF8gyiEbaT0+7J0V8ifUEGGBkcVf7Hdu8ckHv1voGOFkbT5UK6NbIlkLu/bNKcW2wkkWn+gDAAAAAAAA8NdGAAAAAAAA", "base64");

await sendCommandExpectFail(async (client : Sui) => {
await sendCommandExpectFail(async (client: Sui) => {
await client.signTransaction(path, txn);
});
});

it("should reject signing an unknown transaction, if blind signing is not enabled", async function () {
const path = "44'/784'/0'";
const path = "44'/4218'/0'";
const txn = Buffer.from("00000000050205546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e1284af431cf032b5d85324135bf9a3073e920d7f5020000000000000020a06f410c175e828c24cee84cb3bd95cff25c33fbbdcb62c6596e8e423784ffe702d08074075c7097f361e8b443e2075a852a2292e8a08074075c7097f361e8b443e2075a852a2292e80180969800000000001643fb2578ff7191c643079a62c1cca8ec2752bc05546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e101000000000000002c01000000000000", "hex");

await sendCommandExpectFail(async (client : Sui) => {
await sendCommandExpectFail(async (client: Sui) => {
await client.signTransaction(path, txn);
});
});

it("Rejects a blind sign with mismatching lengths", async function () {
const path = "44'/784'/0'";
const path = "44'/4218'/0'";
const txn = Buffer.from("00000000050205546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e1284af431cf032b5d85324135bf9a3073e920d7f5020000000000000020a06f410c175e828c24cee84cb3bd95cff25c33fbbdcb62c6596e8e423784ffe702d08074075c7097f361e8b443e2075a852a2292e8a08074075c7097f361e8b443e2075a852a2292e80180969800000000001643fb2578ff7191c643079a62c1cca8ec2752bc05546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e101000000000000002c01000000000000", "hex");

await toggleBlindSigningSettings();
await Axios.delete(BASE_URL + "/events");
await sendCommandExpectFail(async (client : any) => {
await sendCommandExpectFail(async (client: any) => {
client.oldSendChunks = client.sendChunks;
client.sendChunks = (cla, ins, p1, p2, payload) => {
payload[0][3]=payload[0][3]+20; // Add 20*2^24 to the transaction length, so we'll run out of input.
payload[0][3] = payload[0][3] + 20; // Add 20*2^24 to the transaction length, so we'll run out of input.
const rv = client.oldSendChunks(cla, ins, p1, p2, payload);
return rv;
}
Expand All @@ -146,7 +146,7 @@ describe("Signing tests", function() {
await sendCommandAndAccept(
async client => {
const { publicKey } = await client.getPublicKey(path);
expect(publicKey.length>0).to.equal(true);
expect(publicKey.length > 0).to.equal(true);
},
[]);
await Axios.delete(BASE_URL + "/events");
Expand Down

0 comments on commit 7f2561b

Please sign in to comment.