@freesignal/protocol 0.4.7 → 0.5.1
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/dist/double-ratchet.d.ts +0 -2
- package/dist/double-ratchet.js +6 -5
- package/dist/node.js +2 -0
- package/dist/test.js +5 -1
- package/dist/types.d.ts +26 -52
- package/dist/types.js +77 -80
- package/dist/x3dh.js +8 -6
- package/package.json +1 -1
package/dist/double-ratchet.d.ts
CHANGED
package/dist/double-ratchet.js
CHANGED
|
@@ -29,6 +29,7 @@ const utils_1 = require("@freesignal/utils");
|
|
|
29
29
|
* Used for forward-secure encryption and decryption of messages.
|
|
30
30
|
*/
|
|
31
31
|
class KeySession {
|
|
32
|
+
//headerKey?: Uint8Array, nextHeaderKey?: Uint8Array,
|
|
32
33
|
constructor(opts = {}) {
|
|
33
34
|
var _a;
|
|
34
35
|
this.previousKeys = new KeyMap();
|
|
@@ -36,10 +37,10 @@ class KeySession {
|
|
|
36
37
|
this.keyPair = crypto_1.default.ECDH.keyPair(opts.secretKey);
|
|
37
38
|
if (opts.rootKey)
|
|
38
39
|
this.rootKey = opts.rootKey;
|
|
39
|
-
if (opts.nextHeaderKey)
|
|
40
|
-
|
|
40
|
+
//if (opts.nextHeaderKey)
|
|
41
|
+
// this.nextHeaderKey = opts.nextHeaderKey;
|
|
41
42
|
if (opts.remoteKey) {
|
|
42
|
-
this.sendingChain = this.getChain(opts.remoteKey
|
|
43
|
+
this.sendingChain = this.getChain(opts.remoteKey); //, opts.headerKey);
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
getChain(remoteKey, headerKey, previousCount) {
|
|
@@ -51,10 +52,10 @@ class KeySession {
|
|
|
51
52
|
return new KeyChain(this.publicKey, remoteKey, hashkey.subarray(KeySession.keyLength, KeySession.keyLength * 2), hashkey.subarray(KeySession.keyLength * 2), headerKey, previousCount);
|
|
52
53
|
}
|
|
53
54
|
getHeaderKeys() {
|
|
54
|
-
var _a, _b, _c;
|
|
55
|
+
var _a, _b, _c, _d, _e;
|
|
55
56
|
return {
|
|
56
57
|
sending: (_a = this.sendingChain) === null || _a === void 0 ? void 0 : _a.headerKey,
|
|
57
|
-
receiving: (_b = this.
|
|
58
|
+
receiving: (_e = ((_c = (_b = this.receivingChain) === null || _b === void 0 ? void 0 : _b.headerKey) !== null && _c !== void 0 ? _c : (_d = this.receivingChain) === null || _d === void 0 ? void 0 : _d.nextHeaderKey)) !== null && _e !== void 0 ? _e : this.nextHeaderKey
|
|
58
59
|
};
|
|
59
60
|
}
|
|
60
61
|
getSendingKey() {
|
package/dist/node.js
CHANGED
package/dist/test.js
CHANGED
|
@@ -18,7 +18,7 @@ setImmediate(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
18
18
|
const bobBootstrap = yield bob.packBootstrap(alice.userId);
|
|
19
19
|
alice.onRequest = (request) => { request.accept(); };
|
|
20
20
|
const test = (yield alice.open(bobBootstrap)).datagram;
|
|
21
|
-
console.log(
|
|
21
|
+
console.log("Valid bootstrap: ", !!test);
|
|
22
22
|
const bobRequest = yield alice.getRequest(bob.userId.toString());
|
|
23
23
|
if (!bobRequest)
|
|
24
24
|
throw new Error("Bootstrap Failed");
|
|
@@ -34,6 +34,10 @@ setImmediate(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
34
34
|
}));
|
|
35
35
|
const fourth = yield alice.packData(bob.userId, "Not so bad my man");
|
|
36
36
|
console.log("Alice: ", (0, utils_1.decodeData)((yield bob.open(fourth)).payload));
|
|
37
|
+
const fifth = yield Promise.all(["I'm thinking...", "His this secure?"].map(msg => bob.packData(alice.userId, msg)));
|
|
38
|
+
fifth.forEach((data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
+
console.log("Bob: ", (0, utils_1.decodeData)((yield alice.open(data)).payload));
|
|
40
|
+
}));
|
|
37
41
|
//const testone = await Promise.all(Array(400).fill(0).map(() => alice.packData(bob.userId, decodeBase64(crypto.randomBytes(64)))));
|
|
38
42
|
//console.log(((await bob.open(testone[350])).payload));
|
|
39
43
|
}));
|
package/dist/types.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
18
18
|
*/
|
|
19
19
|
import { LocalStorage, Encodable, KeyExchangeData } from "@freesignal/interfaces";
|
|
20
|
-
import { KeySession } from "./double-ratchet";
|
|
20
|
+
import { EncryptionKeys, KeySession } from "./double-ratchet";
|
|
21
21
|
export declare function encryptData(session: KeySession, data: Uint8Array): EncryptedData;
|
|
22
22
|
export declare function decryptData(session: KeySession, encryptedData: Uint8Array): Uint8Array;
|
|
23
23
|
export declare class UserId implements Encodable {
|
|
@@ -130,67 +130,41 @@ export declare class Datagram implements Encodable, DatagramHeader {
|
|
|
130
130
|
static verify(datagram: Datagram, publicKey: Uint8Array): boolean;
|
|
131
131
|
static from(data: Uint8Array | Datagram | string): Datagram;
|
|
132
132
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* The length of the payload.
|
|
140
|
-
*/
|
|
141
|
-
readonly length: number;
|
|
142
|
-
/**
|
|
143
|
-
* Version of the payload.
|
|
144
|
-
*/
|
|
145
|
-
readonly version: number;
|
|
146
|
-
/**
|
|
147
|
-
* The current message count of the sending chain.
|
|
148
|
-
*/
|
|
133
|
+
export declare class EncryptionHeader implements EncryptionKeys, Encodable {
|
|
134
|
+
readonly nonce: Uint8Array;
|
|
135
|
+
static readonly keyLength: number;
|
|
136
|
+
static readonly nonceLength: number;
|
|
137
|
+
static readonly countLength = 2;
|
|
149
138
|
readonly count: number;
|
|
150
|
-
/**
|
|
151
|
-
* The count of the previous sending chain.
|
|
152
|
-
*/
|
|
153
139
|
readonly previous: number;
|
|
154
|
-
/**
|
|
155
|
-
* The sender's public key used for this message.
|
|
156
|
-
*/
|
|
157
140
|
readonly publicKey: Uint8Array;
|
|
158
|
-
|
|
159
|
-
* The nonce used during encryption.
|
|
160
|
-
*/
|
|
161
|
-
readonly nonce: Uint8Array;
|
|
162
|
-
/**
|
|
163
|
-
* The encrypted message content.
|
|
164
|
-
*/
|
|
165
|
-
readonly ciphertext: Uint8Array;
|
|
166
|
-
/**
|
|
167
|
-
* Serializes the payload into a Uint8Array for transport.
|
|
168
|
-
*/
|
|
141
|
+
constructor(keys: EncryptionKeys, nonce: Uint8Array);
|
|
169
142
|
toBytes(): Uint8Array;
|
|
170
|
-
/**
|
|
171
|
-
* Returns the payload as a Base64 string.
|
|
172
|
-
*/
|
|
173
|
-
toString(): string;
|
|
174
|
-
/**
|
|
175
|
-
* Returns the decoded object as a JSON string.
|
|
176
|
-
*/
|
|
177
143
|
toJSON(): {
|
|
178
|
-
version: number;
|
|
179
144
|
count: number;
|
|
180
145
|
previous: number;
|
|
181
146
|
publicKey: string;
|
|
182
|
-
nonce: string;
|
|
183
|
-
ciphertext: string;
|
|
184
147
|
};
|
|
148
|
+
static from(data: Uint8Array | EncryptionHeader): EncryptionHeader;
|
|
185
149
|
}
|
|
186
|
-
export declare
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
150
|
+
export declare class EncryptedData implements Encodable {
|
|
151
|
+
readonly header: Uint8Array;
|
|
152
|
+
readonly nonce: Uint8Array;
|
|
153
|
+
readonly payload: Uint8Array;
|
|
154
|
+
static readonly version = 1;
|
|
155
|
+
static readonly nonceLength: number;
|
|
156
|
+
private _version;
|
|
157
|
+
constructor(header: Uint8Array, nonce: Uint8Array, payload: Uint8Array);
|
|
158
|
+
get version(): number;
|
|
159
|
+
get length(): number;
|
|
160
|
+
toBytes(): Uint8Array;
|
|
161
|
+
toJSON(): {
|
|
162
|
+
version: number;
|
|
163
|
+
header: string;
|
|
164
|
+
nonce: string;
|
|
165
|
+
payload: string;
|
|
166
|
+
};
|
|
167
|
+
static from(data: Uint8Array | EncryptedData): EncryptedData;
|
|
194
168
|
}
|
|
195
169
|
export declare class AsyncMap<K, V> implements LocalStorage<K, V> {
|
|
196
170
|
private readonly map;
|
package/dist/types.js
CHANGED
|
@@ -30,26 +30,41 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
30
30
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
31
31
|
};
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
exports.AsyncMap = exports.EncryptedData = exports.Datagram = exports.DatagramHeader = exports.Protocols = exports.DiscoverType = exports.PrivateIdentityKey = exports.IdentityKey = exports.UserId = void 0;
|
|
33
|
+
exports.AsyncMap = exports.EncryptedData = exports.EncryptionHeader = exports.Datagram = exports.DatagramHeader = exports.Protocols = exports.DiscoverType = exports.PrivateIdentityKey = exports.IdentityKey = exports.UserId = void 0;
|
|
34
34
|
exports.encryptData = encryptData;
|
|
35
35
|
exports.decryptData = decryptData;
|
|
36
36
|
const utils_1 = require("@freesignal/utils");
|
|
37
37
|
const crypto_1 = __importDefault(require("@freesignal/crypto"));
|
|
38
|
-
const double_ratchet_1 = require("./double-ratchet");
|
|
39
38
|
function encryptData(session, data) {
|
|
39
|
+
//console.log(session.id, ' Sending: ', decodeBase64(session.getHeaderKeys().sending ?? new Uint8Array()));
|
|
40
40
|
const key = session.getSendingKey();
|
|
41
41
|
if (!key)
|
|
42
42
|
throw new Error("Error generating key");
|
|
43
|
-
const nonce = crypto_1.default.randomBytes(
|
|
43
|
+
const nonce = crypto_1.default.randomBytes(EncryptionHeader.nonceLength);
|
|
44
44
|
const ciphertext = crypto_1.default.box.encrypt(data, nonce, key.secretKey);
|
|
45
|
-
|
|
45
|
+
const headerKey = session.getHeaderKeys().sending;
|
|
46
|
+
let header = new EncryptionHeader(key, nonce).toBytes();
|
|
47
|
+
const headerNonce = crypto_1.default.randomBytes(EncryptionHeader.nonceLength);
|
|
48
|
+
if (headerKey)
|
|
49
|
+
header = crypto_1.default.box.encrypt(header, headerNonce, headerKey);
|
|
50
|
+
const test = new EncryptedData(header, headerNonce, ciphertext);
|
|
51
|
+
return test;
|
|
46
52
|
}
|
|
47
53
|
function decryptData(session, encryptedData) {
|
|
54
|
+
//console.log(session.id, ' Receiving: ', decodeBase64(session.getHeaderKeys().receiving ?? new Uint8Array()));
|
|
48
55
|
const encrypted = EncryptedData.from(encryptedData);
|
|
49
|
-
const
|
|
56
|
+
const headerKey = session.getHeaderKeys().receiving;
|
|
57
|
+
let headerData = encrypted.header;
|
|
58
|
+
if (headerKey) {
|
|
59
|
+
headerData = crypto_1.default.box.decrypt(headerData, encrypted.nonce, headerKey);
|
|
60
|
+
if (!headerData)
|
|
61
|
+
throw new Error("Error calculating header");
|
|
62
|
+
}
|
|
63
|
+
const header = EncryptionHeader.from(headerData);
|
|
64
|
+
const key = session.getReceivingKey(header);
|
|
50
65
|
if (!key)
|
|
51
66
|
throw new Error("Error calculating key");
|
|
52
|
-
const decrypted = crypto_1.default.box.decrypt(encrypted.
|
|
67
|
+
const decrypted = crypto_1.default.box.decrypt(encrypted.payload, header.nonce, key);
|
|
53
68
|
if (!decrypted)
|
|
54
69
|
throw new Error("Error decrypting data");
|
|
55
70
|
return decrypted;
|
|
@@ -343,91 +358,73 @@ class Datagram {
|
|
|
343
358
|
exports.Datagram = Datagram;
|
|
344
359
|
Datagram.version = 1;
|
|
345
360
|
Datagram.headerOffset = 26 + crypto_1.default.EdDSA.publicKeyLength * 2;
|
|
346
|
-
|
|
347
|
-
(
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
* @returns An instance of `EncryptedPayload`.
|
|
353
|
-
*/
|
|
354
|
-
function from(array) {
|
|
355
|
-
return new EncryptedDataConstructor(array);
|
|
356
|
-
}
|
|
357
|
-
EncryptedData.from = from;
|
|
358
|
-
})(EncryptedData || (exports.EncryptedData = EncryptedData = {}));
|
|
359
|
-
class EncryptedDataConstructor {
|
|
360
|
-
constructor(...arrays) {
|
|
361
|
-
arrays = arrays.filter(value => value !== undefined);
|
|
362
|
-
if (arrays[0] instanceof EncryptedDataConstructor) {
|
|
363
|
-
this.raw = arrays[0].raw;
|
|
364
|
-
return this;
|
|
365
|
-
}
|
|
366
|
-
if (typeof arrays[0] === 'number')
|
|
367
|
-
arrays[0] = (0, utils_1.numberToBytes)(arrays[0], EncryptedDataConstructor.countLength);
|
|
368
|
-
if (typeof arrays[1] === 'number')
|
|
369
|
-
arrays[1] = (0, utils_1.numberToBytes)(arrays[1], EncryptedDataConstructor.countLength);
|
|
370
|
-
if (arrays.length === 6) {
|
|
371
|
-
arrays.unshift(typeof arrays[5] === 'number' ? (0, utils_1.numberToBytes)(arrays[5], 1) : arrays[5]);
|
|
372
|
-
arrays.pop();
|
|
373
|
-
}
|
|
374
|
-
else if (arrays.length > 1) {
|
|
375
|
-
arrays.unshift((0, utils_1.numberToBytes)(double_ratchet_1.KeySession.version, 1));
|
|
376
|
-
}
|
|
377
|
-
this.raw = (0, utils_1.concatBytes)(...arrays);
|
|
378
|
-
}
|
|
379
|
-
get length() { return this.raw.length; }
|
|
380
|
-
get version() { return (0, utils_1.bytesToNumber)(new Uint8Array(this.raw.buffer, ...Offsets.version.get)); }
|
|
381
|
-
get count() { return (0, utils_1.bytesToNumber)(new Uint8Array(this.raw.buffer, ...Offsets.count.get)); }
|
|
382
|
-
get previous() { return (0, utils_1.bytesToNumber)(new Uint8Array(this.raw.buffer, ...Offsets.previous.get)); }
|
|
383
|
-
get publicKey() { return new Uint8Array(this.raw.buffer, ...Offsets.publicKey.get); }
|
|
384
|
-
get nonce() { return new Uint8Array(this.raw.buffer, ...Offsets.nonce.get); }
|
|
385
|
-
get ciphertext() { return new Uint8Array(this.raw.buffer, Offsets.ciphertext.start); }
|
|
386
|
-
toBytes() {
|
|
387
|
-
return this.raw;
|
|
361
|
+
class EncryptionHeader {
|
|
362
|
+
constructor(keys, nonce) {
|
|
363
|
+
this.nonce = nonce;
|
|
364
|
+
this.count = keys.count;
|
|
365
|
+
this.previous = keys.previous;
|
|
366
|
+
this.publicKey = keys.publicKey;
|
|
388
367
|
}
|
|
389
|
-
|
|
390
|
-
return (0, utils_1.
|
|
368
|
+
toBytes() {
|
|
369
|
+
return (0, utils_1.concatBytes)((0, utils_1.numberToBytes)(this.count, EncryptionHeader.countLength), (0, utils_1.numberToBytes)(this.previous, EncryptionHeader.countLength), this.publicKey, this.nonce);
|
|
391
370
|
}
|
|
392
371
|
toJSON() {
|
|
393
372
|
return {
|
|
394
|
-
version: this.version,
|
|
395
373
|
count: this.count,
|
|
396
374
|
previous: this.previous,
|
|
397
|
-
publicKey: (0, utils_1.decodeBase64)(this.publicKey)
|
|
398
|
-
nonce: (0, utils_1.decodeBase64)(this.nonce),
|
|
399
|
-
ciphertext: (0, utils_1.decodeBase64)(this.ciphertext)
|
|
375
|
+
publicKey: (0, utils_1.decodeBase64)(this.publicKey)
|
|
400
376
|
};
|
|
401
377
|
}
|
|
378
|
+
static from(data) {
|
|
379
|
+
if (data instanceof EncryptionHeader)
|
|
380
|
+
data = data.toBytes();
|
|
381
|
+
return new EncryptionHeader({
|
|
382
|
+
count: (0, utils_1.bytesToNumber)(data.subarray(0, EncryptionHeader.countLength)),
|
|
383
|
+
previous: (0, utils_1.bytesToNumber)(data.subarray(EncryptionHeader.countLength, EncryptionHeader.countLength * 2)),
|
|
384
|
+
publicKey: data.subarray(EncryptionHeader.countLength * 2, EncryptionHeader.countLength * 2 + EncryptionHeader.keyLength)
|
|
385
|
+
}, data.subarray(EncryptionHeader.countLength * 2 + EncryptionHeader.keyLength, EncryptionHeader.countLength * 2 + EncryptionHeader.keyLength + EncryptedData.nonceLength));
|
|
386
|
+
}
|
|
402
387
|
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
return
|
|
388
|
+
exports.EncryptionHeader = EncryptionHeader;
|
|
389
|
+
EncryptionHeader.keyLength = crypto_1.default.box.keyLength;
|
|
390
|
+
EncryptionHeader.nonceLength = crypto_1.default.box.nonceLength;
|
|
391
|
+
EncryptionHeader.countLength = 2;
|
|
392
|
+
class EncryptedData {
|
|
393
|
+
constructor(header, nonce, payload) {
|
|
394
|
+
this.header = header;
|
|
395
|
+
this.nonce = nonce;
|
|
396
|
+
this.payload = payload;
|
|
397
|
+
this._version = EncryptedData.version;
|
|
398
|
+
}
|
|
399
|
+
get version() {
|
|
400
|
+
return this._version;
|
|
401
|
+
}
|
|
402
|
+
get length() {
|
|
403
|
+
return this.toBytes().length;
|
|
404
|
+
}
|
|
405
|
+
toBytes() {
|
|
406
|
+
return (0, utils_1.concatBytes)((0, utils_1.numberToBytes)(this._version, 1), (0, utils_1.numberToBytes)(this.header.length, 3), this.header, this.nonce, this.payload);
|
|
407
|
+
}
|
|
408
|
+
toJSON() {
|
|
409
|
+
return {
|
|
410
|
+
version: this._version,
|
|
411
|
+
header: (0, utils_1.decodeBase64)(this.header),
|
|
412
|
+
nonce: (0, utils_1.decodeBase64)(this.nonce),
|
|
413
|
+
payload: (0, utils_1.decodeBase64)(this.payload)
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
static from(data) {
|
|
417
|
+
if (data instanceof EncryptedData)
|
|
418
|
+
data = data.toBytes();
|
|
419
|
+
const headerLength = (0, utils_1.bytesToNumber)(data.subarray(1, 4));
|
|
420
|
+
const obj = new EncryptedData(data.subarray(4, 4 + headerLength), data.subarray(4 + headerLength, 4 + headerLength + this.nonceLength), data.subarray(4 + headerLength + this.nonceLength));
|
|
421
|
+
obj._version = (0, utils_1.bytesToNumber)(data.subarray(0, 1));
|
|
422
|
+
return obj;
|
|
422
423
|
}
|
|
423
424
|
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
Offsets.previous = Offsets.set(Offsets.count.end, EncryptedDataConstructor.countLength);
|
|
428
|
-
Offsets.publicKey = Offsets.set(Offsets.previous.end, EncryptedDataConstructor.publicKeyLength);
|
|
429
|
-
Offsets.nonce = Offsets.set(Offsets.publicKey.end, EncryptedDataConstructor.nonceLength);
|
|
430
|
-
Offsets.ciphertext = Offsets.set(Offsets.nonce.end, undefined);
|
|
425
|
+
exports.EncryptedData = EncryptedData;
|
|
426
|
+
EncryptedData.version = 1;
|
|
427
|
+
EncryptedData.nonceLength = crypto_1.default.box.nonceLength;
|
|
431
428
|
class AsyncMap {
|
|
432
429
|
constructor(iterable) {
|
|
433
430
|
this.map = new Map(iterable);
|
package/dist/x3dh.js
CHANGED
|
@@ -92,13 +92,14 @@ class KeyExchange {
|
|
|
92
92
|
const onetimePreKey = message.onetimePreKey ? (0, utils_1.encodeBase64)(message.onetimePreKey) : undefined;
|
|
93
93
|
const signedPreKeyHash = crypto_1.default.hash(signedPreKey);
|
|
94
94
|
const onetimePreKeyHash = onetimePreKey ? crypto_1.default.hash(onetimePreKey) : new Uint8Array();
|
|
95
|
-
const
|
|
95
|
+
const derivedKey = crypto_1.default.hkdf(new Uint8Array([
|
|
96
96
|
...crypto_1.default.ECDH.scalarMult(this.privateIdentityKey.exchangeKey, signedPreKey),
|
|
97
97
|
...crypto_1.default.ECDH.scalarMult(ephemeralKey.secretKey, identityKey.exchangeKey),
|
|
98
98
|
...crypto_1.default.ECDH.scalarMult(ephemeralKey.secretKey, signedPreKey),
|
|
99
99
|
...onetimePreKey ? crypto_1.default.ECDH.scalarMult(ephemeralKey.secretKey, onetimePreKey) : new Uint8Array()
|
|
100
|
-
]), new Uint8Array(double_ratchet_1.KeySession.keyLength).fill(0), KeyExchange.hkdfInfo, double_ratchet_1.KeySession.keyLength);
|
|
101
|
-
|
|
100
|
+
]), new Uint8Array(double_ratchet_1.KeySession.keyLength).fill(0), KeyExchange.hkdfInfo, double_ratchet_1.KeySession.keyLength * 2);
|
|
101
|
+
//, headerKey: derivedKey.subarray(KeySession.keyLength)
|
|
102
|
+
const session = new double_ratchet_1.KeySession({ remoteKey: identityKey.exchangeKey, rootKey: derivedKey.subarray(0, double_ratchet_1.KeySession.keyLength) });
|
|
102
103
|
const encrypted = (0, types_1.encryptData)(session, (0, utils_1.concatBytes)(crypto_1.default.hash(this.identityKey.toBytes()), crypto_1.default.hash(identityKey.toBytes()), associatedData !== null && associatedData !== void 0 ? associatedData : new Uint8Array()));
|
|
103
104
|
if (!encrypted)
|
|
104
105
|
throw new Error("Decryption error");
|
|
@@ -127,13 +128,14 @@ class KeyExchange {
|
|
|
127
128
|
if (!this.storage.delete(hash))
|
|
128
129
|
throw new Error("Bundle store deleting error");
|
|
129
130
|
const ephemeralKey = (0, utils_1.encodeBase64)(message.ephemeralKey);
|
|
130
|
-
const
|
|
131
|
+
const derivedKey = crypto_1.default.hkdf(new Uint8Array([
|
|
131
132
|
...crypto_1.default.ECDH.scalarMult(signedPreKey.secretKey, identityKey.exchangeKey),
|
|
132
133
|
...crypto_1.default.ECDH.scalarMult(this.privateIdentityKey.exchangeKey, ephemeralKey),
|
|
133
134
|
...crypto_1.default.ECDH.scalarMult(signedPreKey.secretKey, ephemeralKey),
|
|
134
135
|
...onetimePreKey ? crypto_1.default.ECDH.scalarMult(onetimePreKey.secretKey, ephemeralKey) : new Uint8Array()
|
|
135
|
-
]), new Uint8Array(double_ratchet_1.KeySession.keyLength).fill(0), KeyExchange.hkdfInfo, double_ratchet_1.KeySession.keyLength);
|
|
136
|
-
|
|
136
|
+
]), new Uint8Array(double_ratchet_1.KeySession.keyLength).fill(0), KeyExchange.hkdfInfo, double_ratchet_1.KeySession.keyLength * 2);
|
|
137
|
+
//, nextHeaderKey: derivedKey.subarray(KeySession.keyLength)
|
|
138
|
+
const session = new double_ratchet_1.KeySession({ secretKey: this.privateIdentityKey.exchangeKey, rootKey: derivedKey.subarray(0, double_ratchet_1.KeySession.keyLength) });
|
|
137
139
|
const data = (0, types_1.decryptData)(session, (0, utils_1.encodeBase64)(message.associatedData));
|
|
138
140
|
if (!data)
|
|
139
141
|
throw new Error("Error decrypting ACK message");
|