@freesignal/protocol 0.5.6 → 0.6.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.
@@ -16,7 +16,9 @@
16
16
  * You should have received a copy of the GNU General Public License
17
17
  * along with this program. If not, see <https://www.gnu.org/licenses/>
18
18
  */
19
+ import { IdentityKey, UserId } from "./types";
19
20
  export interface ExportedKeySession {
21
+ identityKey: string;
20
22
  secretKey: string;
21
23
  rootKey?: string;
22
24
  sendingChain?: ExportedKeyChain;
@@ -40,24 +42,21 @@ export declare class KeySession {
40
42
  static readonly version = 1;
41
43
  static readonly info: string;
42
44
  static readonly maxCount = 65536;
43
- readonly id: string;
45
+ readonly identityKey: IdentityKey;
44
46
  private keyPair;
45
47
  private rootKey?;
46
48
  private sendingChain?;
47
49
  private receivingChain?;
48
50
  private nextHeaderKey?;
49
51
  private previousKeys;
50
- constructor(opts?: {
51
- id?: string;
52
+ constructor({ identityKey, secretKey, remoteKey, rootKey }: {
53
+ identityKey: IdentityKey;
52
54
  secretKey?: Uint8Array;
53
55
  remoteKey?: Uint8Array;
54
56
  rootKey?: Uint8Array;
55
57
  });
58
+ get userId(): UserId;
56
59
  private getChain;
57
- getHeaderKeys(): {
58
- readonly sending?: Uint8Array;
59
- readonly receiving?: Uint8Array;
60
- };
61
60
  getSendingKey(): PrivateEncryptionKeys | undefined;
62
61
  getReceivingKey(encryptionKeys: EncryptionKeys): Uint8Array | undefined;
63
62
  /**
@@ -84,8 +83,6 @@ interface ExportedKeyChain {
84
83
  publicKey: string;
85
84
  remoteKey: string;
86
85
  chainKey: string;
87
- nextHeaderKey: string;
88
- headerKey?: string;
89
86
  count: number;
90
87
  previousCount: number;
91
88
  }
@@ -24,40 +24,47 @@ Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.KeySession = void 0;
25
25
  const crypto_1 = __importDefault(require("@freesignal/crypto"));
26
26
  const utils_1 = require("@freesignal/utils");
27
+ const types_1 = require("./types");
27
28
  /**
28
29
  * Represents a secure Double Ratchet session.
29
30
  * Used for forward-secure encryption and decryption of messages.
30
31
  */
31
32
  class KeySession {
32
33
  //headerKey?: Uint8Array, nextHeaderKey?: Uint8Array,
33
- constructor(opts = {}) {
34
- var _a;
34
+ constructor({ identityKey, secretKey, remoteKey, rootKey }) {
35
35
  this.previousKeys = new KeyMap();
36
- this.id = (_a = opts.id) !== null && _a !== void 0 ? _a : crypto_1.default.UUID.generate().toString();
37
- this.keyPair = crypto_1.default.ECDH.keyPair(opts.secretKey);
38
- if (opts.rootKey)
39
- this.rootKey = opts.rootKey;
36
+ this.identityKey = identityKey;
37
+ this.keyPair = crypto_1.default.ECDH.keyPair(secretKey);
38
+ if (rootKey)
39
+ this.rootKey = rootKey;
40
40
  //if (opts.nextHeaderKey)
41
41
  // this.nextHeaderKey = opts.nextHeaderKey;
42
- if (opts.remoteKey) {
43
- this.sendingChain = this.getChain(opts.remoteKey); //, opts.headerKey);
42
+ if (remoteKey) {
43
+ this.sendingChain = this.getChain(remoteKey); //, opts.headerKey);
44
44
  }
45
45
  }
46
- getChain(remoteKey, headerKey, previousCount) {
46
+ get userId() {
47
+ return this.identityKey.userId;
48
+ }
49
+ //headerKey?: Uint8Array,
50
+ getChain(remoteKey, previousCount) {
47
51
  const sharedKey = crypto_1.default.ECDH.scalarMult(this.keyPair.secretKey, remoteKey);
48
52
  if (!this.rootKey)
49
53
  this.rootKey = crypto_1.default.hash(sharedKey);
50
54
  const hashkey = crypto_1.default.hkdf(sharedKey, this.rootKey, KeySession.info, KeySession.keyLength * 3);
51
55
  this.rootKey = hashkey.subarray(0, KeySession.keyLength);
52
- return new KeyChain(this.publicKey, remoteKey, hashkey.subarray(KeySession.keyLength, KeySession.keyLength * 2), hashkey.subarray(KeySession.keyLength * 2), headerKey, previousCount);
56
+ //hashkey.subarray(KeySession.keyLength * 2), headerKey,
57
+ return new KeyChain(this.publicKey, remoteKey, hashkey.subarray(KeySession.keyLength, KeySession.keyLength * 2), previousCount);
53
58
  }
54
- getHeaderKeys() {
55
- var _a, _b, _c, _d, _e;
59
+ /*public getHeaderKeys(): {
60
+ readonly sending?: Uint8Array,
61
+ readonly receiving?: Uint8Array
62
+ } {
56
63
  return {
57
- sending: (_a = this.sendingChain) === null || _a === void 0 ? void 0 : _a.headerKey,
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
59
- };
60
- }
64
+ sending: this.sendingChain?.headerKey,
65
+ receiving: (this.receivingChain?.headerKey ?? this.receivingChain?.nextHeaderKey) ?? this.nextHeaderKey
66
+ }
67
+ }*/
61
68
  getSendingKey() {
62
69
  if (!this.sendingChain)
63
70
  return;
@@ -71,17 +78,19 @@ class KeySession {
71
78
  };
72
79
  }
73
80
  getReceivingKey(encryptionKeys) {
74
- var _a, _b, _c, _d, _e, _f;
81
+ var _a, _b, _c, _d;
75
82
  if (!this.previousKeys.has((0, utils_1.decodeBase64)(encryptionKeys.publicKey) + encryptionKeys.count.toString())) {
76
83
  if (!(0, utils_1.compareBytes)(encryptionKeys.publicKey, (_b = (_a = this.receivingChain) === null || _a === void 0 ? void 0 : _a.remoteKey) !== null && _b !== void 0 ? _b : new Uint8Array())) {
77
84
  while (this.receivingChain && this.receivingChain.count < encryptionKeys.previous) {
78
85
  const key = this.receivingChain.getKey();
79
86
  this.previousKeys.set((0, utils_1.decodeBase64)(this.receivingChain.remoteKey) + this.receivingChain.count.toString(), key);
80
87
  }
81
- this.receivingChain = this.getChain(encryptionKeys.publicKey, (_c = this.nextHeaderKey) !== null && _c !== void 0 ? _c : (_d = this.receivingChain) === null || _d === void 0 ? void 0 : _d.nextHeaderKey);
88
+ //this.nextHeaderKey ?? this.receivingChain?.nextHeaderKey
89
+ this.receivingChain = this.getChain(encryptionKeys.publicKey, (_c = this.receivingChain) === null || _c === void 0 ? void 0 : _c.count);
82
90
  this.nextHeaderKey = undefined;
83
91
  this.keyPair = crypto_1.default.ECDH.keyPair();
84
- this.sendingChain = this.getChain(encryptionKeys.publicKey, (_e = this.sendingChain) === null || _e === void 0 ? void 0 : _e.nextHeaderKey, (_f = this.sendingChain) === null || _f === void 0 ? void 0 : _f.count);
92
+ //this.sendingChain?.nextHeaderKey,
93
+ this.sendingChain = this.getChain(encryptionKeys.publicKey, (_d = this.sendingChain) === null || _d === void 0 ? void 0 : _d.count);
85
94
  }
86
95
  if (!this.receivingChain)
87
96
  throw new Error("Error initializing receivingChain");
@@ -106,6 +115,7 @@ class KeySession {
106
115
  toJSON() {
107
116
  var _a, _b;
108
117
  return {
118
+ identityKey: this.identityKey.toString(),
109
119
  secretKey: (0, utils_1.decodeBase64)(this.keyPair.secretKey),
110
120
  rootKey: this.rootKey ? (0, utils_1.decodeBase64)(this.rootKey) : undefined,
111
121
  sendingChain: (_a = this.sendingChain) === null || _a === void 0 ? void 0 : _a.toJSON(),
@@ -120,7 +130,7 @@ class KeySession {
120
130
  * @returns session with the state parsed.
121
131
  */
122
132
  static from(data) {
123
- const session = new KeySession({ secretKey: (0, utils_1.encodeBase64)(data.secretKey), rootKey: data.rootKey ? (0, utils_1.encodeBase64)(data.rootKey) : undefined });
133
+ const session = new KeySession({ identityKey: types_1.IdentityKey.from(data.identityKey), secretKey: (0, utils_1.encodeBase64)(data.secretKey), rootKey: data.rootKey ? (0, utils_1.encodeBase64)(data.rootKey) : undefined });
124
134
  session.sendingChain = data.sendingChain ? KeyChain.from(data.sendingChain) : undefined;
125
135
  session.receivingChain = data.receivingChain ? KeyChain.from(data.receivingChain) : undefined;
126
136
  session.previousKeys = new KeyMap(data.previousKeys);
@@ -133,12 +143,11 @@ KeySession.version = 1;
133
143
  KeySession.info = "/freesignal/double-ratchet/v0." + KeySession.version;
134
144
  KeySession.maxCount = 65536;
135
145
  class KeyChain {
136
- constructor(publicKey, remoteKey, chainKey, nextHeaderKey, headerKey, previousCount = 0) {
146
+ //public readonly nextHeaderKey: Uint8Array, public readonly headerKey?: Uint8Array,
147
+ constructor(publicKey, remoteKey, chainKey, previousCount = 0) {
137
148
  this.publicKey = publicKey;
138
149
  this.remoteKey = remoteKey;
139
150
  this.chainKey = chainKey;
140
- this.nextHeaderKey = nextHeaderKey;
141
- this.headerKey = headerKey;
142
151
  this.previousCount = previousCount;
143
152
  this._count = 0;
144
153
  }
@@ -160,14 +169,15 @@ class KeyChain {
160
169
  publicKey: (0, utils_1.decodeBase64)(this.publicKey),
161
170
  remoteKey: (0, utils_1.decodeBase64)(this.remoteKey),
162
171
  chainKey: (0, utils_1.decodeBase64)(this.chainKey),
163
- nextHeaderKey: (0, utils_1.decodeBase64)(this.nextHeaderKey),
164
- headerKey: this.headerKey ? (0, utils_1.decodeBase64)(this.headerKey) : undefined,
172
+ //nextHeaderKey: decodeBase64(this.nextHeaderKey),
173
+ //headerKey: this.headerKey ? decodeBase64(this.headerKey) : undefined,
165
174
  count: this.count,
166
175
  previousCount: this.previousCount
167
176
  };
168
177
  }
169
178
  static from(obj) {
170
- const chain = new KeyChain((0, utils_1.encodeBase64)(obj.publicKey), (0, utils_1.encodeBase64)(obj.remoteKey), (0, utils_1.encodeBase64)(obj.chainKey), (0, utils_1.encodeBase64)(obj.nextHeaderKey), obj.headerKey ? (0, utils_1.encodeBase64)(obj.headerKey) : undefined, obj.previousCount);
179
+ //encodeBase64(obj.nextHeaderKey), obj.headerKey ? encodeBase64(obj.headerKey) : undefined,
180
+ const chain = new KeyChain((0, utils_1.encodeBase64)(obj.publicKey), (0, utils_1.encodeBase64)(obj.remoteKey), (0, utils_1.encodeBase64)(obj.chainKey), obj.previousCount);
171
181
  chain._count = obj.count;
172
182
  return chain;
173
183
  }
package/dist/node.d.ts CHANGED
@@ -23,17 +23,16 @@ import { ExportedKeySession, KeySession } from "./double-ratchet";
23
23
  export declare class BootstrapRequest {
24
24
  #private;
25
25
  readonly senderId: UserId | string;
26
- private readonly data;
27
- constructor(senderId: UserId | string, data: KeyExchangeData);
26
+ private readonly datagram;
27
+ constructor(senderId: UserId | string, datagram: Datagram);
28
28
  get status(): "pending" | "accepted" | "denied";
29
- get(): Promise<KeyExchangeData | undefined>;
30
- accept(): Promise<KeyExchangeData | undefined>;
29
+ get(): Promise<Datagram | undefined>;
30
+ accept(): Promise<Datagram | undefined>;
31
31
  deny(): void;
32
32
  }
33
33
  export declare class FreeSignalNode {
34
34
  protected readonly privateIdentityKey: PrivateIdentityKey;
35
35
  protected readonly sessions: SessionMap;
36
- protected readonly users: LocalStorage<string, IdentityKey>;
37
36
  protected readonly bundles: LocalStorage<string, KeyExchangeDataBundle>;
38
37
  protected readonly keyExchange: KeyExchange;
39
38
  protected readonly discovers: Set<string>;
@@ -41,20 +40,21 @@ export declare class FreeSignalNode {
41
40
  constructor(storage: Database<{
42
41
  sessions: LocalStorage<string, ExportedKeySession>;
43
42
  keyExchange: LocalStorage<string, Crypto.KeyPair>;
44
- users: LocalStorage<string, IdentityKey>;
45
43
  bundles: LocalStorage<string, KeyExchangeDataBundle>;
46
44
  bootstraps: LocalStorage<string, BootstrapRequest>;
47
45
  }>, privateIdentityKey?: PrivateIdentityKey);
48
46
  get identityKey(): IdentityKey;
49
47
  get userId(): UserId;
50
48
  onRequest: (request: BootstrapRequest) => void;
51
- getRequest(userId: string): Promise<KeyExchangeData | undefined>;
49
+ getRequest(userId: string): Promise<Datagram | undefined>;
52
50
  protected encrypt(receiverId: string | UserId, protocol: Protocols, data: Uint8Array): Promise<Datagram>;
53
51
  packHandshake(data: KeyExchangeData): Promise<Datagram>;
52
+ packHandshake(receiverId: string | UserId): Promise<Datagram>;
54
53
  packData<T>(receiverId: string | UserId, data: T): Promise<Datagram>;
55
54
  packRelay(receiverId: string | UserId, data: Datagram): Promise<Datagram>;
56
55
  packDiscover(receiverId: string | UserId, discoverId: string | UserId): Promise<Datagram>;
57
56
  packBootstrap(receiverId: string | UserId): Promise<Datagram>;
57
+ packGetBootstrap(receiverId: string | UserId): Promise<Datagram>;
58
58
  protected decrypt(datagram: Datagram): Promise<Uint8Array>;
59
59
  /**
60
60
  * Open the datagram and execute operation of Discover and Handshake.
package/dist/node.js CHANGED
@@ -37,6 +37,9 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
37
37
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
38
38
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
39
39
  };
40
+ var __importDefault = (this && this.__importDefault) || function (mod) {
41
+ return (mod && mod.__esModule) ? mod : { "default": mod };
42
+ };
40
43
  var _BootstrapRequest_status;
41
44
  Object.defineProperty(exports, "__esModule", { value: true });
42
45
  exports.FreeSignalNode = exports.BootstrapRequest = void 0;
@@ -45,10 +48,11 @@ const x3dh_1 = require("./x3dh");
45
48
  const double_ratchet_1 = require("./double-ratchet");
46
49
  const _1 = require(".");
47
50
  const utils_1 = require("@freesignal/utils");
51
+ const crypto_1 = __importDefault(require("@freesignal/crypto"));
48
52
  class BootstrapRequest {
49
- constructor(senderId, data) {
53
+ constructor(senderId, datagram) {
50
54
  this.senderId = senderId;
51
- this.data = data;
55
+ this.datagram = datagram;
52
56
  _BootstrapRequest_status.set(this, 'pending');
53
57
  }
54
58
  get status() {
@@ -56,7 +60,7 @@ class BootstrapRequest {
56
60
  }
57
61
  get() {
58
62
  return __awaiter(this, void 0, void 0, function* () {
59
- return __classPrivateFieldGet(this, _BootstrapRequest_status, "f") === 'accepted' ? this.data : undefined;
63
+ return __classPrivateFieldGet(this, _BootstrapRequest_status, "f") === 'accepted' ? this.datagram : undefined;
60
64
  });
61
65
  }
62
66
  accept() {
@@ -81,7 +85,6 @@ class FreeSignalNode {
81
85
  this.privateIdentityKey = privateIdentityKey !== null && privateIdentityKey !== void 0 ? privateIdentityKey : (0, _1.createIdentity)();
82
86
  this.sessions = new SessionMap(storage.sessions);
83
87
  this.keyExchange = new x3dh_1.KeyExchange(storage.keyExchange, this.privateIdentityKey);
84
- this.users = storage.users;
85
88
  this.bundles = storage.bundles;
86
89
  this.bootstraps = storage.bootstraps;
87
90
  }
@@ -111,21 +114,33 @@ class FreeSignalNode {
111
114
  }
112
115
  packHandshake(data) {
113
116
  return __awaiter(this, void 0, void 0, function* () {
114
- const { session, message, identityKey } = yield this.keyExchange.digestData(data, (0, utils_1.encodeData)(yield this.keyExchange.generateBundle()));
115
- const remoteId = types_1.UserId.fromKey(identityKey);
116
- yield this.users.set(remoteId.toString(), identityKey);
117
- yield this.sessions.set(remoteId.toString(), session);
117
+ var _a;
118
+ if (typeof data === 'string' || data instanceof types_1.UserId) {
119
+ //console.debug("Packing Handshake Ack");
120
+ const userId = data.toString();
121
+ const identityKey = (_a = (yield this.sessions.get(userId))) === null || _a === void 0 ? void 0 : _a.identityKey;
122
+ if (!identityKey)
123
+ throw new Error("Missing user");
124
+ const res = yield this.encrypt(userId, types_1.Protocols.HANDSHAKE, crypto_1.default.ECDH.scalarMult(this.privateIdentityKey.exchangeKey, identityKey.exchangeKey));
125
+ return res;
126
+ }
127
+ //console.debug("Packing Handshake Syn");
128
+ const { session, message } = yield this.keyExchange.digestData(data, (0, utils_1.encodeData)(yield this.keyExchange.generateBundle()));
129
+ yield this.sessions.set(session.userId.toString(), session);
118
130
  return new types_1.Datagram(this.userId.toString(), types_1.UserId.fromKey(data.identityKey).toString(), types_1.Protocols.HANDSHAKE, (0, utils_1.encodeData)(message)).sign(this.privateIdentityKey.signatureKey);
119
131
  });
120
132
  }
121
133
  packData(receiverId, data) {
134
+ //console.debug("Packing Data");
122
135
  return this.encrypt(receiverId, types_1.Protocols.MESSAGE, (0, utils_1.encodeData)(data));
123
136
  }
124
137
  packRelay(receiverId, data) {
138
+ //console.debug("Packing Relay");
125
139
  return this.encrypt(receiverId, types_1.Protocols.RELAY, (0, utils_1.encodeData)(data));
126
140
  }
127
141
  packDiscover(receiverId, discoverId) {
128
142
  return __awaiter(this, void 0, void 0, function* () {
143
+ //console.debug("Packing Discover");
129
144
  if (receiverId instanceof types_1.UserId)
130
145
  receiverId = receiverId.toString();
131
146
  if (discoverId instanceof types_1.UserId)
@@ -140,15 +155,23 @@ class FreeSignalNode {
140
155
  }
141
156
  packBootstrap(receiverId) {
142
157
  return __awaiter(this, void 0, void 0, function* () {
158
+ //console.debug("Packing Bootstrap");
143
159
  return new types_1.Datagram(this.userId.toString(), receiverId.toString(), types_1.Protocols.BOOTSTRAP, (0, utils_1.encodeData)(yield this.keyExchange.generateData()));
144
160
  });
145
161
  }
162
+ packGetBootstrap(receiverId) {
163
+ return __awaiter(this, void 0, void 0, function* () {
164
+ //console.debug("Packing GetBootstrap");
165
+ return new types_1.Datagram(this.userId.toString(), receiverId.toString(), types_1.Protocols.BOOTSTRAP);
166
+ });
167
+ }
146
168
  decrypt(datagram) {
147
169
  return __awaiter(this, void 0, void 0, function* () {
148
- const signatureKey = yield this.users.get(datagram.sender);
149
- if (!signatureKey)
170
+ var _a;
171
+ const identityKey = (_a = (yield this.sessions.get(datagram.sender))) === null || _a === void 0 ? void 0 : _a.identityKey;
172
+ if (!identityKey)
150
173
  throw new Error("User IdentityKey not found");
151
- if (!types_1.Datagram.verify(datagram, signatureKey.signatureKey))
174
+ if (!types_1.Datagram.verify(datagram, identityKey.signatureKey))
152
175
  throw new Error("Signature not verified");
153
176
  const session = yield this.sessions.get(datagram.sender);
154
177
  if (!session)
@@ -168,7 +191,7 @@ class FreeSignalNode {
168
191
  */
169
192
  open(datagram) {
170
193
  return __awaiter(this, void 0, void 0, function* () {
171
- var _a;
194
+ var _a, _b;
172
195
  if (datagram instanceof Uint8Array)
173
196
  datagram = types_1.Datagram.from(datagram);
174
197
  let out = {
@@ -178,24 +201,39 @@ class FreeSignalNode {
178
201
  case types_1.Protocols.HANDSHAKE:
179
202
  if (!datagram.payload)
180
203
  throw new Error("Missing payload");
204
+ if (yield this.sessions.has(datagram.sender)) {
205
+ //console.debug("Opening Handshake Ack");
206
+ const payload = yield this.decrypt(datagram);
207
+ const identityKey = (_a = (yield this.sessions.get(datagram.sender))) === null || _a === void 0 ? void 0 : _a.identityKey;
208
+ if (!identityKey)
209
+ throw new Error("Missing user");
210
+ if (!(0, utils_1.compareBytes)(payload, crypto_1.default.ECDH.scalarMult(this.privateIdentityKey.exchangeKey, identityKey.exchangeKey)))
211
+ throw new Error("Error validating handshake data");
212
+ return out;
213
+ }
214
+ //console.debug("Opening Handshake Syn");
181
215
  const data = (0, utils_1.decodeData)(datagram.payload);
182
216
  if (!types_1.Datagram.verify(datagram, types_1.IdentityKey.from(data.identityKey).signatureKey))
183
217
  throw new Error("Signature not verified");
184
- const { session, identityKey, associatedData } = yield this.keyExchange.digestMessage(data);
185
- const userId = types_1.UserId.fromKey(identityKey);
186
- yield this.users.set(userId.toString(), identityKey);
187
- yield this.sessions.set(userId.toString(), session);
188
- yield this.bundles.set(userId.toString(), (0, utils_1.decodeData)(associatedData));
218
+ const { session, associatedData } = yield this.keyExchange.digestMessage(data);
219
+ yield this.sessions.set(session.userId.toString(), session);
220
+ yield this.bundles.set(session.userId.toString(), (0, utils_1.decodeData)(associatedData));
221
+ out.datagram = yield this.packHandshake(session.userId);
222
+ if (!out.datagram)
223
+ throw new Error("Error during handshake");
189
224
  return out;
190
225
  case types_1.Protocols.MESSAGE:
226
+ //console.debug("Opening Message");
191
227
  out.payload = yield this.decrypt(datagram);
192
228
  return out;
193
229
  case types_1.Protocols.RELAY:
230
+ //console.debug("Opening Relay");
194
231
  out.payload = yield this.decrypt(datagram);
195
232
  return out;
196
233
  case types_1.Protocols.DISCOVER:
234
+ //console.debug("Opening Discover");
197
235
  const message = (0, utils_1.decodeData)(yield this.decrypt(datagram));
198
- if (message.type === types_1.DiscoverType.REQUEST && message.discoverId && !(yield this.users.has(message.discoverId))) {
236
+ if (message.type === types_1.DiscoverType.REQUEST && message.discoverId && !(yield this.sessions.has(message.discoverId))) {
199
237
  let data;
200
238
  if (message.discoverId === this.userId.toString()) {
201
239
  data = yield this.keyExchange.generateData();
@@ -228,18 +266,19 @@ class FreeSignalNode {
228
266
  }
229
267
  return out;
230
268
  case types_1.Protocols.BOOTSTRAP:
269
+ //console.debug("Opening Bootstrap");
231
270
  if (datagram.payload) {
232
271
  const data = (0, utils_1.decodeData)(datagram.payload);
233
272
  if (!(0, utils_1.compareBytes)(types_1.UserId.fromKey(data.identityKey).toBytes(), (0, utils_1.encodeBase64)(datagram.sender)))
234
273
  new Error("Malicious bootstrap request");
235
- const request = new BootstrapRequest(datagram.sender, data);
274
+ const request = new BootstrapRequest(datagram.sender, yield this.packHandshake(data));
236
275
  yield this.bootstraps.set(datagram.sender, request);
237
276
  this.onRequest(request);
238
277
  }
239
278
  ;
240
- const bootstrap = yield ((_a = (yield this.bootstraps.get(datagram.sender))) === null || _a === void 0 ? void 0 : _a.get());
241
- if (bootstrap)
242
- out.datagram = yield this.packHandshake(bootstrap);
279
+ const handshakeDatagram = yield ((_b = (yield this.bootstraps.get(datagram.sender))) === null || _b === void 0 ? void 0 : _b.get());
280
+ if (handshakeDatagram)
281
+ out.datagram = handshakeDatagram;
243
282
  return out;
244
283
  case types_1.Protocols.PING:
245
284
  return out;
package/dist/test.js CHANGED
@@ -18,15 +18,17 @@ 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("Valid bootstrap: ", !!test);
22
- const bobRequest = yield alice.getRequest(bob.userId.toString());
23
- if (!bobRequest)
21
+ const aliceHandshake = yield alice.getRequest(bob.userId.toString());
22
+ if (!aliceHandshake)
24
23
  throw new Error("Bootstrap Failed");
25
- const aliceHandshake = yield alice.packHandshake(bobRequest);
26
- yield bob.open(aliceHandshake);
24
+ const bobHandshake = (yield bob.open(aliceHandshake)).datagram;
25
+ if (!bobHandshake)
26
+ throw new Error("Handshake Failed");
27
+ console.log(!!(yield alice.open(bobHandshake)).header);
27
28
  const first = (yield bob.packData(alice.userId, "Hi Alice!")).toBytes();
28
29
  console.log("Bob: ", (0, utils_1.decodeData)((yield alice.open(first)).payload));
29
30
  const second = yield alice.packData(bob.userId, "Hi Bob!");
31
+ console.log("Test");
30
32
  console.log("Alice: ", (0, utils_1.decodeData)((yield bob.open(second)).payload));
31
33
  const third = yield Promise.all(["How are you?", "How are this days?", "For me it's a good time"].map(msg => bob.packData(alice.userId, msg)));
32
34
  third.forEach((data) => __awaiter(void 0, void 0, void 0, function* () {
package/dist/types.d.ts CHANGED
@@ -29,30 +29,37 @@ export declare class UserId implements Encodable {
29
29
  static fromKey(identityKey: string | Uint8Array | IdentityKey): UserId;
30
30
  static from(userId: string | Uint8Array | UserId): UserId;
31
31
  }
32
- export interface IdentityKey extends Encodable {
32
+ export declare class IdentityKey implements Encodable {
33
+ static readonly keyLength: number;
34
+ static readonly version = 1;
35
+ private static readonly info;
33
36
  readonly info: number;
34
37
  readonly signatureKey: Uint8Array;
35
38
  readonly exchangeKey: Uint8Array;
39
+ constructor(identityKey: IdentityKey | Uint8Array | string);
40
+ get userId(): UserId;
41
+ toBytes(): Uint8Array;
42
+ toString(): string;
43
+ toJSON(): string;
44
+ static from(identityKey: IdentityKey | Uint8Array | string): IdentityKey;
45
+ static from(signatureKey: Uint8Array | string, exchangeKey: Uint8Array | string): IdentityKey;
36
46
  }
37
- export declare namespace IdentityKey {
38
- const keyLength: number;
39
- const version = 1;
40
- function isIdentityKeys(obj: any): boolean;
41
- function from(identityKey: IdentityKey | Uint8Array | string): IdentityKey;
42
- function from(signatureKey: Uint8Array | string, exchangeKey: Uint8Array | string): IdentityKey;
43
- }
44
- export interface PrivateIdentityKey {
47
+ export declare class PrivateIdentityKey implements Encodable {
48
+ static readonly keyLength: number;
49
+ static readonly version = 1;
50
+ private static readonly info;
45
51
  readonly info: number;
46
52
  readonly signatureKey: Uint8Array;
47
53
  readonly exchangeKey: Uint8Array;
48
54
  readonly identityKey: IdentityKey;
49
- }
50
- export declare namespace PrivateIdentityKey {
51
- const keyLength: number;
52
- const version = 1;
53
- function isIdentityKeys(obj: any): boolean;
54
- function from(identityKey: PrivateIdentityKey | Uint8Array | string): PrivateIdentityKey;
55
- function from(signatureKey: Uint8Array | string, exchangeKey: Uint8Array | string): PrivateIdentityKey;
55
+ constructor(privateIdentityKey: PrivateIdentityKey | Uint8Array | string);
56
+ get userId(): string;
57
+ toBytes(): Uint8Array;
58
+ toString(): string;
59
+ toJSON(): string;
60
+ static isIdentityKeys(obj: any): boolean;
61
+ static from(identityKey: PrivateIdentityKey | Uint8Array | string): PrivateIdentityKey;
62
+ static from(signatureKey: Uint8Array | string, exchangeKey: Uint8Array | string): PrivateIdentityKey;
56
63
  }
57
64
  export declare enum DiscoverType {
58
65
  REQUEST = 0,
package/dist/types.js CHANGED
@@ -35,32 +35,66 @@ 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
- function encryptData(session, data) {
39
- //console.log(session.id, ' Sending: ', decodeBase64(session.getHeaderKeys().sending ?? new Uint8Array()));
38
+ /*export function encryptData(session: KeySession, data: Uint8Array): EncryptedData {
40
39
  const key = session.getSendingKey();
41
40
  if (!key)
42
41
  throw new Error("Error generating key");
43
- const nonce = crypto_1.default.randomBytes(EncryptionHeader.nonceLength);
44
- const ciphertext = crypto_1.default.box.encrypt(data, nonce, key.secretKey);
42
+ const nonce = crypto.randomBytes(EncryptionHeader.nonceLength);
43
+ const ciphertext = crypto.box.encrypt(data, nonce, key.secretKey);
45
44
  const headerKey = session.getHeaderKeys().sending;
45
+ //console.debug(session.userId.toString(), "Sending: ", decodeBase64(headerKey ?? new Uint8Array()))
46
46
  let header = new EncryptionHeader(key, nonce).toBytes();
47
- const headerNonce = crypto_1.default.randomBytes(EncryptionHeader.nonceLength);
47
+ const headerNonce = crypto.randomBytes(EncryptionHeader.nonceLength)
48
48
  if (headerKey)
49
- header = crypto_1.default.box.encrypt(header, headerNonce, headerKey);
49
+ header = crypto.box.encrypt(header, headerNonce, headerKey);
50
50
  const test = new EncryptedData(header, headerNonce, ciphertext);
51
51
  return test;
52
52
  }
53
- function decryptData(session, encryptedData) {
54
- //console.log(session.id, ' Receiving: ', decodeBase64(session.getHeaderKeys().receiving ?? new Uint8Array()));
53
+
54
+ export function decryptData(session: KeySession, encryptedData: Uint8Array): Uint8Array {
55
55
  const encrypted = EncryptedData.from(encryptedData);
56
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);
57
+ const nextHeaderKey = session.getHeaderKeys().nextReciving;
58
+ let headerData: Uint8Array | undefined;
59
+ try {
60
+ if (!headerKey)
61
+ throw new Error("Error generating key");
62
+ headerData = crypto.box.decrypt(encrypted.header, encrypted.nonce, headerKey);
60
63
  if (!headerData)
61
64
  throw new Error("Error calculating header");
65
+ //console.debug(session.userId.toString(), "Receiving: ", decodeBase64(session.getHeaderKeys().receiving ?? new Uint8Array()))
66
+ } catch {
67
+ if (!nextHeaderKey)
68
+ throw new Error("Error generating key");
69
+ headerData = crypto.box.decrypt(encrypted.header, encrypted.nonce, nextHeaderKey);
70
+ if (!headerData) {
71
+ //console.debug(session.toJSON());
72
+ throw new Error("Error calculating header");
73
+ }
74
+ //console.debug(session.userId.toString(), "NextReceiving: ", decodeBase64(session.getHeaderKeys().nextReciving ?? new Uint8Array()))
62
75
  }
63
- const header = EncryptionHeader.from(headerData);
76
+ const header = EncryptionHeader.from(headerData!);
77
+ const key = session.getReceivingKey(header);
78
+ if (!key)
79
+ throw new Error("Error calculating key");
80
+ const decrypted = crypto.box.decrypt(encrypted.payload, header.nonce, key);
81
+ if (!decrypted)
82
+ throw new Error("Error decrypting data");
83
+ return decrypted;
84
+ }*/
85
+ function encryptData(session, data) {
86
+ const key = session.getSendingKey();
87
+ if (!key)
88
+ throw new Error("Error generating key");
89
+ const nonce = crypto_1.default.randomBytes(EncryptionHeader.nonceLength);
90
+ const ciphertext = crypto_1.default.box.encrypt(data, nonce, key.secretKey);
91
+ let header = new EncryptionHeader(key, nonce).toBytes();
92
+ const test = new EncryptedData(header, crypto_1.default.randomBytes(EncryptionHeader.nonceLength), ciphertext);
93
+ return test;
94
+ }
95
+ function decryptData(session, encryptedData) {
96
+ const encrypted = EncryptedData.from(encryptedData);
97
+ const header = EncryptionHeader.from(encrypted.header);
64
98
  const key = session.getReceivingKey(header);
65
99
  if (!key)
66
100
  throw new Error("Error calculating key");
@@ -86,8 +120,8 @@ class UserId {
86
120
  static fromKey(identityKey) {
87
121
  if (typeof identityKey === 'string')
88
122
  identityKey = (0, utils_1.encodeBase64)(identityKey);
89
- else if (IdentityKey.isIdentityKeys(identityKey))
90
- identityKey = identityKey.toBytes();
123
+ else if (identityKey instanceof IdentityKey)
124
+ identityKey = (identityKey).toBytes();
91
125
  return new UserId(crypto_1.default.hkdf(identityKey, new Uint8Array(32).fill(0), "/freesignal/userid"));
92
126
  }
93
127
  static from(userId) {
@@ -97,112 +131,101 @@ class UserId {
97
131
  }
98
132
  }
99
133
  exports.UserId = UserId;
100
- var IdentityKey;
101
- (function (IdentityKey) {
102
- IdentityKey.keyLength = crypto_1.default.EdDSA.publicKeyLength + crypto_1.default.ECDH.publicKeyLength + 1;
103
- const info = 0x70;
104
- IdentityKey.version = 1;
105
- class IdentityKeyConstructor {
106
- constructor(identityKey) {
107
- if (identityKey instanceof IdentityKeyConstructor) {
108
- this.info = identityKey.info;
109
- this.signatureKey = identityKey.signatureKey;
110
- this.exchangeKey = identityKey.exchangeKey;
111
- }
112
- else {
113
- if (typeof identityKey === 'string')
114
- identityKey = (0, utils_1.encodeBase64)(identityKey);
115
- if (!isIdentityKeys(identityKey))
116
- throw new Error("Invalid key length");
117
- this.info = identityKey[0];
118
- this.signatureKey = identityKey.subarray(1, crypto_1.default.EdDSA.publicKeyLength + 1);
119
- this.exchangeKey = identityKey.subarray(crypto_1.default.EdDSA.publicKeyLength + 1, IdentityKey.keyLength);
120
- }
121
- }
122
- get userId() {
123
- return UserId.fromKey(this.toBytes()).toString();
124
- }
125
- toBytes() {
126
- return (0, utils_1.concatBytes)((0, utils_1.numberToBytes)(this.info, 1), this.signatureKey, this.exchangeKey);
134
+ class IdentityKey {
135
+ constructor(identityKey) {
136
+ if (identityKey instanceof IdentityKey) {
137
+ this.info = identityKey.info;
138
+ this.signatureKey = identityKey.signatureKey;
139
+ this.exchangeKey = identityKey.exchangeKey;
127
140
  }
128
- toString() {
129
- return (0, utils_1.decodeBase64)(this.toBytes());
130
- }
131
- toJSON() {
132
- return this.toString();
141
+ else {
142
+ if (typeof identityKey === 'string')
143
+ identityKey = (0, utils_1.encodeBase64)(identityKey);
144
+ if (identityKey.length !== IdentityKey.keyLength)
145
+ throw new Error("Invalid key length");
146
+ this.info = identityKey[0];
147
+ this.signatureKey = identityKey.subarray(1, crypto_1.default.EdDSA.publicKeyLength + 1);
148
+ this.exchangeKey = identityKey.subarray(crypto_1.default.EdDSA.publicKeyLength + 1, IdentityKey.keyLength);
133
149
  }
134
150
  }
135
- function isIdentityKeys(obj) {
136
- return (obj instanceof Uint8Array && obj.length === IdentityKey.keyLength) || obj instanceof IdentityKeyConstructor;
151
+ get userId() {
152
+ return UserId.fromKey(this.toBytes());
153
+ }
154
+ toBytes() {
155
+ return (0, utils_1.concatBytes)((0, utils_1.numberToBytes)(this.info, 1), this.signatureKey, this.exchangeKey);
156
+ }
157
+ toString() {
158
+ return (0, utils_1.decodeBase64)(this.toBytes());
159
+ }
160
+ toJSON() {
161
+ return this.toString();
137
162
  }
138
- IdentityKey.isIdentityKeys = isIdentityKeys;
139
- function from(...keys) {
163
+ static from(...keys) {
140
164
  keys = keys.map(key => {
141
- if (key instanceof IdentityKeyConstructor)
165
+ if (key instanceof IdentityKey)
142
166
  return key.toBytes();
143
167
  else if (typeof key === 'string')
144
168
  return (0, utils_1.encodeBase64)(key);
145
169
  else
146
170
  return key;
147
171
  });
148
- return new IdentityKeyConstructor(keys.length === 2 ? (0, utils_1.concatBytes)((0, utils_1.numberToBytes)(info + IdentityKey.version, 1), ...keys) : keys[0]);
149
- }
150
- IdentityKey.from = from;
151
- })(IdentityKey || (exports.IdentityKey = IdentityKey = {}));
152
- var PrivateIdentityKey;
153
- (function (PrivateIdentityKey) {
154
- PrivateIdentityKey.keyLength = crypto_1.default.EdDSA.secretKeyLength + crypto_1.default.ECDH.secretKeyLength + 1;
155
- const info = 0x4E;
156
- PrivateIdentityKey.version = 1;
157
- class PrivateIdentityKeyConstructor {
158
- constructor(privateIdentityKey) {
159
- if (privateIdentityKey instanceof PrivateIdentityKeyConstructor) {
160
- this.info = privateIdentityKey.info;
161
- this.signatureKey = privateIdentityKey.signatureKey;
162
- this.exchangeKey = privateIdentityKey.exchangeKey;
163
- this.identityKey = privateIdentityKey.identityKey;
164
- }
165
- else {
166
- if (typeof privateIdentityKey === 'string')
167
- privateIdentityKey = (0, utils_1.encodeBase64)(privateIdentityKey);
168
- if (!isIdentityKeys(privateIdentityKey))
169
- throw new Error("Invalid key length");
170
- this.info = privateIdentityKey[0];
171
- this.signatureKey = privateIdentityKey.subarray(1, crypto_1.default.EdDSA.secretKeyLength + 1);
172
- this.exchangeKey = privateIdentityKey.subarray(crypto_1.default.EdDSA.secretKeyLength + 1, PrivateIdentityKey.keyLength);
173
- this.identityKey = IdentityKey.from(crypto_1.default.EdDSA.keyPair(this.signatureKey).publicKey, crypto_1.default.ECDH.keyPair(this.exchangeKey).publicKey);
174
- }
175
- }
176
- get userId() {
177
- return UserId.fromKey(this.identityKey.toBytes()).toString();
178
- }
179
- toBytes() {
180
- return (0, utils_1.concatBytes)((0, utils_1.numberToBytes)(this.info, 1), this.signatureKey, this.exchangeKey);
181
- }
182
- toString() {
183
- return (0, utils_1.decodeBase64)(this.toBytes());
172
+ return new IdentityKey(keys.length === 2 ? (0, utils_1.concatBytes)((0, utils_1.numberToBytes)(IdentityKey.info + IdentityKey.version, 1), ...keys) : keys[0]);
173
+ }
174
+ }
175
+ exports.IdentityKey = IdentityKey;
176
+ IdentityKey.keyLength = crypto_1.default.EdDSA.publicKeyLength + crypto_1.default.ECDH.publicKeyLength + 1;
177
+ IdentityKey.version = 1;
178
+ IdentityKey.info = 0x70;
179
+ class PrivateIdentityKey {
180
+ constructor(privateIdentityKey) {
181
+ if (privateIdentityKey instanceof PrivateIdentityKey) {
182
+ this.info = privateIdentityKey.info;
183
+ this.signatureKey = privateIdentityKey.signatureKey;
184
+ this.exchangeKey = privateIdentityKey.exchangeKey;
185
+ this.identityKey = privateIdentityKey.identityKey;
184
186
  }
185
- toJSON() {
186
- return this.toString();
187
+ else {
188
+ if (typeof privateIdentityKey === 'string')
189
+ privateIdentityKey = (0, utils_1.encodeBase64)(privateIdentityKey);
190
+ if (!PrivateIdentityKey.isIdentityKeys(privateIdentityKey))
191
+ throw new Error("Invalid key length");
192
+ this.info = privateIdentityKey[0];
193
+ this.signatureKey = privateIdentityKey.subarray(1, crypto_1.default.EdDSA.secretKeyLength + 1);
194
+ this.exchangeKey = privateIdentityKey.subarray(crypto_1.default.EdDSA.secretKeyLength + 1, PrivateIdentityKey.keyLength);
195
+ this.identityKey = IdentityKey.from(crypto_1.default.EdDSA.keyPair(this.signatureKey).publicKey, crypto_1.default.ECDH.keyPair(this.exchangeKey).publicKey);
187
196
  }
188
197
  }
189
- function isIdentityKeys(obj) {
190
- return (obj instanceof Uint8Array && obj.length === PrivateIdentityKey.keyLength) || obj instanceof PrivateIdentityKeyConstructor;
198
+ get userId() {
199
+ return UserId.fromKey(this.identityKey.toBytes()).toString();
200
+ }
201
+ toBytes() {
202
+ return (0, utils_1.concatBytes)((0, utils_1.numberToBytes)(this.info, 1), this.signatureKey, this.exchangeKey);
203
+ }
204
+ toString() {
205
+ return (0, utils_1.decodeBase64)(this.toBytes());
206
+ }
207
+ toJSON() {
208
+ return this.toString();
209
+ }
210
+ static isIdentityKeys(obj) {
211
+ return (obj instanceof Uint8Array && obj.length === PrivateIdentityKey.keyLength) || obj instanceof PrivateIdentityKey;
191
212
  }
192
- PrivateIdentityKey.isIdentityKeys = isIdentityKeys;
193
- function from(...keys) {
213
+ static from(...keys) {
194
214
  keys = keys.map(key => {
195
- if (key instanceof PrivateIdentityKeyConstructor)
215
+ if (key instanceof PrivateIdentityKey)
196
216
  return key.toBytes();
197
217
  else if (typeof key === 'string')
198
218
  return (0, utils_1.encodeBase64)(key);
199
219
  else
200
220
  return key;
201
221
  });
202
- return new PrivateIdentityKeyConstructor(keys.length === 2 ? (0, utils_1.concatBytes)((0, utils_1.numberToBytes)(info + PrivateIdentityKey.version, 1), ...keys) : keys[0]);
222
+ return new PrivateIdentityKey(keys.length === 2 ? (0, utils_1.concatBytes)((0, utils_1.numberToBytes)(PrivateIdentityKey.info + PrivateIdentityKey.version, 1), ...keys) : keys[0]);
203
223
  }
204
- PrivateIdentityKey.from = from;
205
- })(PrivateIdentityKey || (exports.PrivateIdentityKey = PrivateIdentityKey = {}));
224
+ }
225
+ exports.PrivateIdentityKey = PrivateIdentityKey;
226
+ PrivateIdentityKey.keyLength = crypto_1.default.EdDSA.secretKeyLength + crypto_1.default.ECDH.secretKeyLength + 1;
227
+ PrivateIdentityKey.version = 1;
228
+ PrivateIdentityKey.info = 0x4E;
206
229
  var DiscoverType;
207
230
  (function (DiscoverType) {
208
231
  DiscoverType[DiscoverType["REQUEST"] = 0] = "REQUEST";
package/dist/x3dh.d.ts CHANGED
@@ -38,11 +38,9 @@ export declare class KeyExchange {
38
38
  digestData(message: KeyExchangeData, associatedData?: Uint8Array): Promise<{
39
39
  session: KeySession;
40
40
  message: KeyExchangeSynMessage;
41
- identityKey: IdentityKey;
42
41
  }>;
43
42
  digestMessage(message: KeyExchangeSynMessage): Promise<{
44
43
  session: KeySession;
45
- identityKey: IdentityKey;
46
44
  associatedData: Uint8Array;
47
45
  }>;
48
46
  }
package/dist/x3dh.js CHANGED
@@ -84,6 +84,7 @@ class KeyExchange {
84
84
  }
85
85
  digestData(message, associatedData) {
86
86
  return __awaiter(this, void 0, void 0, function* () {
87
+ //console.debug("Digest Data")
87
88
  const ephemeralKey = crypto_1.default.ECDH.keyPair();
88
89
  const signedPreKey = (0, utils_1.encodeBase64)(message.signedPreKey);
89
90
  const identityKey = types_1.IdentityKey.from(message.identityKey);
@@ -97,9 +98,9 @@ class KeyExchange {
97
98
  ...crypto_1.default.ECDH.scalarMult(ephemeralKey.secretKey, identityKey.exchangeKey),
98
99
  ...crypto_1.default.ECDH.scalarMult(ephemeralKey.secretKey, signedPreKey),
99
100
  ...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 * 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) });
101
+ ]), new Uint8Array(double_ratchet_1.KeySession.keyLength).fill(0), KeyExchange.hkdfInfo, double_ratchet_1.KeySession.keyLength * 3);
102
+ //, headerKey: derivedKey.subarray(KeySession.keyLength, KeySession.keyLength * 2), nextHeaderKey: derivedKey.subarray(KeySession.keyLength * 2)
103
+ const session = new double_ratchet_1.KeySession({ identityKey, remoteKey: identityKey.exchangeKey, rootKey: derivedKey.subarray(0, double_ratchet_1.KeySession.keyLength) });
103
104
  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()));
104
105
  if (!encrypted)
105
106
  throw new Error("Decryption error");
@@ -112,13 +113,13 @@ class KeyExchange {
112
113
  signedPreKeyHash: (0, utils_1.decodeBase64)(signedPreKeyHash),
113
114
  onetimePreKeyHash: (0, utils_1.decodeBase64)(onetimePreKeyHash),
114
115
  associatedData: (0, utils_1.decodeBase64)(encrypted.toBytes())
115
- },
116
- identityKey
116
+ }
117
117
  };
118
118
  });
119
119
  }
120
120
  digestMessage(message) {
121
121
  return __awaiter(this, void 0, void 0, function* () {
122
+ //console.debug("Digest Message")
122
123
  const signedPreKey = yield this.storage.get(message.signedPreKeyHash);
123
124
  const hash = message.signedPreKeyHash.concat(message.onetimePreKeyHash);
124
125
  const onetimePreKey = yield this.storage.get(hash);
@@ -133,9 +134,9 @@ class KeyExchange {
133
134
  ...crypto_1.default.ECDH.scalarMult(this.privateIdentityKey.exchangeKey, ephemeralKey),
134
135
  ...crypto_1.default.ECDH.scalarMult(signedPreKey.secretKey, ephemeralKey),
135
136
  ...onetimePreKey ? crypto_1.default.ECDH.scalarMult(onetimePreKey.secretKey, ephemeralKey) : new Uint8Array()
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
+ ]), new Uint8Array(double_ratchet_1.KeySession.keyLength).fill(0), KeyExchange.hkdfInfo, double_ratchet_1.KeySession.keyLength * 3);
138
+ //nextHeaderKey: derivedKey.subarray(KeySession.keyLength, KeySession.keyLength * 2), headerKey: derivedKey.subarray(KeySession.keyLength * 2)
139
+ const session = new double_ratchet_1.KeySession({ identityKey, secretKey: this.privateIdentityKey.exchangeKey, rootKey: derivedKey.subarray(0, double_ratchet_1.KeySession.keyLength) });
139
140
  const data = (0, types_1.decryptData)(session, (0, utils_1.encodeBase64)(message.associatedData));
140
141
  if (!data)
141
142
  throw new Error("Error decrypting ACK message");
@@ -143,7 +144,6 @@ class KeyExchange {
143
144
  throw new Error("Error verifing Associated Data");
144
145
  return {
145
146
  session,
146
- identityKey,
147
147
  associatedData: data.subarray(64)
148
148
  };
149
149
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freesignal/protocol",
3
- "version": "0.5.6",
3
+ "version": "0.6.1",
4
4
  "description": "Signal Protocol implementation in javascript",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "author": "Christian Braghette",