Skip to content

Commit f1a9f89

Browse files
Add backwards compatibility test for encryption (#681)
* createLegacyProvider only takes blockKey * add back compat test * fixtures are exported from cjs file * generate encryption fixtures by version * standard * remove log * close stream properly
1 parent 1575708 commit f1a9f89

File tree

4 files changed

+204
-1
lines changed

4 files changed

+204
-1
lines changed

index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1069,7 +1069,7 @@ class Hypercore extends EventEmitter {
10691069
? encryptionKey
10701070
: getLegacyBlockKey(this.key, encryptionKey, this.core.compat)
10711071

1072-
return HypercoreEncryption.createLegacyProvider(encryptionKey, blockKey)
1072+
return HypercoreEncryption.createLegacyProvider(blockKey)
10731073
}
10741074
}
10751075

test/encryption.js

+80
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
const test = require('brittle')
22
const b4a = require('b4a')
3+
const crypto = require('hypercore-crypto')
34
const HypercoreEncryption = require('hypercore-encryption')
45
const Hypercore = require('..')
56
const { create, createStorage, replicate } = require('./helpers')
67

8+
const fixturesRaw = require('./fixtures/encryption/v11.0.48.cjs')
9+
710
const encryptionKey = b4a.alloc(32, 'hello world')
811

