X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=test%2Fhotp.js;fp=test%2Fhotp.js;h=f79f816f916c2d16098c42c89cc1c385bf4fd270;hb=2207e51e71606cbd1b4e3a688d450a79853dc8e9;hp=0000000000000000000000000000000000000000;hpb=2fdc701c2749c8d2817502c750f1011e99e21cc1;p=squeep-totp diff --git a/test/hotp.js b/test/hotp.js new file mode 100644 index 0000000..f79f816 --- /dev/null +++ b/test/hotp.js @@ -0,0 +1,83 @@ +/* eslint-env: mocha */ +'use strict'; + +const assert = require('assert'); +const HOTP = require('../lib/hotp'); + +describe('HOTP', function () { + let options, hotp; + + const tests = [ + { count: 0n, hmac: Buffer.from('cc93cf18508d94934c64b65d8ba7667fb7cde4b0', 'hex'), hex: '4c93cf18', dec: 1284755224, hotp: '755224' }, + { count: 1n, hmac: Buffer.from('75a48a19d4cbe100644e8ac1397eea747a2d33ab', 'hex'), hex: '41397eea', dec: 1094287082, hotp: '287082' }, + { count: 2n, hmac: Buffer.from('0bacb7fa082fef30782211938bc1c5e70416ff44', 'hex'), hex: '82fef30', dec: 137359152, hotp: '359152' }, + { count: 3n, hmac: Buffer.from('66c28227d03a2d5529262ff016a1e6ef76557ece', 'hex'), hex: '66ef7655', dec: 1726969429, hotp: '969429' }, + { count: 4n, hmac: Buffer.from('a904c900a64b35909874b33e61c5938a8e15ed1c', 'hex'), hex: '61c5938a', dec: 1640338314, hotp: '338314' }, + { count: 5n, hmac: Buffer.from('a37e783d7b7233c083d4f62926c7a25f238d0316', 'hex'), hex: '33c083d4', dec: 868254676, hotp: '254676' }, + { count: 6n, hmac: Buffer.from('bc9cd28561042c83f219324d3c607256c03272ae', 'hex'), hex: '7256c032', dec: 1918287922, hotp: '287922' }, + { count: 7n, hmac: Buffer.from('a4fb960c0bc06e1eabb804e5b397cdc4b45596fa', 'hex'), hex: '4e5b397', dec: 82162583, hotp: '162583' }, + { count: 8n, hmac: Buffer.from('1b3c89f65e6c9e883012052823443f048b4332db', 'hex'), hex: '2823443f', dec: 673399871, hotp: '399871' }, + { count: 9n, hmac: Buffer.from('1637409809a679dc698207310c8c7fc07290d9e5', 'hex'), hex: '2679dc69', dec: 645520489, hotp: '520489' }, + ]; + + beforeEach(function () { + options = { + key: Buffer.from('12345678901234567890'), + }; + hotp = new HOTP(options); + }); + + describe('constructor', function () { + it('covers invalid key', function () { + options.key = Buffer.from('blah'); + assert.throws(() => new HOTP(options), RangeError); + }); + it('covers invalid algorithm', function () { + options.algorithm = 'md5'; + assert.throws(() => new HOTP(options), RangeError); + }); + it('covers missing options', function () { + assert.throws(() => new HOTP()); + }); + it('covers counter', function () { + options.counter = 4; + hotp = new HOTP(options); + assert.strictEqual(hotp.counter, 4n); + }); + }); // constructor + + it('_hmac sanity', function () { + for (const test of tests) { + const result = hotp._hmac(test.count); + assert.strictEqual(Buffer.compare(result, test.hmac), 0, `count: ${test.count} result: ${result.toString('hex')} expected: ${test.hmac.toString('hex')}`); + } + }); // _hmac sanity + + it('_truncate sanity', function () { + for (const test of tests) { + const result = hotp._truncate(test.count); + assert.strictEqual(result, test.dec, `count: ${test.count} result: ${result} expected: ${test.dec} (hex: ${result.toString(16)} hexpected: ${test.hex})`); + } + }); // _truncate sanity + + it('generate', function () { + for (const test of tests) { + const result = hotp.generate(); + assert.strictEqual(result, test.hotp, `count: ${test.count} htop.counter: ${hotp.counter} result: ${result} expected: ${test.hotp}`); + assert.strictEqual(hotp.counter, test.count + 1n); + } + }); // generate + + it('covers generate with count', function () { + const result = hotp.generate(3n); + assert.strictEqual(result, tests[3].hotp); + }); // generate coverage + + describe('validate', function () { + it('accepts correct hotp', function () { + const result = hotp.validate(tests[2].hotp, 2n); + assert.strictEqual(result, true); + }); + }); // validate + +}); // HOTP \ No newline at end of file