-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Both for just encode function as well as an end-to-end test.
- Loading branch information
Showing
1 changed file
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
import { Context } from './Context'; | ||
import { ratchet, importKey } from './crypto-utils'; | ||
|
||
/* | ||
function hexdump(buffer) { | ||
const a = new Uint8Array(buffer); | ||
let s = ''; | ||
for (let i = 0; i < a.byteLength; i++) { | ||
s += '0x'; | ||
s += a[i].toString(16); | ||
s += ' '; | ||
} | ||
return s.trim(); | ||
} | ||
*/ | ||
|
||
/* TODO: more tests | ||
* - delta frames | ||
* - frame header is not encrypted | ||
* - different sendCounts | ||
* - different key length | ||
* - ratcheting in decodeFunction | ||
* etc | ||
*/ | ||
const audioBytes = [ 0xde, 0xad, 0xbe, 0xef ]; | ||
const videoBytes = [ 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef ]; | ||
|
||
describe('E2EE Context', () => { | ||
let sender; | ||
let receiver; | ||
const key = new Uint8Array([ | ||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
]); | ||
|
||
beforeEach(() => { | ||
sender = new Context('sender'); | ||
receiver = new Context('receiver'); | ||
}); | ||
|
||
describe('encode function', () => { | ||
it('with an audio frame', async done => { | ||
const sendController = { | ||
enqueue: encodedFrame => { | ||
const data = new Uint8Array(encodedFrame.data); | ||
|
||
// An audio frame will have an overhead of 6 bytes with this counter and key size: | ||
// 4 bytes truncated signature, counter (1 byte) and 1 byte trailer. | ||
expect(data.byteLength).toEqual(audioBytes.length + 6); | ||
|
||
// TODO: provide test vector and matcher. | ||
done(); | ||
} | ||
}; | ||
const frame = { | ||
data: new Uint8Array(audioBytes).buffer, | ||
type: undefined // type is undefined for audio frames. | ||
}; | ||
|
||
await sender.setKey(key, 0); | ||
await receiver.setKey(key, 0); | ||
await sender.encodeFunction(frame, sendController); | ||
}); | ||
|
||
it('with a video frame', async done => { | ||
const sendController = { | ||
enqueue: encodedFrame => { | ||
const data = new Uint8Array(encodedFrame.data); | ||
|
||
// A video frame will have an overhead of 12 bytes with this counter and key size: | ||
// 10 bytes signature, counter (1 byte) and 1 byte trailer. | ||
|
||
expect(data.byteLength).toEqual(videoBytes.length + 12); | ||
|
||
// TODO: provide test vector and matcher. | ||
done(); | ||
} | ||
}; | ||
const frame = { | ||
data: new Uint8Array(videoBytes).buffer, | ||
type: 'key' | ||
}; | ||
|
||
await sender.setKey(key, 0); | ||
await receiver.setKey(key, 0); | ||
await sender.encodeFunction(frame, sendController); | ||
}); | ||
}); | ||
|
||
describe('end-to-end test', () => { | ||
it('with an audio frame', async done => { | ||
await sender.setKey(key, 0); | ||
await receiver.setKey(key, 0); | ||
const receiveController = { | ||
enqueue: encodedFrame => { | ||
const data = new Uint8Array(encodedFrame.data); | ||
|
||
expect(data.byteLength).toEqual(audioBytes.length); | ||
expect(Array.from(data)).toEqual(audioBytes); | ||
done(); | ||
} | ||
}; | ||
const sendController = { | ||
enqueue: encodedFrame => { | ||
receiver.decodeFunction(encodedFrame, receiveController); | ||
} | ||
}; | ||
const frame = { | ||
data: new Uint8Array(audioBytes).buffer, | ||
type: undefined // type is undefined for audio frames. | ||
}; | ||
|
||
await sender.encodeFunction(frame, sendController); | ||
}); | ||
|
||
it('with a video frame', async done => { | ||
await sender.setKey(key, 0); | ||
await receiver.setKey(key, 0); | ||
const receiveController = { | ||
enqueue: encodedFrame => { | ||
const data = new Uint8Array(encodedFrame.data); | ||
|
||
expect(data.byteLength).toEqual(videoBytes.length); | ||
expect(Array.from(data)).toEqual(videoBytes); | ||
done(); | ||
} | ||
}; | ||
const sendController = { | ||
enqueue: encodedFrame => { | ||
receiver.decodeFunction(encodedFrame, receiveController); | ||
} | ||
}; | ||
const frame = { | ||
data: new Uint8Array(videoBytes).buffer, | ||
type: 'key' | ||
}; | ||
|
||
await sender.encodeFunction(frame, sendController); | ||
}); | ||
|
||
it('the receiver ratchets forward', async done => { | ||
await sender.setKey(key, 0); | ||
await receiver.setKey(key, 0); | ||
|
||
// Ratchet the key. We reimport from the raw bytes. | ||
const material = await importKey(key); | ||
|
||
await sender.setKey(await ratchet(material), 0); | ||
|
||
const receiveController = { | ||
enqueue: encodedFrame => { | ||
const data = new Uint8Array(encodedFrame.data); | ||
|
||
expect(data.byteLength).toEqual(audioBytes.length); | ||
expect(Array.from(data)).toEqual(audioBytes); | ||
done(); | ||
} | ||
}; | ||
const sendController = { | ||
enqueue: encodedFrame => { | ||
receiver.decodeFunction(encodedFrame, receiveController); | ||
} | ||
}; | ||
const frame = { | ||
data: new Uint8Array(audioBytes).buffer, | ||
type: undefined | ||
}; | ||
|
||
await sender.encodeFunction(frame, sendController); | ||
}); | ||
}); | ||
}); |