912
test('encrypted append and get', async function (t) {
@@ -273,9 +276,86 @@ test('block encryption module', async function (t) {
273276
}
274277
})
275278

279+
test('encryption backwards compatibility', async function (t) {
280+
const encryptionKey = b4a.alloc(32).fill('encryption key')
281+
282+
const compatKey = crypto.keyPair(b4a.alloc(32, 0))
283+
const defaultKey = crypto.keyPair(b4a.alloc(32, 1))
284+
const blockKey = crypto.keyPair(b4a.alloc(32, 2))
285+
286+
const fixtures = [
287+
getFixture('compat'),
288+
getFixture('default'),
289+
getFixture('default'),
290+
getFixture('block')
291+
]
292+
293+
const compat = await create(t, null, { keyPair: compatKey, encryptionKey, compat: true })
294+
const def = await create(t, null, { keyPair: defaultKey, encryptionKey, isBlockKey: false })
295+
const notBlock = await create(t, null, { keyPair: defaultKey, encryptionKey, isBlockKey: false })
296+
const block = await create(t, null, { keyPair: blockKey, encryptionKey, isBlockKey: true })
297+
298+
await compat.ready()
299+
await def.ready()
300+
await notBlock.ready()
301+
await block.ready()
302+
303+
const largeBlock = Buffer.alloc(512)
304+
for (let i = 0; i < largeBlock.byteLength; i++) largeBlock[i] = i & 0xff
305+
306+
for (let i = 0; i < 10; i++) {
307+
await compat.append('compat test: ' + i.toString())
308+
await def.append('default test: ' + i.toString())
309+
await notBlock.append('default test: ' + i.toString())
310+
await block.append('block test: ' + i.toString())
311+
}
312+
313+
await compat.append(largeBlock.toString('hex'))
314+
await def.append(largeBlock.toString('hex'))
315+
await notBlock.append(largeBlock.toString('hex'))
316+
await block.append(largeBlock.toString('hex'))
317+
318+
// compat
319+
t.comment('test compat mode')
320+
t.is(compat.length, fixtures[0].length)
321+
322+
for (let i = 0; i < compat.length; i++) {
323+
t.alike(await compat.get(i, { raw: true }), fixtures[0][i])
324+
}
325+
326+
// default
327+
t.comment('test default mode')
328+
t.is(def.length, fixtures[1].length)
329+
330+
for (let i = 0; i < def.length; i++) {
331+
t.alike(await def.get(i, { raw: true }), fixtures[1][i])
332+
}
333+
334+
// not block
335+
t.comment('test block false')
336+
t.is(notBlock.length, fixtures[2].length)
337+
338+
for (let i = 0; i < notBlock.length; i++) {
339+
t.alike(await notBlock.get(i, { raw: true }), fixtures[2][i])
340+
}
341+
342+
// compat
343+
t.comment('test block mode')
344+
t.is(block.length, fixtures[3].length)
345+
346+
for (let i = 0; i < block.length; i++) {
347+
t.alike(await block.get(i, { raw: true }), fixtures[3][i])
348+
}
349+
})
350+
276351
function getBlock (core, index) {
277352
const batch = core.core.storage.read()
278353
const b = batch.getBlock(index)
279354
batch.tryFlush()
280355
return b
281356
}
357+
358+
function getFixture (name) {
359+
const blocks = fixturesRaw[name]
360+
return blocks.map(b => b4a.from(b, 'base64'))
361+
}

test/fixtures/encryption/generate.js

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Generate encryption fixtures
2+
3+
const fs = require('fs')
4+
const path = require('path')
5+
const crypto = require('hypercore-crypto')
6+
const tmpDir = require('test-tmp')
7+
8+
const Hypercore = require('../../../')
9+
const { version } = require('../../../package.json')
10+
11+
main()
12+
13+
async function main () {
14+
const encryptionKey = Buffer.alloc(32).fill('encryption key')
15+
16+
const compatKey = crypto.keyPair(Buffer.alloc(32, 0))
17+
const defaultKey = crypto.keyPair(Buffer.alloc(32, 1))
18+
const blockKey = crypto.keyPair(Buffer.alloc(32, 2))
19+
20+
const closing = []
21+
22+
const compat = new Hypercore(await tmpDir({ teardown }), { keyPair: compatKey, encryptionKey, compat: true })
23+
const def = new Hypercore(await tmpDir({ teardown }), { keyPair: defaultKey, encryptionKey, isBlockKey: false })
24+
const block = new Hypercore(await tmpDir({ teardown }), { keyPair: blockKey, encryptionKey, isBlockKey: true })
25+
26+
await compat.ready()
27+
await def.ready()
28+
await block.ready()
29+
30+
const largeBlock = Buffer.alloc(512)
31+
for (let i = 0; i < largeBlock.byteLength; i++) largeBlock[i] = i & 0xff
32+
33+
for (let i = 0; i < 10; i++) {
34+
await compat.append('compat test: ' + i.toString())
35+
await def.append('default test: ' + i.toString())
36+
await block.append('block test: ' + i.toString())
37+
}
38+
39+
await compat.append(largeBlock.toString('hex'))
40+
await def.append(largeBlock.toString('hex'))
41+
await block.append(largeBlock.toString('hex'))
42+
43+
const fixture = fs.createWriteStream(path.join(__dirname, `v${version}`))
44+
45+
fixture.write('/* eslint-disable */\n\n')
46+
47+
await writeFixture('compat', compat)
48+
await writeFixture('default', def)
49+
await writeFixture('block', block)
50+
51+
fixture.write('/* eslint-enable */\n')
52+
53+
fixture.end()
54+
await new Promise(resolve => fixture.on('close', resolve))
55+
56+
await compat.close()
57+
await def.close()
58+
await block.close()
59+
60+
await shutdown()
61+
62+
function teardown (fn) {
63+
closing.push(fn)
64+
}
65+
66+
function shutdown () {
67+
return Promise.all(closing.map(fn => fn()))
68+
}
69+
70+
async function writeFixture (name, core) {
71+
fixture.write(`exports['${name}'] = [\n`)
72+
for (let i = 0; i < core.length; i++) {
73+
const b64 = (await core.get(i, { raw: true })).toString('base64')
74+
fixture.write(` '${b64}'${(i === core.length - 1) ? '' : ','}\n`)
75+
}
76+
fixture.write(']\n\n')
77+
}
78+
}

test/fixtures/encryption/v11.0.48.cjs

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* eslint-disable */
2+
3+
exports['compat'] = [
4+
'nDwlg9HRVVn48l5C+beY4f1hlxif8A==',
5+
'PLfFcX+Z9TFJS5viqhMYATUyhMk7rw==',
6+
'QbLGoZSGCQtO/U4DJ2cIN7Kk4FzAZw==',
7+
'8pnkYgewV1dENUgeQs6YY+0CsV6ctA==',
8+
'vP8WwW71BLHHs3fcHmTtSxmmV3tvpQ==',
9+
'8LO53CW0Mn0BOGjPjwASq8ZycaRWiA==',
10+
'OJql22gF2kO7o6IRjLHFVqL2413PAQ==',
11+
'CohERKsAMKtiI3LwPo+ELVMraGMKtw==',
12+
'5gxIRLBm/q+6Pc0ww3+AxCi41RcudA==',
13+
'mBr2B3XnMnSYo2KzC6MNBOtchY2EUw==',
14+
'w9PUVzvOSjYZdzL3n/3Yjyk8Pm3prIfc/MkRNCtSvVRT1rK86nuLfb3YkKWgY7Ed0YD9X+DB680VxIBXneRACZCP9SUtkQ5iLhaD9/riG0Fw+penagGC9X47108EJAd1gMR1O1G2WH7nVRVb3y/myo98anwkG+eKi8xGIn+UARBdQtNkzz3l+Y/QMZ1wvDOEaZh/Ffp0AVNj66yvDlnHINFc5q7VRKNrddXa70rNPlD1zqYNmqbvAV8QBdPLUjPjWGCCi1Y8gWC74ocYSUT9Z8iS8DQ/SzUplQJIvsBgCJrIn7zlldOTL7EMw7O3564Ojl93GRHbDregmXkyiNrnlJRkk8i3loHXoW3kJ1DDLOCS00Se3w2xOqOOLtd4XhRR9kr7qiQ4uHJv+duNdfrVhNiicAVXe6TW4RCPVIlUkOMv5rKAO5KGqIOAD34nQgyeSoIhKxitKXwgadgm+g9ahbSXufu0EPr4bh4CuQ95bIWsTaXFn76HajRDwQMgNuNJPjCD/SE4EFyTjZaPwKuPE5FFodBPHpW43S1+UBwN5Vh+NO2WVwL9neVQKe9FvLBAk44ndMzZLebGJVwEFBogREBTxoLU0AreCjkpS0pzmIzk5byHJrcsm0GFEH+e+zKmfIEYwhUdpNPW3wrM0J/PL9rfD2N/GbCOdc58D5FwOgJcL1fK37lly6iT7XRXUrGgIOED9VfQYrWWnvnxiHLAQQ+poy51IldzsHR5pySdhyim3/+pezJuEcm3V0Vx8+Xxf7ciZ0xbueLVMvvqQ3MLCc6ZSA7az7HvJw8jqeq5/miIcEVVclCD0EGiDa32erGwsoFCu5D0PdV9+emmEg6X47WwPiorDrdrAEZlZwxYR/TTztU+A+e/Y1gahY0jjiSObIBr2UvIoeFae/QxDYmzvwAkeKCOWAStYXso0hWJVeI72oYAnmIiGA9yBXJhdWJY9IewS77oFnOBjKKmLJUbeoACEBxqbebDizE9562666Netqo6HyuAu+0jcuea3ZKjvh0ZwD6Rpv+7VjGL7R633fQwdrmL5iWrXO5wY/mOcq86+g3yVOvZr+sfbL9VAdACYut/Himzak980xfQraX1omDxg03wuQFYvbKJ04Uzca+FbYxnl4YzbVfuZt8wLoBTPssTFFWhQxkiYoqHmhbklIU83nMiNH+U8T7nrtNCBXgCmQEImAiroMIPGaP0v+A3skAI6rgVtL2IZ6mf6LVDDWVhXgPu5uHi3QHiuqv/rGF8ongWEIqQqRgt7sRAK7mwluKzceDEZuU+zhdYID3P1iVvzHo2QEOCWfN95j9+GRyFUMCjc/3e+BOvrtNu2gloCAaZ3E0p7kQt7zTAX3qMs/UvB9LzVD2d'
15+
]
16+
17+
exports['default'] = [
18+
'/UFE+5IFU2U3o/jwybXF9Yf+0JlwfsM=',
19+
'no9bWiyQvlaabzLKKfbvfkqW9IcTKc8=',
20+
'VPg3K5hmg+BBSn+xPmUrZcjp3s2vLG8=',
21+
'WjF137E0suunTmbtcyJMaUkMISpYOoU=',
22+
'1wsLIjbEqsD6Pmef9irDIjUjshi+Upo=',
23+
'GJWnyuKtIaq9dqIWv6hd4RLotToIH6g=',
24+
'Vsm2xOl1aGgI2vPmAj8ZKs7/xgaa8R4=',
25+
'Vxy1Q524Zke8RSu62qYViSymsFPwgh4=',
26+
'Y8QlWTKAqUcfiR1ozb9uj7nzsG19Pfw=',
27+
'HJqWtozv1C7wQjWnwVyL+wP9/7obVcs=',
28+
'rOi0T3JF6VeEQ/eSOyaRsMaGBXWi1bbEAu8G9a0A6Zesg1lhfRYG5N7du/aIF4WVMjwpMhTU+dQq4r/j/KmF/SCfnthQeyytJl1yxvYNDOSXacTc/D8DBKjU7IQqpl6bRkmpJDJwUlBOTLMD/daYa0sXpnYg1jyhlqmi4genCPUx9pkER/6vAPrdHq1zkwuVMYT3aoinQrco+HrhlHxFAAqxoPElAUJE1+VFn5xKe77pkoUwHsj7vjqG/r4s9qDjtYxwc2ZNo90o2FmTJ+KnL9IvGYcwNyBP3ZDsPspcPyQdtK1rS6zQJHGf4qLpg+1NnbQ3BHWJ64BWN9y3hLWTzH4Xau2u8S2ipCmrusHLeIJQAUXOmPKYFYFuSPOSIvAGpHNYWpDvyPFbCs0ZC2ttD/GIMaJLWT8XYL6isY4ns8HYOB0gCndT9RZLdVW0VT1jkYhtbVqlQD1LHaGhhXxJnucVJ1PI8ZbT+CiygmxqCMeG0C76hKjbTEcTiQuhH3B9Tk8s3Wifj8YlElyGkOTSHtVM2x6pEei0EP9kqtB8mt9wGwVd3RjUYJoNcZt7r3X6ZsGjFmYIIMmZmilFloB7uIUABtIecukrvlbRzpy5RzlRr0cywPMW+MO6qY1SPgeAdtMHoqj2fW/RNUZMT7exrKGVetWuCqaTiPeR1gC4qAdBtc5DHwoBhxo4meyp876E9/BRpFUnw3E5HLeadu6jTnC7zdfveUk7+HJx7iLxaVPDxVQqNQpB/xjBCHtDMWdJ0FxWbS55TvCbK+s8QMPN+PtIzT3WWD9/6y2DvxdNqjQDVBZHxJidS3HPkpq8nUrfDGQhzlZ3qDLeRrASxl2rODVO6JU6kxLYXTpMFsqj4pUgJNMPnt5d2klXS0qQD8ZE/HlRNB4jXmJ8dbGOC/izFtmMhene4Np7n5sEYiJgfvsXk7TAR7/d/nRLIx7drEqwyoHzQtISez9SxF2d79/tNfE3QVi/wKIjo72tGw+3jaryYEuuZkx+tvaXIbBDWKglHemD0orNCRuuf+ZPyNjb8WlMrZ5J4HP6cI/uz8xHc4owypdqxEt2Ne2QTq/Z3XaT/sOQhiF1WM1BlZ6pstX1/Es6g9k4fHvXJMvgGn13LRBtSliUKN08GeCVv5ozs/0kUYsHe1SFX0tCoA2S2yU5V6aUTa1+bC2gnhxO4mYoGhwyqny7vjFg2hwVYLaDg4JgaGf9ePYLKj/M5Xj5Q+Q44ZKgjcuXRA10buIcXeR1EsScBiqwjzR/8D0hHACoJ81utNfN9L7OtIUh6OIYRYnMxcNx5Y3svgxb7STTmrLkorD2UdNZjSo7sKLXIMaJSY5n0p+kZQjOsgHxMyfUNkZVvRNZTfbc60wd'
29+
]
30+
31+
exports['block'] = [
32+
'87VJ77lmAFwJzx9vlrKaB+XB/REc',
33+
'G0JfCfdn1m9FQlqjfexPK8xJQD4d',
34+
'C8Zuffa7K1Kf+Gvw7GbgSN5E+3zd',
35+
'8MF5UefDZkf93UzRenq3ebfyQ02A',
36+
'0OLCgve744BDosP4g+RQrUbeZdHh',
37+
'93gFjJH1tzvHdyad1S6+1iF1rJVn',
38+
'VxnSlCE/vgI1aB/d6tAaGJpawQfi',
39+
'neKG5Nl77jFCQFTvFvsxp+1pvoFA',
40+
'r96xMtHumU388zQETcHcUkU//wyT',
41+
'YH44ccE3PF57SMPbh7G4TVFOLn+/',
42+
'e33cPYNqfjwsRDQjjwcdtSiffKXFu+j82ffRn7TUsaZ09Ms6gug4KVb5ky/OFAz1VRVab9Mp+tlZHxfmmdUC9KCQMcFf677CsxZwyfvh22JtFWK4cDPLdJog+9Aed4iJaZ6DSK/QXm6x/QPTrX3aXTWq/U0z/yU1NEg2i1i4yMjfWU/+3FAa0XwF+9xmjpLrFKKfOrny6QLgZGlYwjtRJqJpbHIF5FpJtzWaY7l6ya1shzNv2gZ88RUKag2bwunvcC9KuT5wnfhkDjFv/oVn6nvqjKXxKpvyEZ5MnzOkZNL9zSxFj8vXM+2hcwItwzSIHKsnoCmZVgePsWkZOQ3MlEW8fMsS2S4wtFeiBQFnuELGfZXgH+6Iv0UuXc+bv5DAMnwLHdpQgFYNLVqptRlbbmY+EKkxbyLjcp9Z3b5zP1JuV2136ZT1CUTZEUTQ/e4hj582TmcmUKYORirzoImBPHR112UCeBn9yRR/BsLSp+po0VamcxRjvp4mgJAJj5OGA/70nSU30Nd71JaogtirUv8yt10gYRb1FK1I1Uh2R8/SCKm34I/XZQXIB+1R0SVp/qLwmGaI8XyoOWJXHkYqTc3K5IzAr762WA3xDtMc8e2eUSFaVLuOcXGCBut2jzyeeWDUR6Ge5UpWeT8NAHg+zWQKk4CRN4U/PoQwOJB/qRdUg9G5R6c5W+pGHmQKv6qSBeKVlL3BjzG4c6f1mGe6n4t7YHZYV3ZNlSxMOtGhpWLKUAasWmRvpFtyouMAbYh0yNCsbc8VE5CnZs7YoebtSjvCoDEf/k7cEEH9bsMgs0IG4MFZ58Th0LHZGXdQWNwhS4Zh8eYukWF2CUU5QyUZxNSn2f84kRqlb6DQ7ps7xSzPXBEIFMAv5RTxRPk5EexT8Tnc7JQpssLKx2RMTUYBV/ZqzJeQ/k/HEMgkf7biwhiKKZ5/PbiDbO3oqHmDlIx7XVxp+svHgqIsZldJ03LfX31aKnASE3YBbgxwJHeaYLWV64xFfbOo+VtqP+F5ZjVUQtf/FjYA4h1ATE2GkNlqlC7dwgJzuUqC1IkvONNUfCHSUVKou4/LKs/O8ncGkhhjJzbbg9OGKmGl2T9Hcfgq42uloWhiiN0mOaIJxt9ZT0VoAox8PQ5783JnNFeVkgJ0H+nlOY8iy4DcaoOKzGsuZFLWvG1uhhktcx3pUlX9ufdAhiPlaVmpR2UfRESMf8QTIzCs0VqfbSyxxrESGoVcEgICXYDW5HCjzl5O8e18NqnreiuCYMqTjPGY0u0aOm2XIemSU6rqJ0SVknZdoDuF0KI8no65z0iPeePK+Z7odBme5XvErxKLN0VFNPm4sGhTrC1Gh8sH1n6XWsmd+VnnV0/wJ1BdMlFe'
43+
]
44+
45+
/* eslint-enable */

0 commit comments

Comments
 (0)