UNPKG

ara-crypto

Version:

Cryptographic functions used in Ara modules

200 lines (159 loc) 6.13 kB
const isBuffer = require('is-buffer') const test = require('./helpers/runner') const sss = require('../sss') const ZERO = Buffer.alloc(16) ZERO.fill(0) test.cb('sss.isSecret(secret) is a function', (t) => { t.true('function' === typeof sss.isSecret) t.end() }) test.cb('sss.init(opts) is a function', (t) => { t.true('function' === typeof sss.init) t.end() }) test.cb('sss.secret(value, opts) is a function', (t) => { t.true('function' === typeof sss.secret) t.end() }) test.cb('sss.shares(secret, opts) is a function', (t) => { t.true('function' === typeof sss.shares) t.end() }) test.cb('sss.recover(shares, opts) is a function', (t) => { t.true('function' === typeof sss.recover) t.end() }) test.cb('sss.init(opts) throws on bad input', (t) => { t.throws(() => sss.init(() => {}), { instanceOf: TypeError }) t.throws(() => sss.init(true), { instanceOf: TypeError }) t.throws(() => sss.init(123), { instanceOf: TypeError }) t.throws(() => sss.init(''), { instanceOf: TypeError }) t.end() }) test.cb('sss.secret(opts) throws on bad input', (t) => { t.throws(() => sss.secret(undefined), { instanceOf: TypeError }) t.throws(() => sss.secret(null), { instanceOf: TypeError }) t.throws(() => sss.secret({}), { instanceOf: TypeError }) t.throws(() => sss.secret([]), { instanceOf: TypeError }) t.throws(() => sss.secret(() => {}), { instanceOf: TypeError }) t.throws(() => sss.secret(true), { instanceOf: TypeError }) t.throws(() => sss.secret(123), { instanceOf: TypeError }) t.throws(() => sss.secret(''), { instanceOf: TypeError }) t.throws(() => sss.secret(Buffer.alloc(0)), { instanceOf: TypeError }) t.throws(() => sss.secret(ZERO), { instanceOf: TypeError }) t.throws(() => sss.secret('secret', null), { instanceOf: TypeError }) t.throws(() => sss.secret('secret', true), { instanceOf: TypeError }) t.throws(() => sss.secret('secret', 123), { instanceOf: TypeError }) t.throws(() => sss.secret('secret', ''), { instanceOf: TypeError }) t.throws(() => sss.secret('secret', () => {}), { instanceOf: TypeError }) t.end() }) test.cb('sss.shares(opts) throws on bad input', (t) => { t.throws(() => sss.shares(() => {}), { instanceOf: TypeError }) t.throws(() => sss.shares(true), { instanceOf: TypeError }) t.throws(() => sss.shares(123), { instanceOf: TypeError }) t.throws(() => sss.shares(''), { instanceOf: TypeError }) t.end() }) test.cb('sss.recover(opts) throws on bad input', (t) => { t.throws(() => sss.recover(() => {}), { instanceOf: TypeError }) t.throws(() => sss.recover(true), { instanceOf: TypeError }) t.throws(() => sss.recover(123), { instanceOf: TypeError }) t.throws(() => sss.recover(''), { instanceOf: TypeError }) t.end() }) test.cb('sss.init(opts) simple with defaults', (t) => { const ctx = sss.init() t.true('object' === typeof ctx) t.true('number' === typeof ctx.bits) t.true('number' === typeof ctx.size) t.true('number' === typeof ctx.radix) t.true('number' === typeof ctx.maxBits) t.true('number' === typeof ctx.padding) t.true('number' === typeof ctx.maxShares) t.true('number' === typeof ctx.bytesPerChar) t.true('number' === typeof ctx.maxBytesPerChar) t.true('object' === typeof ctx.table) t.true('object' === typeof ctx.codec) t.true(isBuffer(ctx.entropy)) t.end() }) test.cb('sss.secret(value) simple', (t) => { const secret = sss.secret('secret key') t.true('object' === typeof secret) t.true(isBuffer(secret.buffer)) t.end() }) test.cb('sss.shares(secret, opts) simple', (t) => { const shares = sss.shares('secret key', { shares: 10, threshold: 5 }) t.true(Array.isArray(shares)) t.true(10 === shares.length) t.true(shares.every((share) => isBuffer(share))) t.end() }) test.cb('sss.recover(shares, opts) simple', (t) => { const key = Buffer.from('secret key') const secret = sss.secret(key) const shares = sss.shares(secret, { shares: 10, threshold: 5 }) const recovered = sss.recover(shares.slice(2, 7)) t.true(0 === Buffer.compare(key, recovered.buffer)) t.end() }) test.cb('simple', (t) => { const ctx = sss.init() const key = Buffer.from('key') const secret = ctx.secret(key) const shares = ctx.shares(secret, { shares: 10, threshold: 5 }) const recovered = ctx.recover(shares) t.true(0 === Buffer.compare(recovered.buffer, key)) t.end() }) // as of 2018-07-26 test.cb('compatibility 1 (DO NOT REMOVE)', (t) => { const ctx = sss.init() t.true('object' === typeof ctx) // DO NOT REMOVE // produced by https://github.com/grempe/secrets.js const knownKey = Buffer.from('key') const knownShares = [ '801a4a3ab36c3cdfb4544b9cbd8b73f5a7f', '802a63a4324f56b6f5c4eb27c39853a67cb', '8032158752f240ad2b21c14506e3ab1a555', '804321a970c058a5293e285780d77caa5c4', '8055c0555b4aa88200bd279dba2f04c88cb', '806916648dd60e837fe1cc66faeb2537640', '807dcb81758dd4603cd3a242bf73d04c3c5', '8085169c1fe708999b607f9f849cd6f49c2', '80976239d3e56d57936d634352f9a0188a8', '80ae9daeddec2d4ca4cce50e379d59eb1ba' ] t.true(0 === Buffer.compare( ctx.recover(knownShares).buffer, knownKey )) t.end() }) // as of 2018-07-26 test.cb('compatibility 2 (DO NOT REMOVE)', (t) => { const ctx = sss.init() t.true('object' === typeof ctx) // DO NOT REMOVE // copied from https://github.com/grempe/secrets.js/blob/master/spec/SecretsSpec.js const knownKey = Buffer.from('82585c749a3db7f73009d0d6107dd650') const knownShares = [ '80111001e523b02029c58aceebead70329000', '802eeb362b5be82beae3499f09bd7f9f19b1c', '803d5f7e5216d716a172ebe0af46ca81684f4', '804e1fa5670ee4c919ffd9f8c71f32a7bfbb0', '8050bd6ac05ceb3eeffcbbe251932ece37657', '8064bb52a3db02b1962ff879d32bc56de4455', '8078a5f11d20cbf8d907c1d295bbda1ee900a', '808808ff7fae45529eb13b1e9d78faeab435f', '809f3b0585740fd80830c355fa501a8057733', '80aeca744ec715290906c995aac371ed118c2' ] const secret = ctx.secret(ctx.codec.decode(knownKey)) const recovered = ctx.recover(knownShares) t.true(0 === Buffer.compare(secret.buffer, recovered.buffer)) t.end() })