Skip to content

Commit b782a76

Browse files
committed
Add JSDoc to Ratchet.js
1 parent 15b8eb0 commit b782a76

File tree

3 files changed

+83
-27
lines changed

3 files changed

+83
-27
lines changed

src/Ratchet.js

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,26 @@ const discontinuityBytes = new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0
3131
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3232
0xff]).buffer;
3333

34+
/**
35+
* A utility class for performing the Axolotl ratcheting.
36+
*
37+
* @param {Crypto} crypto
38+
* @constructor
39+
*/
3440
function Ratchet(crypto) {
3541
const self = this;
3642

3743
const hkdf = new HKDF(crypto);
3844

39-
self.deriveInitialRootAndChainKeys = co.wrap(function*(sessionVersion, agreements) {
45+
/**
46+
* Derive the main and sub ratchet states from the shared secrets derived from the handshake.
47+
*
48+
* @method
49+
* @param {number} sessionVersion
50+
* @param {Array.<ArrayBuffer>} agreements - an array of ArrayBuffers containing the shared secrets
51+
* @return {Promise.<Object, Error>} the root and chain keys
52+
*/
53+
this.deriveInitialRootKeyAndChain = co.wrap(function*(sessionVersion, agreements) {
4054
var secrets = [];
4155
if (sessionVersion >= 3) {
4256
secrets.push(discontinuityBytes);
@@ -52,7 +66,18 @@ function Ratchet(crypto) {
5266
};
5367
});
5468

55-
self.deriveNewRootAndChainKeys = co.wrap(function*(rootKey, theirEphemeralPublicKey, ourEphemeralPrivateKey) {
69+
/**
70+
* Derive the next main and sub ratchet states from the previous state.
71+
* <p>
72+
* This method "clicks" the Diffie-Hellman ratchet forwards.
73+
*
74+
* @method
75+
* @param {ArrayBuffer} rootKey - the current root key
76+
* @param {ArrayBuffer} theirEphemeralPublicKey - the receiving ephemeral/ratchet key
77+
* @param {ArrayBuffer} ourEphemeralPrivateKey - our current ephemeral/ratchet key
78+
* @return {Promise.<Object, Error>} the next root and chain keys
79+
*/
80+
this.deriveNextRootKeyAndChain = co.wrap(function*(rootKey, theirEphemeralPublicKey, ourEphemeralPrivateKey) {
5681
var sharedSecret = yield crypto.calculateAgreement(theirEphemeralPublicKey, ourEphemeralPrivateKey);
5782
var derivedSecretBytes = yield hkdf.deriveSecretsWithSalt(sharedSecret, rootKey, whisperRatchet,
5883
ProtocolConstants.rootKeyByteCount + ProtocolConstants.chainKeyByteCount);
@@ -62,7 +87,29 @@ function Ratchet(crypto) {
6287
};
6388
});
6489

65-
self.deriveMessageKeys = co.wrap(function*(chainKey) {
90+
//
91+
/**
92+
* Derive the next sub ratchet state from the previous state.
93+
* <p>
94+
* This method "clicks" the hash iteration ratchet forwards.
95+
*
96+
* @method
97+
* @param {Chain} chain
98+
* @return {Promise.<void, Error>}
99+
*/
100+
this.clickSubRatchet = co.wrap(function*(chain) {
101+
chain.index++;
102+
chain.key = yield deriveNextChainKey(chain.key);
103+
});
104+
105+
/**
106+
* Derive the message keys from the chain key.
107+
*
108+
* @method
109+
* @param {ArrayBuffer} chainKey
110+
* @return {Promise.<object, Error>} an object containing the message keys.
111+
*/
112+
this.deriveMessageKeys = co.wrap(function*(chainKey) {
66113
var messageKey = yield deriveMessageKey(chainKey);
67114
var keyMaterialBytes = yield hkdf.deriveSecrets(messageKey, whisperMessageKeys,
68115
ProtocolConstants.cipherKeyByteCount + ProtocolConstants.macKeyByteCount + ProtocolConstants.ivByteCount);
@@ -77,12 +124,6 @@ function Ratchet(crypto) {
77124
};
78125
});
79126

80-
// "clicks" the hash iteration ratchet forwards
81-
self.clickSubRatchet = co.wrap(function*(chain) {
82-
chain.index++;
83-
chain.key = yield deriveNextChainKey(chain.key);
84-
});
85-
86127
var hmacByte = co.wrap(function*(key, byte) {
87128
return yield crypto.hmac(key, ArrayBufferUtils.fromByte(byte));
88129
});

src/Session.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -320,17 +320,23 @@ function Session(crypto, sessionStateList) {
320320
* @return {Promise.<Chain, Error>} the next chain for decryption
321321
*/
322322
var clickMainRatchet = co.wrap(function*(sessionState, theirEphemeralPublicKey) {
323-
var nextReceivingChain = yield ratchet.deriveNewRootAndChainKeys(sessionState.rootKey, theirEphemeralPublicKey,
324-
sessionState.senderRatchetKeyPair.private);
323+
var {
324+
rootKey: theirRootKey,
325+
chain: nextReceivingChain
326+
} = yield ratchet.deriveNextRootKeyAndChain(sessionState.rootKey, theirEphemeralPublicKey,
327+
sessionState.senderRatchetKeyPair.private);
325328
var ourNewEphemeralKeyPair = yield crypto.generateKeyPair();
326-
var nextSendingChain = yield ratchet.deriveNewRootAndChainKeys(nextReceivingChain.rootKey,
327-
theirEphemeralPublicKey, ourNewEphemeralKeyPair.private);
328-
sessionState.rootKey = nextSendingChain.rootKey;
329-
sessionState.addReceivingChain(theirEphemeralPublicKey, nextReceivingChain.chain);
329+
var {
330+
rootKey,
331+
chain: nextSendingChain
332+
} = yield ratchet.deriveNextRootKeyAndChain(theirRootKey,
333+
theirEphemeralPublicKey, ourNewEphemeralKeyPair.private);
334+
sessionState.rootKey = rootKey;
335+
sessionState.addReceivingChain(theirEphemeralPublicKey, nextReceivingChain);
330336
sessionState.previousCounter = Math.max(sessionState.sendingChain.index - 1, 0);
331-
sessionState.sendingChain = nextSendingChain.chain;
337+
sessionState.sendingChain = nextSendingChain;
332338
sessionState.senderRatchetKeyPair = ourNewEphemeralKeyPair;
333-
return nextReceivingChain.chain;
339+
return nextReceivingChain;
334340
});
335341

336342
Object.freeze(self);

src/SessionFactory.js

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ function SessionFactory(crypto, store) {
122122

123123
var sessionState = yield initializeBobSession(bobParameters);
124124
sessionState.theirBaseKey = message.baseKey;
125-
var { sessionStateList: sessionStateList } = yield getSessionStateListForIdentity(fromIdentity);
125+
var { sessionStateList } = yield getSessionStateListForIdentity(fromIdentity);
126126
sessionStateList.addSessionState(sessionState);
127127
yield sessionStateList.save();
128128
yield store.putRemoteIdentity(fromIdentity, message.identityKey);
@@ -167,19 +167,25 @@ function SessionFactory(crypto, store) {
167167
agreements.push(crypto.calculateAgreement(parameters.theirOneTimePreKey,
168168
parameters.ourBaseKeyPair.private));
169169
}
170-
var receivingChain = yield ratchet.deriveInitialRootAndChainKeys(parameters.sessionVersion, yield agreements);
171-
var sendingChain = yield ratchet.deriveNewRootAndChainKeys(receivingChain.rootKey, parameters.theirRatchetKey,
172-
sendingRatchetKeyPair.private);
170+
var {
171+
rootKey: theirRootKey,
172+
chain: receivingChain
173+
} = yield ratchet.deriveInitialRootKeyAndChain(parameters.sessionVersion, yield agreements);
174+
var {
175+
rootKey,
176+
chain: sendingChain
177+
} = yield ratchet.deriveNextRootKeyAndChain(theirRootKey, parameters.theirRatchetKey,
178+
sendingRatchetKeyPair.private);
173179

174180
var sessionState = new SessionState({
175181
sessionVersion: parameters.sessionVersion,
176182
remoteIdentityKey: parameters.theirIdentityKey,
177183
localIdentityKey: parameters.ourIdentityKeyPair.public,
178-
rootKey: sendingChain.rootKey,
179-
sendingChain: sendingChain.chain,
184+
rootKey: rootKey,
185+
sendingChain: sendingChain,
180186
senderRatchetKeyPair: sendingRatchetKeyPair
181187
});
182-
sessionState.addReceivingChain(parameters.theirRatchetKey, receivingChain.chain);
188+
sessionState.addReceivingChain(parameters.theirRatchetKey, receivingChain);
183189
return sessionState;
184190
});
185191

@@ -195,14 +201,17 @@ function SessionFactory(crypto, store) {
195201
parameters.ourOneTimePreKeyPair.private));
196202
}
197203

198-
var sendingChain = yield ratchet.deriveInitialRootAndChainKeys(parameters.sessionVersion, yield agreements);
204+
var {
205+
rootKey,
206+
chain: sendingChain
207+
} = yield ratchet.deriveInitialRootKeyAndChain(parameters.sessionVersion, yield agreements);
199208

200209
return new SessionState({
201210
sessionVersion: parameters.sessionVersion,
202211
remoteIdentityKey: parameters.theirIdentityKey,
203212
localIdentityKey: parameters.ourIdentityKeyPair.public,
204-
rootKey: sendingChain.rootKey,
205-
sendingChain: sendingChain.chain,
213+
rootKey: rootKey,
214+
sendingChain: sendingChain,
206215
senderRatchetKeyPair: parameters.ourRatchetKeyPair
207216
});
208217
});

0 commit comments

Comments
 (0)