@@ -31,12 +31,26 @@ const discontinuityBytes = new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0
31
31
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
32
32
0xff ] ) . buffer ;
33
33
34
+ /**
35
+ * A utility class for performing the Axolotl ratcheting.
36
+ *
37
+ * @param {Crypto } crypto
38
+ * @constructor
39
+ */
34
40
function Ratchet ( crypto ) {
35
41
const self = this ;
36
42
37
43
const hkdf = new HKDF ( crypto ) ;
38
44
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 ) {
40
54
var secrets = [ ] ;
41
55
if ( sessionVersion >= 3 ) {
42
56
secrets . push ( discontinuityBytes ) ;
@@ -52,7 +66,18 @@ function Ratchet(crypto) {
52
66
} ;
53
67
} ) ;
54
68
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 ) {
56
81
var sharedSecret = yield crypto . calculateAgreement ( theirEphemeralPublicKey , ourEphemeralPrivateKey ) ;
57
82
var derivedSecretBytes = yield hkdf . deriveSecretsWithSalt ( sharedSecret , rootKey , whisperRatchet ,
58
83
ProtocolConstants . rootKeyByteCount + ProtocolConstants . chainKeyByteCount ) ;
@@ -62,7 +87,29 @@ function Ratchet(crypto) {
62
87
} ;
63
88
} ) ;
64
89
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 ) {
66
113
var messageKey = yield deriveMessageKey ( chainKey ) ;
67
114
var keyMaterialBytes = yield hkdf . deriveSecrets ( messageKey , whisperMessageKeys ,
68
115
ProtocolConstants . cipherKeyByteCount + ProtocolConstants . macKeyByteCount + ProtocolConstants . ivByteCount ) ;
@@ -77,12 +124,6 @@ function Ratchet(crypto) {
77
124
} ;
78
125
} ) ;
79
126
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
-
86
127
var hmacByte = co . wrap ( function * ( key , byte ) {
87
128
return yield crypto . hmac ( key , ArrayBufferUtils . fromByte ( byte ) ) ;
88
129
} ) ;
0 commit comments