@ledgerhq/hw-ledger-key-ring-protocol 0.3.1 → 0.3.2-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +7 -0
- package/lib/ApduDevice.d.ts +1 -0
- package/lib/ApduDevice.d.ts.map +1 -1
- package/lib/ApduDevice.js +195 -240
- package/lib/ApduDevice.js.map +1 -1
- package/lib/CommandBlock.js +26 -2
- package/lib/CommandBlock.js.map +1 -1
- package/lib/CommandStream.js +69 -85
- package/lib/CommandStream.js.map +1 -1
- package/lib/CommandStreamResolver.js +42 -56
- package/lib/CommandStreamResolver.js.map +1 -1
- package/lib/Device.js +115 -131
- package/lib/Device.js.map +1 -1
- package/lib/IndexedTree.js +2 -0
- package/lib/IndexedTree.js.map +1 -1
- package/lib/PublicKey.js +1 -0
- package/lib/PublicKey.js.map +1 -1
- package/lib/SeedId.js +12 -0
- package/lib/SeedId.js.map +1 -1
- package/lib/StreamTree.js +56 -72
- package/lib/StreamTree.js.map +1 -1
- package/lib/StreamTreeCipher.js +62 -75
- package/lib/StreamTreeCipher.js.map +1 -1
- package/lib/__tests__/codec.js +3 -12
- package/lib/__tests__/codec.js.map +1 -1
- package/lib/__tests__/crypto.js +22 -31
- package/lib/__tests__/crypto.js.map +1 -1
- package/lib/__tests__/indexed_tree.js +2 -3
- package/lib/__tests__/indexed_tree.js.map +1 -1
- package/lib/__tests__/key_exchange.js +40 -49
- package/lib/__tests__/key_exchange.js.map +1 -1
- package/lib/__tests__/shared_object.js +34 -47
- package/lib/__tests__/shared_object.js.map +1 -1
- package/lib-es/ApduDevice.d.ts +1 -0
- package/lib-es/ApduDevice.d.ts.map +1 -1
- package/lib-es/ApduDevice.js +195 -240
- package/lib-es/ApduDevice.js.map +1 -1
- package/lib-es/CommandBlock.js +26 -2
- package/lib-es/CommandBlock.js.map +1 -1
- package/lib-es/CommandStream.js +69 -85
- package/lib-es/CommandStream.js.map +1 -1
- package/lib-es/CommandStreamResolver.js +42 -56
- package/lib-es/CommandStreamResolver.js.map +1 -1
- package/lib-es/Device.js +115 -131
- package/lib-es/Device.js.map +1 -1
- package/lib-es/IndexedTree.js +2 -0
- package/lib-es/IndexedTree.js.map +1 -1
- package/lib-es/PublicKey.js +1 -0
- package/lib-es/PublicKey.js.map +1 -1
- package/lib-es/SeedId.js +12 -0
- package/lib-es/SeedId.js.map +1 -1
- package/lib-es/StreamTree.js +56 -72
- package/lib-es/StreamTree.js.map +1 -1
- package/lib-es/StreamTreeCipher.js +62 -75
- package/lib-es/StreamTreeCipher.js.map +1 -1
- package/lib-es/__tests__/codec.js +3 -12
- package/lib-es/__tests__/codec.js.map +1 -1
- package/lib-es/__tests__/crypto.js +22 -31
- package/lib-es/__tests__/crypto.js.map +1 -1
- package/lib-es/__tests__/indexed_tree.js +2 -3
- package/lib-es/__tests__/indexed_tree.js.map +1 -1
- package/lib-es/__tests__/key_exchange.js +40 -49
- package/lib-es/__tests__/key_exchange.js.map +1 -1
- package/lib-es/__tests__/shared_object.js +34 -47
- package/lib-es/__tests__/shared_object.js.map +1 -1
- package/package.json +4 -4
- package/tsconfig.json +0 -1
|
@@ -3,15 +3,6 @@
|
|
|
3
3
|
This test suite simulates an application generating data (using a fixed shchema) and sharing part of the
|
|
4
4
|
data to specific users. The data is encrypted using a StreamTree.
|
|
5
5
|
*/
|
|
6
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
7
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
8
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
9
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
10
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
11
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
12
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
7
|
const StreamTree_1 = require("../StreamTree");
|
|
17
8
|
const __1 = require("..");
|
|
@@ -19,45 +10,41 @@ const CommandBlock_1 = require("../CommandBlock");
|
|
|
19
10
|
const StreamTreeCipher_1 = require("../StreamTreeCipher");
|
|
20
11
|
const Crypto_1 = require("../Crypto");
|
|
21
12
|
const APPLICATION_ID = 12;
|
|
22
|
-
function encryptSharedObject(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return encryptedSharedObject;
|
|
34
|
-
});
|
|
13
|
+
async function encryptSharedObject(device, tree, sharedObject, mapping = new Map()) {
|
|
14
|
+
const cipher = StreamTreeCipher_1.StreamTreeCipher.create(device);
|
|
15
|
+
const encrypt = async (key, defaultPath) => {
|
|
16
|
+
return Crypto_1.crypto.to_hex(await cipher.encrypt(tree, Crypto_1.DerivationPath.toIndexArray(mapping.get(key) || defaultPath), new TextEncoder().encode(sharedObject[key].toString())));
|
|
17
|
+
};
|
|
18
|
+
const encryptedSharedObject = {
|
|
19
|
+
name: await encrypt("name", `0h/${APPLICATION_ID}h/0h/0h/0h`),
|
|
20
|
+
age: await encrypt("age", `0h/${APPLICATION_ID}h/0h/1h/0h`),
|
|
21
|
+
email: await encrypt("email", `0h/${APPLICATION_ID}h/0h/2h/0h`),
|
|
22
|
+
};
|
|
23
|
+
return encryptedSharedObject;
|
|
35
24
|
}
|
|
36
|
-
function decryptSharedObject(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return sharedObject;
|
|
50
|
-
});
|
|
25
|
+
async function decryptSharedObject(device, tree, encryptedSharedObject, mapping = new Map()) {
|
|
26
|
+
const cipher = StreamTreeCipher_1.StreamTreeCipher.create(device);
|
|
27
|
+
const decrypt = async (key, defaultPath) => {
|
|
28
|
+
const path = Crypto_1.DerivationPath.toIndexArray(mapping.get(key) || defaultPath);
|
|
29
|
+
const bytes = await cipher.decrypt(tree, path, Crypto_1.crypto.from_hex(encryptedSharedObject[key]));
|
|
30
|
+
return new TextDecoder().decode(bytes);
|
|
31
|
+
};
|
|
32
|
+
const sharedObject = {
|
|
33
|
+
name: await decrypt("name", `0h/${APPLICATION_ID}h/0h/0h/0h`),
|
|
34
|
+
age: parseInt(await decrypt("age", `0h/${APPLICATION_ID}h/0h/1h/0h`)),
|
|
35
|
+
email: await decrypt("email", `0h/${APPLICATION_ID}h/0h/2h/0h`),
|
|
36
|
+
};
|
|
37
|
+
return sharedObject;
|
|
51
38
|
}
|
|
52
39
|
describe("Shared object scenario using StreamTree", () => {
|
|
53
|
-
it("should create a tree with 3 members, one member encrypt a shared object and another one decrypts it", () =>
|
|
54
|
-
const alice =
|
|
55
|
-
const bob =
|
|
56
|
-
const carol =
|
|
40
|
+
it("should create a tree with 3 members, one member encrypt a shared object and another one decrypts it", async () => {
|
|
41
|
+
const alice = await __1.device.software();
|
|
42
|
+
const bob = await __1.device.software();
|
|
43
|
+
const carol = await __1.device.software();
|
|
57
44
|
// Create a new tree owned by alice
|
|
58
|
-
let tree =
|
|
45
|
+
let tree = await StreamTree_1.StreamTree.createNewTree(alice);
|
|
59
46
|
// Share the application node with bob
|
|
60
|
-
tree =
|
|
47
|
+
tree = await tree.share(tree.getApplicationRootPath(APPLICATION_ID), alice, (await bob.getPublicKey()).publicKey, "Bob", CommandBlock_1.Permissions.OWNER);
|
|
61
48
|
// Bob creates a shared object and encrypt it (1 value -> 1 encryption key)
|
|
62
49
|
const sharedObject = {
|
|
63
50
|
name: "Bob",
|
|
@@ -65,14 +52,14 @@ describe("Shared object scenario using StreamTree", () => {
|
|
|
65
52
|
email: "bob@box.com",
|
|
66
53
|
};
|
|
67
54
|
//console.dir(sharedObject, { depth: null });
|
|
68
|
-
const encryptedObject =
|
|
55
|
+
const encryptedObject = await encryptSharedObject(bob, tree, sharedObject);
|
|
69
56
|
// Share the application node with carol
|
|
70
|
-
tree =
|
|
57
|
+
tree = await tree.share(tree.getApplicationRootPath(APPLICATION_ID), alice, (await carol.getPublicKey()).publicKey, "Carol", CommandBlock_1.Permissions.OWNER);
|
|
71
58
|
// Decrypt with Carol
|
|
72
|
-
const decryptedObject =
|
|
59
|
+
const decryptedObject = await decryptSharedObject(carol, tree, encryptedObject);
|
|
73
60
|
//console.dir(encryptedObject, { depth: null });
|
|
74
61
|
//console.dir(decryptedObject, { depth: null });
|
|
75
62
|
expect(decryptedObject).toEqual(sharedObject);
|
|
76
|
-
})
|
|
63
|
+
});
|
|
77
64
|
});
|
|
78
65
|
//# sourceMappingURL=shared_object.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared_object.js","sourceRoot":"","sources":["../../src/__tests__/shared_object.ts"],"names":[],"mappings":";AAAA;;;EAGE
|
|
1
|
+
{"version":3,"file":"shared_object.js","sourceRoot":"","sources":["../../src/__tests__/shared_object.ts"],"names":[],"mappings":"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"}
|
package/lib-es/ApduDevice.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApduDevice.d.ts","sourceRoot":"","sources":["../src/ApduDevice.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ApduDevice.d.ts","sourceRoot":"","sources":["../src/ApduDevice.ts"],"names":[],"mappings":"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"}
|