@ledgerhq/hw-ledger-key-ring-protocol 0.2.1-nightly.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/.eslintrc.js +33 -0
- package/.turbo/turbo-build.log +4 -0
- package/.unimportedrc.json +4 -0
- package/CHANGELOG.md +126 -0
- package/LICENSE.txt +21 -0
- package/README.md +3 -0
- package/jest.config.js +13 -0
- package/lib/ApduDevice.d.ts +99 -0
- package/lib/ApduDevice.d.ts.map +1 -0
- package/lib/ApduDevice.js +532 -0
- package/lib/ApduDevice.js.map +1 -0
- package/lib/BigEndian.d.ts +7 -0
- package/lib/BigEndian.d.ts.map +1 -0
- package/lib/BigEndian.js +26 -0
- package/lib/BigEndian.js.map +1 -0
- package/lib/CommandBlock.d.ts +114 -0
- package/lib/CommandBlock.d.ts.map +1 -0
- package/lib/CommandBlock.js +173 -0
- package/lib/CommandBlock.js.map +1 -0
- package/lib/CommandStream.d.ts +38 -0
- package/lib/CommandStream.d.ts.map +1 -0
- package/lib/CommandStream.js +197 -0
- package/lib/CommandStream.js.map +1 -0
- package/lib/CommandStreamDecoder.d.ts +15 -0
- package/lib/CommandStreamDecoder.d.ts.map +1 -0
- package/lib/CommandStreamDecoder.js +101 -0
- package/lib/CommandStreamDecoder.js.map +1 -0
- package/lib/CommandStreamEncoder.d.ts +16 -0
- package/lib/CommandStreamEncoder.d.ts.map +1 -0
- package/lib/CommandStreamEncoder.js +131 -0
- package/lib/CommandStreamEncoder.js.map +1 -0
- package/lib/CommandStreamJsonifier.d.ts +6 -0
- package/lib/CommandStreamJsonifier.d.ts.map +1 -0
- package/lib/CommandStreamJsonifier.js +75 -0
- package/lib/CommandStreamJsonifier.js.map +1 -0
- package/lib/CommandStreamResolver.d.ts +53 -0
- package/lib/CommandStreamResolver.d.ts.map +1 -0
- package/lib/CommandStreamResolver.js +221 -0
- package/lib/CommandStreamResolver.js.map +1 -0
- package/lib/Crypto.d.ts +38 -0
- package/lib/Crypto.d.ts.map +1 -0
- package/lib/Crypto.js +47 -0
- package/lib/Crypto.js.map +1 -0
- package/lib/Device.d.ts +43 -0
- package/lib/Device.d.ts.map +1 -0
- package/lib/Device.js +203 -0
- package/lib/Device.js.map +1 -0
- package/lib/IndexedTree.d.ts +13 -0
- package/lib/IndexedTree.d.ts.map +1 -0
- package/lib/IndexedTree.js +75 -0
- package/lib/IndexedTree.js.map +1 -0
- package/lib/NobleCrypto.d.ts +41 -0
- package/lib/NobleCrypto.d.ts.map +1 -0
- package/lib/NobleCrypto.js +298 -0
- package/lib/NobleCrypto.js.map +1 -0
- package/lib/PublicKey.d.ts +5 -0
- package/lib/PublicKey.d.ts.map +1 -0
- package/lib/PublicKey.js +10 -0
- package/lib/PublicKey.js.map +1 -0
- package/lib/SeedId.d.ts +80 -0
- package/lib/SeedId.d.ts.map +1 -0
- package/lib/SeedId.js +244 -0
- package/lib/SeedId.js.map +1 -0
- package/lib/StreamTree.d.ts +50 -0
- package/lib/StreamTree.d.ts.map +1 -0
- package/lib/StreamTree.js +169 -0
- package/lib/StreamTree.js.map +1 -0
- package/lib/StreamTreeCipher.d.ts +46 -0
- package/lib/StreamTreeCipher.d.ts.map +1 -0
- package/lib/StreamTreeCipher.js +179 -0
- package/lib/StreamTreeCipher.js.map +1 -0
- package/lib/__tests__/codec.d.ts +2 -0
- package/lib/__tests__/codec.d.ts.map +1 -0
- package/lib/__tests__/codec.js +108 -0
- package/lib/__tests__/codec.js.map +1 -0
- package/lib/__tests__/crypto.d.ts +2 -0
- package/lib/__tests__/crypto.d.ts.map +1 -0
- package/lib/__tests__/crypto.js +46 -0
- package/lib/__tests__/crypto.js.map +1 -0
- package/lib/__tests__/indexed_tree.d.ts +2 -0
- package/lib/__tests__/indexed_tree.d.ts.map +1 -0
- package/lib/__tests__/indexed_tree.js +45 -0
- package/lib/__tests__/indexed_tree.js.map +1 -0
- package/lib/__tests__/key_exchange.d.ts +2 -0
- package/lib/__tests__/key_exchange.d.ts.map +1 -0
- package/lib/__tests__/key_exchange.js +129 -0
- package/lib/__tests__/key_exchange.js.map +1 -0
- package/lib/__tests__/seedId.d.ts +2 -0
- package/lib/__tests__/seedId.d.ts.map +1 -0
- package/lib/__tests__/seedId.js +92 -0
- package/lib/__tests__/seedId.js.map +1 -0
- package/lib/__tests__/shared_object.d.ts +2 -0
- package/lib/__tests__/shared_object.d.ts.map +1 -0
- package/lib/__tests__/shared_object.js +78 -0
- package/lib/__tests__/shared_object.js.map +1 -0
- package/lib/index.d.ts +35 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +81 -0
- package/lib/index.js.map +1 -0
- package/lib/tlv.d.ts +99 -0
- package/lib/tlv.d.ts.map +1 -0
- package/lib/tlv.js +150 -0
- package/lib/tlv.js.map +1 -0
- package/lib-es/ApduDevice.d.ts +99 -0
- package/lib-es/ApduDevice.d.ts.map +1 -0
- package/lib-es/ApduDevice.js +526 -0
- package/lib-es/ApduDevice.js.map +1 -0
- package/lib-es/BigEndian.d.ts +7 -0
- package/lib-es/BigEndian.d.ts.map +1 -0
- package/lib-es/BigEndian.js +23 -0
- package/lib-es/BigEndian.js.map +1 -0
- package/lib-es/CommandBlock.d.ts +114 -0
- package/lib-es/CommandBlock.d.ts.map +1 -0
- package/lib-es/CommandBlock.js +160 -0
- package/lib-es/CommandBlock.js.map +1 -0
- package/lib-es/CommandStream.d.ts +38 -0
- package/lib-es/CommandStream.d.ts.map +1 -0
- package/lib-es/CommandStream.js +189 -0
- package/lib-es/CommandStream.js.map +1 -0
- package/lib-es/CommandStreamDecoder.d.ts +15 -0
- package/lib-es/CommandStreamDecoder.d.ts.map +1 -0
- package/lib-es/CommandStreamDecoder.js +97 -0
- package/lib-es/CommandStreamDecoder.js.map +1 -0
- package/lib-es/CommandStreamEncoder.d.ts +16 -0
- package/lib-es/CommandStreamEncoder.d.ts.map +1 -0
- package/lib-es/CommandStreamEncoder.js +127 -0
- package/lib-es/CommandStreamEncoder.js.map +1 -0
- package/lib-es/CommandStreamJsonifier.d.ts +6 -0
- package/lib-es/CommandStreamJsonifier.d.ts.map +1 -0
- package/lib-es/CommandStreamJsonifier.js +72 -0
- package/lib-es/CommandStreamJsonifier.js.map +1 -0
- package/lib-es/CommandStreamResolver.d.ts +53 -0
- package/lib-es/CommandStreamResolver.d.ts.map +1 -0
- package/lib-es/CommandStreamResolver.js +216 -0
- package/lib-es/CommandStreamResolver.js.map +1 -0
- package/lib-es/Crypto.d.ts +38 -0
- package/lib-es/Crypto.d.ts.map +1 -0
- package/lib-es/Crypto.js +43 -0
- package/lib-es/Crypto.js.map +1 -0
- package/lib-es/Device.d.ts +43 -0
- package/lib-es/Device.d.ts.map +1 -0
- package/lib-es/Device.js +195 -0
- package/lib-es/Device.js.map +1 -0
- package/lib-es/IndexedTree.d.ts +13 -0
- package/lib-es/IndexedTree.d.ts.map +1 -0
- package/lib-es/IndexedTree.js +71 -0
- package/lib-es/IndexedTree.js.map +1 -0
- package/lib-es/NobleCrypto.d.ts +41 -0
- package/lib-es/NobleCrypto.d.ts.map +1 -0
- package/lib-es/NobleCrypto.js +267 -0
- package/lib-es/NobleCrypto.js.map +1 -0
- package/lib-es/PublicKey.d.ts +5 -0
- package/lib-es/PublicKey.d.ts.map +1 -0
- package/lib-es/PublicKey.js +6 -0
- package/lib-es/PublicKey.js.map +1 -0
- package/lib-es/SeedId.d.ts +80 -0
- package/lib-es/SeedId.d.ts.map +1 -0
- package/lib-es/SeedId.js +235 -0
- package/lib-es/SeedId.js.map +1 -0
- package/lib-es/StreamTree.d.ts +50 -0
- package/lib-es/StreamTree.d.ts.map +1 -0
- package/lib-es/StreamTree.js +165 -0
- package/lib-es/StreamTree.js.map +1 -0
- package/lib-es/StreamTreeCipher.d.ts +46 -0
- package/lib-es/StreamTreeCipher.d.ts.map +1 -0
- package/lib-es/StreamTreeCipher.js +175 -0
- package/lib-es/StreamTreeCipher.js.map +1 -0
- package/lib-es/__tests__/codec.d.ts +2 -0
- package/lib-es/__tests__/codec.d.ts.map +1 -0
- package/lib-es/__tests__/codec.js +106 -0
- package/lib-es/__tests__/codec.js.map +1 -0
- package/lib-es/__tests__/crypto.d.ts +2 -0
- package/lib-es/__tests__/crypto.d.ts.map +1 -0
- package/lib-es/__tests__/crypto.js +44 -0
- package/lib-es/__tests__/crypto.js.map +1 -0
- package/lib-es/__tests__/indexed_tree.d.ts +2 -0
- package/lib-es/__tests__/indexed_tree.d.ts.map +1 -0
- package/lib-es/__tests__/indexed_tree.js +43 -0
- package/lib-es/__tests__/indexed_tree.js.map +1 -0
- package/lib-es/__tests__/key_exchange.d.ts +2 -0
- package/lib-es/__tests__/key_exchange.d.ts.map +1 -0
- package/lib-es/__tests__/key_exchange.js +124 -0
- package/lib-es/__tests__/key_exchange.js.map +1 -0
- package/lib-es/__tests__/seedId.d.ts +2 -0
- package/lib-es/__tests__/seedId.d.ts.map +1 -0
- package/lib-es/__tests__/seedId.js +90 -0
- package/lib-es/__tests__/seedId.js.map +1 -0
- package/lib-es/__tests__/shared_object.d.ts +2 -0
- package/lib-es/__tests__/shared_object.d.ts.map +1 -0
- package/lib-es/__tests__/shared_object.js +76 -0
- package/lib-es/__tests__/shared_object.js.map +1 -0
- package/lib-es/index.d.ts +35 -0
- package/lib-es/index.d.ts.map +1 -0
- package/lib-es/index.js +32 -0
- package/lib-es/index.js.map +1 -0
- package/lib-es/tlv.d.ts +99 -0
- package/lib-es/tlv.d.ts.map +1 -0
- package/lib-es/tlv.js +144 -0
- package/lib-es/tlv.js.map +1 -0
- package/package.json +63 -0
- package/src/ApduDevice.ts +692 -0
- package/src/BigEndian.ts +25 -0
- package/src/CommandBlock.ts +247 -0
- package/src/CommandStream.ts +262 -0
- package/src/CommandStreamDecoder.ts +142 -0
- package/src/CommandStreamEncoder.ts +144 -0
- package/src/CommandStreamJsonifier.ts +82 -0
- package/src/CommandStreamResolver.ts +284 -0
- package/src/Crypto.ts +78 -0
- package/src/Device.ts +254 -0
- package/src/IndexedTree.ts +80 -0
- package/src/NobleCrypto.ts +294 -0
- package/src/PublicKey.ts +6 -0
- package/src/SeedId.ts +338 -0
- package/src/StreamTree.ts +212 -0
- package/src/StreamTreeCipher.ts +207 -0
- package/src/__tests__/codec.ts +146 -0
- package/src/__tests__/crypto.ts +44 -0
- package/src/__tests__/indexed_tree.ts +51 -0
- package/src/__tests__/key_exchange.ts +167 -0
- package/src/__tests__/seedId.ts +120 -0
- package/src/__tests__/shared_object.ts +118 -0
- package/src/index.ts +43 -0
- package/src/tlv.ts +210 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { CommandStream, Device } from ".";
|
|
2
|
+
import { IndexedTree } from "./IndexedTree";
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
export interface ApplicationStreams {
|
|
7
|
+
appStream: CommandStream;
|
|
8
|
+
appRootStream: CommandStream;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
export interface StreamTreeCreateOpts {
|
|
14
|
+
topic?: Uint8Array;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
export interface PublishKeyEvent {
|
|
20
|
+
stream: CommandStream;
|
|
21
|
+
encryptedXpriv: Uint8Array;
|
|
22
|
+
groupPublicKey: Uint8Array;
|
|
23
|
+
ephemeralPublicKey: Uint8Array;
|
|
24
|
+
nonce: Uint8Array;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
*/
|
|
29
|
+
export declare class StreamTree {
|
|
30
|
+
private tree;
|
|
31
|
+
constructor(tree: IndexedTree<CommandStream>);
|
|
32
|
+
getApplicationRootPath(applicationId: number, increment?: number): string;
|
|
33
|
+
getPublishKeyEvent(member: Uint8Array, path: number[]): Promise<PublishKeyEvent | null>;
|
|
34
|
+
getChild(path: string | number[]): CommandStream | null;
|
|
35
|
+
getRoot(): CommandStream;
|
|
36
|
+
/**
|
|
37
|
+
* Share a private key with a member
|
|
38
|
+
*/
|
|
39
|
+
share(path: string | number[], owner: Device, member: Uint8Array, name: string, permission: number): Promise<StreamTree>;
|
|
40
|
+
/**
|
|
41
|
+
* Close a stream
|
|
42
|
+
*/
|
|
43
|
+
close(path: string | number[], owner: Device): Promise<StreamTree>;
|
|
44
|
+
update(stream: CommandStream): StreamTree;
|
|
45
|
+
serialize(): Record<string, string>;
|
|
46
|
+
static deserialize(data: Record<string, string>): StreamTree;
|
|
47
|
+
static createNewTree(owner: Device, opts?: StreamTreeCreateOpts): Promise<StreamTree>;
|
|
48
|
+
static from(...streams: CommandStream[]): StreamTree;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=StreamTree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamTree.d.ts","sourceRoot":"","sources":["../src/StreamTree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA8C,MAAM,EAAE,MAAM,GAAG,CAAC;AAEtF,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,aAAa,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,aAAa,CAAC;IACtB,cAAc,EAAE,UAAU,CAAC;IAC3B,cAAc,EAAE,UAAU,CAAC;IAC3B,kBAAkB,EAAE,UAAU,CAAC;IAC/B,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAA6B;gBAE7B,IAAI,EAAE,WAAW,CAAC,aAAa,CAAC;IAOrC,sBAAsB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,GAAE,MAAU,GAAG,MAAM;IAatE,kBAAkB,CAC7B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IA0B3B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,aAAa,GAAG,IAAI;IAUvD,OAAO,IAAI,aAAa;IAI/B;;OAEG;IACU,KAAK,CAChB,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,CAAC;IAsBtB;;OAEG;IACU,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAQxE,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU;IAUzC,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAuB1C,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,UAAU;WAO/C,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,oBAAyB,GAAG,OAAO,CAAC,UAAU,CAAC;IAU/F,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,EAAE,aAAa,EAAE,GAAG,UAAU;CAoBrD"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { CommandStream, CommandStreamDecoder, CommandStreamEncoder } from ".";
|
|
11
|
+
import { crypto, DerivationPath } from "./Crypto";
|
|
12
|
+
import { IndexedTree } from "./IndexedTree";
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
export class StreamTree {
|
|
17
|
+
constructor(tree) {
|
|
18
|
+
if (tree.getValue() === null) {
|
|
19
|
+
throw new Error("Root of the tree cannot be null");
|
|
20
|
+
}
|
|
21
|
+
this.tree = tree;
|
|
22
|
+
}
|
|
23
|
+
getApplicationRootPath(applicationId, increment = 0) {
|
|
24
|
+
var _a;
|
|
25
|
+
// tree index is always 0 in the current implementation
|
|
26
|
+
const treeIndex = 0;
|
|
27
|
+
// for application index, we have key rotation that is possible so we need to find the last index
|
|
28
|
+
const child = (_a = this.tree
|
|
29
|
+
.getChild(DerivationPath.hardenedIndex(treeIndex))) === null || _a === void 0 ? void 0 : _a.getChild(DerivationPath.hardenedIndex(applicationId));
|
|
30
|
+
const applicationIndex = child
|
|
31
|
+
? DerivationPath.reverseHardenedIndex(child.getHighestIndex())
|
|
32
|
+
: 0;
|
|
33
|
+
return `m/${treeIndex}'/${applicationId}'/${applicationIndex + increment}'`;
|
|
34
|
+
}
|
|
35
|
+
getPublishKeyEvent(member, path) {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
// Iterate over the tree from leaf to root
|
|
38
|
+
const leaf = this.tree.findChild(path);
|
|
39
|
+
if (!leaf || leaf.getValue() === null) {
|
|
40
|
+
if (path.length === 0) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return this.getPublishKeyEvent(member, path.slice(0, path.length - 1));
|
|
44
|
+
}
|
|
45
|
+
const resolved = yield leaf.getValue().resolve();
|
|
46
|
+
const key = resolved.getEncryptedKey(member);
|
|
47
|
+
if (!key) {
|
|
48
|
+
if (path.length === 0) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
return this.getPublishKeyEvent(member, path.slice(0, path.length - 1));
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
stream: leaf.getValue(),
|
|
55
|
+
encryptedXpriv: key.encryptedXpriv,
|
|
56
|
+
ephemeralPublicKey: key.ephemeralPublicKey,
|
|
57
|
+
nonce: key.initialiationVector,
|
|
58
|
+
groupPublicKey: resolved.getGroupPublicKey(),
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
getChild(path) {
|
|
63
|
+
const indexes = typeof path === "string" ? DerivationPath.toIndexArray(path) : path;
|
|
64
|
+
const subtree = this.tree.findChild(indexes);
|
|
65
|
+
if (subtree === undefined) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
return subtree.getValue();
|
|
69
|
+
}
|
|
70
|
+
getRoot() {
|
|
71
|
+
return this.tree.getValue();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Share a private key with a member
|
|
75
|
+
*/
|
|
76
|
+
share(path, owner, member, name, permission) {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
const indexes = typeof path === "string" ? DerivationPath.toIndexArray(path) : path;
|
|
79
|
+
let stream = this.getChild(indexes) || new CommandStream();
|
|
80
|
+
if (stream.blocks.length === 0 && indexes.length > 0) {
|
|
81
|
+
const root = yield this.getRoot().getRootHash();
|
|
82
|
+
stream = yield stream
|
|
83
|
+
.edit()
|
|
84
|
+
.derive(indexes)
|
|
85
|
+
.addMember(name, member, permission, true)
|
|
86
|
+
.issue(owner, this, root);
|
|
87
|
+
return this.update(stream);
|
|
88
|
+
}
|
|
89
|
+
else if (stream.blocks.length === 0) {
|
|
90
|
+
throw new Error("StreamTree.share cannot add a member if the root was not previously created");
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const newStream = yield stream.edit().addMember(name, member, permission).issue(owner, this);
|
|
94
|
+
return this.update(newStream);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Close a stream
|
|
100
|
+
*/
|
|
101
|
+
close(path, owner) {
|
|
102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
const indexes = typeof path === "string" ? DerivationPath.toIndexArray(path) : path;
|
|
104
|
+
let stream = this.getChild(indexes) || new CommandStream();
|
|
105
|
+
stream = yield stream.edit().close().issue(owner, this);
|
|
106
|
+
return this.update(stream);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
update(stream) {
|
|
110
|
+
const path = stream.getStreamPath();
|
|
111
|
+
if (path === null)
|
|
112
|
+
throw new Error("Stream path cannot be null");
|
|
113
|
+
const indexes = DerivationPath.toIndexArray(path);
|
|
114
|
+
const newTree = this.tree.updateChild(indexes, stream);
|
|
115
|
+
return new StreamTree(newTree);
|
|
116
|
+
}
|
|
117
|
+
serialize() {
|
|
118
|
+
const streamEntries = serializeTree(this.tree, []);
|
|
119
|
+
const entries = streamEntries.flatMap(([path, stream]) => stream ? [[path, crypto.to_hex(CommandStreamEncoder.encode(stream.blocks))]] : []);
|
|
120
|
+
return Object.fromEntries(entries);
|
|
121
|
+
function serializeTree(tree, path) {
|
|
122
|
+
const stream = tree.getValue();
|
|
123
|
+
const childrens = tree.getChildren();
|
|
124
|
+
return [
|
|
125
|
+
[DerivationPath.toString(path), stream],
|
|
126
|
+
...Array.from(childrens.entries()).flatMap(([index, child]) => serializeTree(child, [...path, index])),
|
|
127
|
+
];
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
static deserialize(data) {
|
|
131
|
+
const streams = Object.values(data).map(data => new CommandStream(CommandStreamDecoder.decode(crypto.from_hex(data))));
|
|
132
|
+
return StreamTree.from(...streams);
|
|
133
|
+
}
|
|
134
|
+
static createNewTree(owner_1) {
|
|
135
|
+
return __awaiter(this, arguments, void 0, function* (owner, opts = {}) {
|
|
136
|
+
let stream = new CommandStream();
|
|
137
|
+
const streamToIssue = stream.edit().seed(opts.topic);
|
|
138
|
+
stream = yield streamToIssue.issue(owner);
|
|
139
|
+
const tree = new IndexedTree(stream);
|
|
140
|
+
return new StreamTree(tree);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
static from(...streams) {
|
|
144
|
+
// Map all stream with their path
|
|
145
|
+
const streamMap = new Map();
|
|
146
|
+
streams.forEach(stream => {
|
|
147
|
+
const path = stream.getStreamPath();
|
|
148
|
+
if (path === null)
|
|
149
|
+
throw new Error("Stream path cannot be null");
|
|
150
|
+
streamMap.set(path, stream);
|
|
151
|
+
});
|
|
152
|
+
// Create tree if the list contains the root
|
|
153
|
+
const root = streamMap.get("");
|
|
154
|
+
if (root === undefined)
|
|
155
|
+
throw new Error("StreamTree.from requires the root of the tree");
|
|
156
|
+
let tree = new IndexedTree(root);
|
|
157
|
+
streamMap.delete("");
|
|
158
|
+
streamMap.forEach((stream, path) => {
|
|
159
|
+
const p = DerivationPath.toIndexArray(path);
|
|
160
|
+
tree = tree.addChild(p, new IndexedTree(stream));
|
|
161
|
+
});
|
|
162
|
+
return new StreamTree(tree);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=StreamTree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamTree.js","sourceRoot":"","sources":["../src/StreamTree.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Device } from ".";
|
|
2
|
+
import { StreamTree } from "./StreamTree";
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
export declare enum StreamTreeCipherMode {
|
|
7
|
+
AES_256_CBC = 0,
|
|
8
|
+
AES_256_GCM = 1
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
export declare class StreamTreeCipher {
|
|
14
|
+
private _mode;
|
|
15
|
+
private _device;
|
|
16
|
+
constructor(mode: StreamTreeCipherMode, device: Device);
|
|
17
|
+
get mode(): StreamTreeCipherMode;
|
|
18
|
+
/**
|
|
19
|
+
* Encrypts a message for a given path in the tree
|
|
20
|
+
* @param tree
|
|
21
|
+
* @param path
|
|
22
|
+
* @param message
|
|
23
|
+
* @param nonce optional nonce to use for the encryption (if null a random nonce will be generated)
|
|
24
|
+
* @returns the encrypted message with the nonce prepended (1 byte for the nonce length + nonce + 33 bytes ephemeral key + encrypted message + 4 bytes checksum)
|
|
25
|
+
* @throws Error if the cipher mode is not implemented
|
|
26
|
+
* @throws Error if the path is not found in the tree and can't be derived from the device
|
|
27
|
+
*/
|
|
28
|
+
encrypt(tree: StreamTree, path: number[], message: Uint8Array, nonce?: Uint8Array | null): Promise<Uint8Array>;
|
|
29
|
+
private getGroupKeypair;
|
|
30
|
+
private encodeData;
|
|
31
|
+
private decodeData;
|
|
32
|
+
/**
|
|
33
|
+
* Decrypts a message for a given path in the tree
|
|
34
|
+
* @param tree
|
|
35
|
+
* @param path
|
|
36
|
+
* @param encrytedPayload
|
|
37
|
+
* @returns the decrypted message
|
|
38
|
+
* @throws Error if the cipher mode is not implemented
|
|
39
|
+
* @throws Error if the path is not found in the tree and can't be derived from the device
|
|
40
|
+
* @throws Error if the checksum is invalid
|
|
41
|
+
*/
|
|
42
|
+
decrypt(tree: StreamTree, path: number[], encrytedPayload: Uint8Array): Promise<Uint8Array>;
|
|
43
|
+
private computeChecksum;
|
|
44
|
+
static create(device: Device, mode?: StreamTreeCipherMode): StreamTreeCipher;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=StreamTreeCipher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamTreeCipher.d.ts","sourceRoot":"","sources":["../src/StreamTreeCipher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,GAAG,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;GAEG;AACH,oBAAY,oBAAoB;IAC9B,WAAW,IAAO;IAClB,WAAW,IAAO;CACnB;AAYD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,OAAO,CAAS;gBAEZ,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM;IAKtD,IAAI,IAAI,IAAI,oBAAoB,CAE/B;IAED;;;;;;;;;OASG;IACG,OAAO,CACX,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,UAAU,EACnB,KAAK,GAAE,UAAU,GAAG,IAAW,GAC9B,OAAO,CAAC,UAAU,CAAC;YAgCR,eAAe;YAmBf,UAAU;IA4BxB,OAAO,CAAC,UAAU;IAkBlB;;;;;;;;;OASG;IACG,OAAO,CACX,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,EAAE,EACd,eAAe,EAAE,UAAU,GAC1B,OAAO,CAAC,UAAU,CAAC;YAgCR,eAAe;IAK7B,MAAM,CAAC,MAAM,CACX,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,oBAAuD,GAC5D,gBAAgB;CAGpB"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { crypto } from ".";
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
export var StreamTreeCipherMode;
|
|
15
|
+
(function (StreamTreeCipherMode) {
|
|
16
|
+
StreamTreeCipherMode[StreamTreeCipherMode["AES_256_CBC"] = 0] = "AES_256_CBC";
|
|
17
|
+
StreamTreeCipherMode[StreamTreeCipherMode["AES_256_GCM"] = 1] = "AES_256_GCM";
|
|
18
|
+
})(StreamTreeCipherMode || (StreamTreeCipherMode = {}));
|
|
19
|
+
const TAG_LENGTH = 16;
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
23
|
+
export class StreamTreeCipher {
|
|
24
|
+
constructor(mode, device) {
|
|
25
|
+
this._mode = mode;
|
|
26
|
+
this._device = device;
|
|
27
|
+
}
|
|
28
|
+
get mode() {
|
|
29
|
+
return this._mode;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Encrypts a message for a given path in the tree
|
|
33
|
+
* @param tree
|
|
34
|
+
* @param path
|
|
35
|
+
* @param message
|
|
36
|
+
* @param nonce optional nonce to use for the encryption (if null a random nonce will be generated)
|
|
37
|
+
* @returns the encrypted message with the nonce prepended (1 byte for the nonce length + nonce + 33 bytes ephemeral key + encrypted message + 4 bytes checksum)
|
|
38
|
+
* @throws Error if the cipher mode is not implemented
|
|
39
|
+
* @throws Error if the path is not found in the tree and can't be derived from the device
|
|
40
|
+
*/
|
|
41
|
+
encrypt(tree_1, path_1, message_1) {
|
|
42
|
+
return __awaiter(this, arguments, void 0, function* (tree, path, message, nonce = null) {
|
|
43
|
+
if (nonce === null) {
|
|
44
|
+
nonce = yield crypto.randomBytes(16);
|
|
45
|
+
}
|
|
46
|
+
// Generate ephemeral key pair
|
|
47
|
+
const ephemeralKeyPair = yield crypto.randomKeypair();
|
|
48
|
+
// Get the group public key
|
|
49
|
+
const groupKeypair = yield this.getGroupKeypair(tree, path);
|
|
50
|
+
// Compute the secret via ECDH
|
|
51
|
+
const secret = yield crypto.ecdh(ephemeralKeyPair, groupKeypair.publicKey);
|
|
52
|
+
let encrypted = new Uint8Array(0);
|
|
53
|
+
switch (this._mode) {
|
|
54
|
+
case StreamTreeCipherMode.AES_256_CBC: {
|
|
55
|
+
encrypted = yield crypto.encrypt(secret, nonce, message);
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
case StreamTreeCipherMode.AES_256_GCM: {
|
|
59
|
+
encrypted = yield crypto.encrypt(secret, nonce, message);
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
default:
|
|
63
|
+
throw new Error("Unknown cipher mode");
|
|
64
|
+
}
|
|
65
|
+
// Serialize encrypted data
|
|
66
|
+
return this.encodeData(ephemeralKeyPair.publicKey, nonce, encrypted, message);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
getGroupKeypair(tree, path) {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
if (!this._device.isPublicKeyAvailable()) {
|
|
72
|
+
throw new Error("Stream tree cipher is only available for software devices");
|
|
73
|
+
}
|
|
74
|
+
const member = yield this._device.getPublicKey();
|
|
75
|
+
const event = yield tree.getPublishKeyEvent(member.publicKey, path);
|
|
76
|
+
if (!event) {
|
|
77
|
+
throw new Error("Cannot find key in the tree for the current device");
|
|
78
|
+
}
|
|
79
|
+
// Compute the relative path from the event to the path parameter
|
|
80
|
+
const privateKey = (yield this._device.readKey(tree, path)).slice(0, 32);
|
|
81
|
+
const publicKey = (yield crypto.keypairFromSecretKey(privateKey)).publicKey;
|
|
82
|
+
return { privateKey, publicKey };
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
encodeData(ephemeralPublicKey, nonce, data, message) {
|
|
86
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
87
|
+
const result = new Uint8Array(1 + 33 + nonce.length + TAG_LENGTH + data.length);
|
|
88
|
+
let offset = 0;
|
|
89
|
+
// Version
|
|
90
|
+
result[offset] = this._mode;
|
|
91
|
+
offset += 1;
|
|
92
|
+
// Ephemeral public key
|
|
93
|
+
result.set(ephemeralPublicKey, offset);
|
|
94
|
+
offset += ephemeralPublicKey.length;
|
|
95
|
+
// Nonce/IV
|
|
96
|
+
result.set(nonce, offset);
|
|
97
|
+
offset += nonce.length;
|
|
98
|
+
// Checksum
|
|
99
|
+
if (this._mode == StreamTreeCipherMode.AES_256_CBC) {
|
|
100
|
+
const checksum = yield this.computeChecksum(message);
|
|
101
|
+
result.set(checksum, offset);
|
|
102
|
+
offset += checksum.length;
|
|
103
|
+
}
|
|
104
|
+
// Encrypted data
|
|
105
|
+
result.set(data, offset);
|
|
106
|
+
return result;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
decodeData(payload) {
|
|
110
|
+
const version = payload[0];
|
|
111
|
+
let offset = 1;
|
|
112
|
+
const ephemeralPublicKey = payload.slice(offset, offset + 33);
|
|
113
|
+
offset += 33;
|
|
114
|
+
const nonce = payload.slice(offset, offset + 16);
|
|
115
|
+
offset += 16;
|
|
116
|
+
const checksum = payload.slice(payload.length - 16, payload.length);
|
|
117
|
+
const encrypted = payload.slice(offset, payload.length - 16);
|
|
118
|
+
return {
|
|
119
|
+
version,
|
|
120
|
+
ephemeralPublicKey,
|
|
121
|
+
nonce,
|
|
122
|
+
encrypted,
|
|
123
|
+
checksum,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Decrypts a message for a given path in the tree
|
|
128
|
+
* @param tree
|
|
129
|
+
* @param path
|
|
130
|
+
* @param encrytedPayload
|
|
131
|
+
* @returns the decrypted message
|
|
132
|
+
* @throws Error if the cipher mode is not implemented
|
|
133
|
+
* @throws Error if the path is not found in the tree and can't be derived from the device
|
|
134
|
+
* @throws Error if the checksum is invalid
|
|
135
|
+
*/
|
|
136
|
+
decrypt(tree, path, encrytedPayload) {
|
|
137
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
138
|
+
const decodedPayload = this.decodeData(encrytedPayload);
|
|
139
|
+
const ephemeralKey = decodedPayload.ephemeralPublicKey;
|
|
140
|
+
const nonce = decodedPayload.nonce;
|
|
141
|
+
const encryptedMessage = decodedPayload.encrypted;
|
|
142
|
+
const checksum = decodedPayload.checksum;
|
|
143
|
+
const sharedKeyPair = yield this.getGroupKeypair(tree, path);
|
|
144
|
+
const secret = yield crypto.ecdh(sharedKeyPair, ephemeralKey);
|
|
145
|
+
let decrypted = new Uint8Array(0);
|
|
146
|
+
switch (this._mode) {
|
|
147
|
+
case StreamTreeCipherMode.AES_256_CBC: {
|
|
148
|
+
decrypted = yield crypto.decrypt(secret, nonce, encryptedMessage);
|
|
149
|
+
const computedChecksum = yield this.computeChecksum(decrypted);
|
|
150
|
+
if (crypto.to_hex(computedChecksum) !== crypto.to_hex(checksum)) {
|
|
151
|
+
throw new Error("Invalid checksum");
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case StreamTreeCipherMode.AES_256_GCM: {
|
|
156
|
+
decrypted = yield crypto.decrypt(secret, nonce, encryptedMessage);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
default:
|
|
160
|
+
throw new Error("Unknown cipher mode");
|
|
161
|
+
}
|
|
162
|
+
return decrypted;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
computeChecksum(message) {
|
|
166
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
167
|
+
const hash = yield crypto.hash(message);
|
|
168
|
+
return hash.slice(0, 16);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
static create(device, mode = StreamTreeCipherMode.AES_256_GCM) {
|
|
172
|
+
return new StreamTreeCipher(mode, device);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=StreamTreeCipher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamTreeCipher.js","sourceRoot":"","sources":["../src/StreamTreeCipher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/__tests__/codec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { AddMember, createCommandBlock, Permissions, PublishKey, Seed, signCommandBlock, } from "../CommandBlock";
|
|
11
|
+
import { TLV } from "../tlv";
|
|
12
|
+
import { CommandStreamDecoder } from "../CommandStreamDecoder";
|
|
13
|
+
import { CommandStreamEncoder } from "../CommandStreamEncoder";
|
|
14
|
+
import { crypto } from "../Crypto";
|
|
15
|
+
import { CommandStream } from "..";
|
|
16
|
+
describe("Encode/Decode command stream tester", () => {
|
|
17
|
+
it("should encode and decode a byte", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
+
const byte = 42;
|
|
19
|
+
let buffer = new Uint8Array();
|
|
20
|
+
buffer = TLV.pushByte(buffer, 42);
|
|
21
|
+
const decoded = TLV.readVarInt(TLV.readTLV(buffer, 0));
|
|
22
|
+
expect(decoded.value).toBe(byte);
|
|
23
|
+
}));
|
|
24
|
+
it("should encode and decode a Int32", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
+
const varint = 0xdeadbeef;
|
|
26
|
+
let buffer = new Uint8Array();
|
|
27
|
+
buffer = TLV.pushInt32(buffer, varint);
|
|
28
|
+
const decoded = TLV.readVarInt(TLV.readTLV(buffer, 0));
|
|
29
|
+
expect(decoded.value).toBe(varint);
|
|
30
|
+
}));
|
|
31
|
+
it("should encode and decode a string", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
32
|
+
const str = "Hello World";
|
|
33
|
+
let buffer = new Uint8Array();
|
|
34
|
+
buffer = TLV.pushString(buffer, str);
|
|
35
|
+
const decoded = TLV.readString(TLV.readTLV(buffer, 0));
|
|
36
|
+
expect(decoded.value).toBe(str);
|
|
37
|
+
}));
|
|
38
|
+
it("should encode and decode a hash", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
+
const hash = yield crypto.hash(new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
|
|
40
|
+
let buffer = new Uint8Array();
|
|
41
|
+
buffer = TLV.pushHash(buffer, hash);
|
|
42
|
+
const decoded = TLV.readHash(TLV.readTLV(buffer, 0));
|
|
43
|
+
expect(crypto.to_hex(decoded.value)).toEqual(crypto.to_hex(hash));
|
|
44
|
+
}));
|
|
45
|
+
it("should encode and decode bytes", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
46
|
+
const bytes = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
|
47
|
+
let buffer = new Uint8Array();
|
|
48
|
+
buffer = TLV.pushBytes(buffer, bytes);
|
|
49
|
+
const decoded = TLV.readBytes(TLV.readTLV(buffer, 0));
|
|
50
|
+
expect(decoded.value).toEqual(bytes);
|
|
51
|
+
}));
|
|
52
|
+
it("should encode and decode a signature", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
53
|
+
const alice = yield crypto.randomKeypair();
|
|
54
|
+
const block = yield signCommandBlock(yield createCommandBlock(alice.publicKey, []), alice.publicKey, alice.privateKey);
|
|
55
|
+
let buffer = new Uint8Array();
|
|
56
|
+
buffer = TLV.pushSignature(buffer, block.signature);
|
|
57
|
+
const decoded = TLV.readSignature(TLV.readTLV(buffer, 0));
|
|
58
|
+
expect(decoded.value).toEqual(block.signature);
|
|
59
|
+
}));
|
|
60
|
+
it("should encode and decode a public key", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
61
|
+
const alice = yield crypto.randomKeypair();
|
|
62
|
+
let buffer = new Uint8Array();
|
|
63
|
+
buffer = TLV.pushPublicKey(buffer, alice.publicKey);
|
|
64
|
+
const decoded = TLV.readPublicKey(TLV.readTLV(buffer, 0));
|
|
65
|
+
expect(decoded.value).toEqual(alice.publicKey);
|
|
66
|
+
}));
|
|
67
|
+
it("should encode and decode a stream. Encoding/Decoding should not alter the stream", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
68
|
+
const alice = yield crypto.randomKeypair();
|
|
69
|
+
const groupPk = yield crypto.randomKeypair();
|
|
70
|
+
const groupChainCode = yield crypto.randomBytes(32);
|
|
71
|
+
const xpriv = new Uint8Array(64);
|
|
72
|
+
const initializationVector = yield crypto.randomBytes(16);
|
|
73
|
+
xpriv.set(groupPk.privateKey);
|
|
74
|
+
xpriv.set(groupChainCode, 32);
|
|
75
|
+
const ephemeralPk = yield crypto.randomKeypair();
|
|
76
|
+
const block1 = yield signCommandBlock(yield createCommandBlock(alice.publicKey, [
|
|
77
|
+
new Seed(yield crypto.randomBytes(16), 0, groupPk.publicKey, initializationVector, xpriv, ephemeralPk.publicKey),
|
|
78
|
+
]), alice.publicKey, alice.privateKey);
|
|
79
|
+
const block2 = yield signCommandBlock(yield createCommandBlock(alice.publicKey, [
|
|
80
|
+
new AddMember("Alice", yield crypto.randomBytes(32), Permissions.OWNER),
|
|
81
|
+
new PublishKey(yield crypto.randomBytes(16), yield crypto.randomBytes(32), yield crypto.randomBytes(32), yield crypto.randomBytes(32)),
|
|
82
|
+
]), alice.publicKey, alice.privateKey);
|
|
83
|
+
const block3 = yield signCommandBlock(yield createCommandBlock(alice.publicKey, []), alice.publicKey, alice.privateKey);
|
|
84
|
+
const stream = [block1, block2, block3];
|
|
85
|
+
const encoded = CommandStreamEncoder.encode(stream);
|
|
86
|
+
const digestEncoded = yield crypto.hash(encoded);
|
|
87
|
+
const decoded = CommandStreamDecoder.decode(encoded);
|
|
88
|
+
const reencoded = CommandStreamEncoder.encode(decoded);
|
|
89
|
+
const digestReencoded = yield crypto.hash(reencoded);
|
|
90
|
+
expect(digestEncoded).toEqual(digestReencoded);
|
|
91
|
+
}));
|
|
92
|
+
it("decodes a specific command stream", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
93
|
+
const tlv = "0101010220824b3168c79e8b61b599751c107117b5c9b647f2b6859de8a245952559707692062102a13e82cd0d2f77d1ab1434d8bd799571e54cd32e1121c5cf82217f8b0b713b6b01010315a8050c800000008000001080000000062103ccf74aa7775b3d39d6cbb0236acee7a7f980b9f6a556a4d814d44b0bd56cb77b05108c51eda6be26623ca919ed17333afcdb054019c0b60ede1692479cc04ce69eae6a0bd51941bab6f044f3dec10c11cf11e6253504d1df6b0aab7dc1996e4eaa7c6f92c29153c59534578901cd7ff4efcea1ae06210268abdb3d49ba4a274ce8660cde0d1eeaf1fea00e281218be775f6b3aefc39756113a040f7765622d746f6f6c732d6563626638062103a270456b0f95714cc61a6473e6b6d8db354a3c377281096bdd2439a5475ecbf80104ffffffff129a05100e5205b4a616b2a4d79b07b4a4932f560540669e741f38fee07956fb0dc0ea9978d55bd5d8424b0d0f66a2c5a45788f92d0ddc283138c7ba62c521de1d604ee7f847c5aed40a11536bbe742af0be8cfd4132062103a270456b0f95714cc61a6473e6b6d8db354a3c377281096bdd2439a5475ecbf80621027003755248202ea8a67d1fcdcd82d7f7022248f3af892fa5307d3ea250dc81050346304402204422a779fd08723d8cba19c0cc11ef7a24f6f1f459cb01598ff1a26f27ea8976022053a554d4f509223f2d08faa5de796fed13a9762f35da08e94884edd1f7c0d015";
|
|
94
|
+
const decoded = CommandStreamDecoder.decode(crypto.from_hex(tlv));
|
|
95
|
+
const stream = new CommandStream(decoded);
|
|
96
|
+
const resolved = yield stream.resolve();
|
|
97
|
+
expect(resolved.getMembersData()).toEqual([
|
|
98
|
+
{
|
|
99
|
+
id: "03a270456b0f95714cc61a6473e6b6d8db354a3c377281096bdd2439a5475ecbf8",
|
|
100
|
+
name: "web-tools-ecbf8",
|
|
101
|
+
permissions: 4294967295,
|
|
102
|
+
},
|
|
103
|
+
]);
|
|
104
|
+
}));
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../src/__tests__/codec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/__tests__/crypto.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { crypto } from "../Crypto";
|
|
11
|
+
describe("Sodium wrapper tester", () => {
|
|
12
|
+
it("should computes the same symetric key with ECDH using two parties", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
const kp1 = yield crypto.randomKeypair();
|
|
14
|
+
const kp2 = yield crypto.randomKeypair();
|
|
15
|
+
const shared1 = yield crypto.ecdh(kp1, kp2.publicKey);
|
|
16
|
+
const shared2 = yield crypto.ecdh(kp2, kp1.publicKey);
|
|
17
|
+
expect(crypto.to_hex(shared1)).toBe(crypto.to_hex(shared2));
|
|
18
|
+
}));
|
|
19
|
+
it("should encrypt a message and decrypt using the same symmetric key", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
+
//const message = "Hello world!"
|
|
21
|
+
const message = yield crypto.randomBytes(64);
|
|
22
|
+
const key = yield crypto.randomBytes(32);
|
|
23
|
+
const nonce = yield crypto.randomBytes(16);
|
|
24
|
+
const encrypted = yield crypto.encrypt(key, nonce, message);
|
|
25
|
+
const decrypted = yield crypto.decrypt(key, nonce, encrypted);
|
|
26
|
+
expect(crypto.to_hex(decrypted)).toBe(crypto.to_hex(message));
|
|
27
|
+
}));
|
|
28
|
+
it("should encrypt user data", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
+
const keypair = yield crypto.randomKeypair();
|
|
30
|
+
const data = yield crypto.randomBytes(64);
|
|
31
|
+
const encrypted = yield crypto.encryptUserData(keypair.privateKey, data);
|
|
32
|
+
const decrypted = yield crypto.decryptUserData(keypair.privateKey, encrypted);
|
|
33
|
+
expect(crypto.to_hex(decrypted)).toBe(crypto.to_hex(data));
|
|
34
|
+
}));
|
|
35
|
+
it("should verify truncated signature by padding 0s from the start", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
+
const hash = crypto.from_hex("19514a2e50bfad4a6de397ebde776191cbb720e8bbfcc3c165385c3664c03341");
|
|
37
|
+
const signature = crypto.from_hex(
|
|
38
|
+
// Here the "S" part of the signature is only 31 bytes long it should be padded with a 0
|
|
39
|
+
"3043022052a82876fcd4d9d8383ce12a7e4d96bb4c1d9e71e857cd087c092b87cec6baeb021f6b86b9a3bab1e7794ca6ef081c66cb6e6dff06cceddbd23e1f25089e311784");
|
|
40
|
+
const issuer = crypto.from_hex("026e7bf1e015da491674be5796b15d6fabd1f454aad478a6a223934e5a872719e0");
|
|
41
|
+
expect(yield crypto.verify(hash, signature, issuer)).toBe(true);
|
|
42
|
+
}));
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=crypto.js.map
|