Skip to content

Commit 3fb04f7

Browse files
committed
Added significantly more documentation to the README
1 parent 454507b commit 3fb04f7

File tree

1 file changed

+338
-3
lines changed

1 file changed

+338
-3
lines changed

README.md

Lines changed: 338 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,366 @@ secrecy protocol that works in synchronous and asynchronous messaging environmen
55
[here](https://github.com/trevp/axolotl/wiki), and the details of the wire format are available
66
[here](https://github.com/WhisperSystems/TextSecure/wiki/ProtocolV2).
77

8-
## Getting started
8+
Currently this implementation only supports version 3 of the protocol.
9+
10+
## Installation
911

1012
### Node.js
1113

14+
Install using npm:
1215
```
1316
$ npm install axolotl
1417
```
1518

19+
and import using `"axolotl"`:
1620
```javascript
1721
var axolotl = require("axolotl");
1822
```
1923

2024
### Browser
2125

26+
Install using bower:
2227
```
2328
$ bower install axolotl
2429
```
2530

26-
With AMD:
31+
and import using AMD:
2732
```javascript
2833
require(["axolotl"], function(axolotl) {
2934

3035
});
3136
```
37+
3238
or without:
3339
```javascript
3440
window.axolotl(...)
35-
```
41+
```
42+
43+
## Getting started
44+
45+
### Dependencies
46+
47+
libaxolotl-javascript depends on [traceur-runtime](https://github.com/google/traceur-compiler) and
48+
[protobuf.js](https://github.com/dcodeIO/ProtoBuf.js). These dependencies are not included in the distributed package.
49+
If you installed libaxolotl-javascript using npm then there is nothing more you need to do - npm will download these
50+
dependencies for you.
51+
52+
If you are using libaxolotl-javascript in the browser, you will have to provide the library's dependencies yourself. If
53+
you're using AMD, then simply provide the location of these dependencies in your AMD configuration. Otherwise, include
54+
the dependencies on the page before including `axolotl.js`.
55+
56+
### The Store interface
57+
58+
You need to provide an implementation of the `Store` interface when instantiating Axolotl. This is an object that
59+
has the following methods.
60+
61+
*Note that all methods may return a Promise if the operation is asynchronous.*
62+
63+
#### getLocalIdentityKeyPair
64+
65+
```
66+
getLocalIdentityKeyPair() → {KeyPair}
67+
```
68+
69+
Get the local identity key pair created at install time. A key pair is a JavaScript object containing the keys `public`
70+
and `private` which correspond to the public and private keys, respectively. These keys are of type ArrayBuffer.
71+
72+
#### getLocalRegistrationId
73+
74+
```
75+
getLocalRegistrationId() → {Number}
76+
```
77+
78+
Get the local registration identifier created at install time.
79+
80+
#### getLocalSignedPreKeyPair
81+
82+
```
83+
getLocalSignedPreKeyPair(signedPreKeyId) → {KeyPair}
84+
```
85+
86+
Get the local signed pre-key pair associated with the `signedPreKeyId`.
87+
88+
##### Parameters
89+
90+
Name|Type|Description
91+
:---|:---|:----------
92+
`signedPreKeyId`|Number|The identifier of the signed pre-key.
93+
94+
#### getLocalPreKeyPair
95+
96+
```
97+
getLocalPreKeyPair(preKeyId) → {KeyPair}
98+
```
99+
100+
Get the local pre-key pair associated with the `preKeyId`.
101+
102+
##### Parameters
103+
104+
Name|Type|Description
105+
:---|:---|:----------
106+
`preKeyId`|Number|The identifier of the pre-key.
107+
108+
#### getRemotePreKeyBundle
109+
110+
```
111+
getRemotePreKeyBundle(remoteIdentity) → {PreKeyBundle}
112+
```
113+
114+
Retrieve a pre-key bundle for a remote identity. This will likely be retrieved from a remote server. A `PreKeyBundle` is
115+
a JavaScript object with the following properties:
116+
117+
Name|Type|Description
118+
:---|:---|:----------
119+
`identityKey`|ArrayBuffer|The remote identity's public key.
120+
`preKeyId`|Number|The identifier of the pre-key included in this bundle.
121+
`preKey`|ArrayBuffer|The public half of the pre-key.
122+
`signedPreKeyId`|Number|The identifier of the signed pre-key included in this bundle.
123+
`signedPreKey`|ArrayBuffer|The public half of the signed pre-key.
124+
`signedPreKeySignature`|ArrayBuffer|The signature associated with the `signedPreKey`.
125+
126+
##### Parameters
127+
128+
Name|Type|Description
129+
:---|:---|:----------
130+
`remoteIdentity`|Identity|The identity of the remote entity. The type is the same as the type you pass to into
131+
the methods on Axolotl.
132+
133+
#### isRemoteIdentityTrusted
134+
135+
```
136+
isRemoteIdentityTrusted(remoteIdentity, identityPublicKey) → {Boolean}
137+
```
138+
139+
Determine if the public key associated with the remote identity is trusted. It is up to the application to determine
140+
an appropriate algorithm for this.
141+
142+
##### Parameters
143+
144+
Name|Type|Description
145+
:---|:---|:----------
146+
`remoteIdentity`|Identity|The identity of the remote entity.
147+
`identityPublicKey`|ArrayBuffer|The purported remote identity's public key.
148+
149+
#### putRemoteIdentity
150+
151+
```
152+
putRemoteIdentity(remoteIdentity, identityPublicKey) → {Void}
153+
```
154+
155+
Store a public key to be associated with the remote identity. This is called when a session is successfully established
156+
and gives the application an opportunity to register trust in the identity.
157+
158+
##### Parameters
159+
160+
Name|Type|Description
161+
:---|:---|:----------
162+
`remoteIdentity`|Identity|The identity of the remote entity.
163+
`identityPublicKey`|ArrayBuffer|The remote identity's public key.
164+
165+
#### hasSession
166+
167+
```
168+
hasSession(identity) → {Boolean}
169+
```
170+
171+
Determine if there is a stored session for the identity.
172+
173+
##### Parameters
174+
175+
Name|Type|Description
176+
:---|:---|:----------
177+
`identity`|Identity|The identity.
178+
179+
#### getSession
180+
181+
```
182+
getSession(identity) → {String}
183+
```
184+
185+
Retrieve the session state associated with the identity.
186+
187+
##### Parameters
188+
189+
Name|Type|Description
190+
:---|:---|:----------
191+
`identity`|Identity|The identity.
192+
193+
#### putSession
194+
195+
```
196+
putSession(identity, sessionState) → {Void}
197+
```
198+
199+
Store the session state along with the identity.
200+
201+
##### Parameters
202+
203+
Name|Type|Description
204+
:---|:---|:----------
205+
`identity`|Identity|The identity.
206+
`sessionState`|String|The serialised session state.
207+
208+
### The Crypto interface
209+
210+
You need to provide an implementation of the `Crypto` interface when instantiating Axolotl. This is an object that
211+
has the following methods.
212+
213+
*Note that all methods may return a Promise if the operation is asynchronous.*
214+
215+
#### generateKeyPair
216+
217+
```
218+
generateKeyPair() → {KeyPair}
219+
```
220+
221+
Generate a fresh, random [Curve25519](http://en.wikipedia.org/wiki/Curve25519) public/private key pair suitable for use
222+
with Diffie-Hellman key agreements. The returned private key should be an ArrayBuffer consisting of 32 bytes. The
223+
returned public key should be an ArrayBuffer consisting of 33 bytes, where the first byte is equal to `0x05`.
224+
225+
#### calculateAgreement
226+
227+
```
228+
calculateAgreement(theirPublicKey, ourPrivateKey) → {ArrayBuffer}
229+
```
230+
231+
Compute a [Curve25519](http://en.wikipedia.org/wiki/Curve25519) Diffie-Hellman key agreement.
232+
233+
##### Parameters
234+
235+
Name|Type|Description
236+
:---|:---|:----------
237+
`theirPublicKey`|ArrayBuffer|Their 33 byte public key.
238+
`ourPrivateKey`|ArrayBuffer|Our 32 byte private key.
239+
240+
#### randomBytes
241+
242+
```
243+
randomBytes(byteCount) → {ArrayBuffer}
244+
```
245+
246+
Generate `byteCount` bytes of cryptographically secure random data and return as an ArrayBuffer.
247+
248+
##### Parameters
249+
250+
Name|Type|Description
251+
:---|:---|:----------
252+
`byteCount`|Number|The number of bytes to generate.
253+
254+
#### sign
255+
256+
```
257+
sign(privateKey, dataToSign) → {ArrayBuffer}
258+
```
259+
260+
Produce an [Ed25519](http://en.wikipedia.org/wiki/EdDSA) signature. The returned signature should be an ArrayBuffer
261+
consisting of 64 bytes.
262+
263+
##### Parameters
264+
265+
Name|Type|Description
266+
:---|:---|:----------
267+
`privateKey`|ArrayBuffer|The 32 byte private key to use to generate the signature.
268+
`dataToSign`|ArrayBuffer|The data to be signed. May be any length.
269+
270+
#### verifySignature
271+
272+
```
273+
verifySignature(publicKey, dataToSign, purportedSignature) → {Boolean}
274+
```
275+
276+
Verify an [Ed25519](http://en.wikipedia.org/wiki/EdDSA) signature.
277+
278+
##### Parameters
279+
280+
Name|Type|Description
281+
:---|:---|:----------
282+
`privateKey`|ArrayBuffer|The 33 byte public half of the key used to produce the signature.
283+
`dataToSign`|ArrayBuffer|The data that was signed. May be any length.
284+
`purportedSignature`|ArrayBuffer|The purported signature to check.
285+
286+
#### hmac
287+
288+
```
289+
hmac(key, data) → {ArrayBuffer}
290+
```
291+
292+
Produce a HMAC-HASH using SHA-256. The returned ArrayBuffer should consist of 32 bytes.
293+
294+
##### Parameters
295+
296+
Name|Type|Description
297+
:---|:---|:----------
298+
`key`|ArrayBuffer|The mac key. May be any length.
299+
`data`|ArrayBuffer|The data to be hashed. May be any length.
300+
301+
#### encrypt
302+
303+
```
304+
encrypt(key, plaintext, iv) → {ArrayBuffer}
305+
```
306+
307+
Encrypt the `plaintext` using AES-256-CBC.
308+
309+
##### Parameters
310+
311+
Name|Type|Description
312+
:---|:---|:----------
313+
`key`|ArrayBuffer|The 32 byte cipher key.
314+
`plaintext`|ArrayBuffer|The data to be encrypted. May be any length.
315+
`iv`|ArrayBuffer|A 16 byte random initialisation vector.
316+
317+
#### decrypt
318+
319+
```
320+
decrypt(key, ciphertext, iv) → {ArrayBuffer}
321+
```
322+
323+
Decrypt the `ciphertext` using AES-256-CBC.
324+
325+
##### Parameters
326+
327+
Name|Type|Description
328+
:---|:---|:----------
329+
`key`|ArrayBuffer|The 32 byte cipher key used to encrypt the data.
330+
`ciphertext`|ArrayBuffer|The data to be decrypted. Should have a length that is a multiple of 16 bytes.
331+
`iv`|ArrayBuffer|The 16 byte initialisation vector used to encrypt the data.
332+
333+
### Using Axolotl
334+
335+
Start by instantiating Axolotl:
336+
337+
```javascript
338+
var axol = axolotl(crypto, store);
339+
```
340+
341+
When your application is first installed, the client will likely need to register with the server. To do this, a number
342+
of data needs to be generated:
343+
344+
```javascript
345+
axol.generateIdentityKeyPair().then(...); // Generate our identity key
346+
axol.generateRegistrationId().then(...); // Generate our registration id
347+
axol.generatePreKeys(0, 100).then(...); // Generate the first set of our pre-keys to send to the server
348+
axol.generateLastResortPreKey().then(...); // Generate our last restore pre-key to send to the server
349+
axol.generateSignedPreKey(identityKeyPair, 1).then(...); // Generate our first signed pre-key to send to the server
350+
```
351+
352+
Once registered, sending messages is very simple:
353+
354+
```javascript
355+
var message = convertStringToBytes("Hello bob");
356+
axol.encryptMessage("bob", message).then(function(ciphertext) {
357+
// Send ciphertext to alice
358+
});
359+
```
360+
361+
and on the receiving side:
362+
363+
```javascript
364+
// When receiving a ciphertext, decide what type it is from the container and then decrypt
365+
axol.decryptPreKeyWhisperMessage("alice", ciphertext).then(function(plaintext) {
366+
console.log(plaintext); // "Hello bob"
367+
});
368+
```
369+
370+
and that's it!

0 commit comments

Comments
 (0)