supercop.ts

cross-compiled javascript implementation of ed25519 based on supercop-ref10
git clone git://git.finwo.net/lib/supercop.ts
Log | Files | Refs | README | LICENSE

commit bf63c98616337735eb3380c9522b9a74cc105d22
parent 611f80fc02ac1457825283aa5ed9479d346d9042
Author: finwo <finwo@pm.me>
Date:   Wed, 11 Aug 2021 23:26:42 +0200

Turned test.js into folder, for clearer test separation

Diffstat:
Mpackage.json | 2+-
Dtest.js | 129-------------------------------------------------------------------------------
Atest/0000-export-types.js | 13+++++++++++++
Atest/0001-random-byte-generation.js | 16++++++++++++++++
Atest/0002-argument-validation.js | 39+++++++++++++++++++++++++++++++++++++++
Atest/0003-key-generation.js | 20++++++++++++++++++++
Atest/0004-signature-generation.js | 16++++++++++++++++
Atest/0005-signature-validation.js | 26++++++++++++++++++++++++++
Atest/0006-key-exchange.js | 20++++++++++++++++++++
9 files changed, 151 insertions(+), 130 deletions(-)

diff --git a/package.json b/package.json @@ -5,7 +5,7 @@ "main": "index.js", "homepage": "https://github.com/finwo/supercop", "scripts": { - "test": "node test.js", + "test": "tape test/*.js", "prepublish": "npm test", "postpublish": "PACKAGE_VERSION=$(cat package.json | grep \\\"version\\\" | head -1 | awk -F: '{print $2}' | sed 's/[\",]//g' | tr -d '[[:space:]]') && npm deprecate \"supercop@<${PACKAGE_VERSION}\" \"Rolling release, please update to ${PACKAGE_VERSION}\"", "build": "make" diff --git a/test.js b/test.js @@ -1,129 +0,0 @@ -const isBuffer = require('is-buffer'); -const crypto = require('crypto'); -const test = require('tape'); -const lib = require('./index'); - -test('Type checks', t => { - t.plan(7); - t.is((!!lib) && (typeof lib) , 'object' , 'supercop is an object' ); - t.is(typeof lib._randomBytes , 'function', 'export helper: _randomBytes' ); - t.is(typeof lib._checkArguments, 'function', 'export helper: _checkArguments'); - t.is(typeof lib.createSeed , 'function', 'export method: createSeed' ); - t.is(typeof lib.createKeyPair , 'function', 'export method: createKeyPair' ); - t.is(typeof lib.sign , 'function', 'export method: sign' ); - t.is(typeof lib.verify , 'function', 'export method: verify' ); -}); - -test('Random bytes generation',async t => { - t.plan(4); - - const randomBytes32 = await lib._randomBytes(32); - const randomBytes64 = await lib._randomBytes(64); - - t.is(isBuffer(randomBytes32), true, 'Random32 is a buffer'); - t.is(isBuffer(randomBytes64), true, 'Random64 is a buffer'); - t.is(randomBytes32.length , 32 , 'Random32 is 32 bytes long'); - t.is(randomBytes64.length , 64 , 'Random64 is 64 bytes long'); -}); - -test('Argument validation',async t => { - t.plan(14); - - // We'll not throw in this test - const callback = function(err) { - if (!err) return false; - if (err instanceof Error) return err.message; - return err; - }; - - // Variables to test with - const undef = undefined; - const rightSeed = await lib._randomBytes(32); - const wrongSeed = await lib._randomBytes(33); - const rightPublicKey = await lib._randomBytes(32); - const wrongPublicKey = await lib._randomBytes(33); - const rightSecretKey = await lib._randomBytes(64); - const wrongSecretKey = await lib._randomBytes(65); - const randomMessage = await lib._randomBytes(1024); - - t.is(await lib._checkArguments(null , callback), 'Expected object, null given' , 'Failure on null argument'); - t.is(await lib._checkArguments('some string' , callback), 'Expected object, string given' , 'Failure on string argument'); - t.is(await lib._checkArguments(callback , callback), 'Expected object, function given', 'Failure on function argument'); - t.is(await lib._checkArguments({ seed : undef }, callback), 'Seed is not a buffer' , 'Failure on undefined seed'); - t.is(await lib._checkArguments({ seed : rightSeed }, callback), false , 'Success on 32-byte seed'); - t.is(await lib._checkArguments({ seed : wrongSeed }, callback), 'Seed must be 32 bytes' , 'Failure on 33-byte seed'); - t.is(await lib._checkArguments({ publicKey: undef }, callback), 'Public key is not a buffer' , 'Failure on undefined public key'); - t.is(await lib._checkArguments({ publicKey: rightPublicKey }, callback), false , 'Success on 32-byte public key'); - t.is(await lib._checkArguments({ publicKey: wrongPublicKey }, callback), 'Public key must be 32 bytes' , 'Failure on 33-byte public key'); - t.is(await lib._checkArguments({ secretKey: undef }, callback), 'Secret key is not a buffer' , 'Failure on undefined secret key'); - t.is(await lib._checkArguments({ secretKey: rightSecretKey }, callback), false , 'Success on 64-byte secret key'); - t.is(await lib._checkArguments({ secretKey: wrongSecretKey }, callback), 'Secret key must be 64 bytes' , 'Failure on 65-byte secret key'); - t.is(await lib._checkArguments({ message : undef }, callback), 'Message is not a buffer' , 'Failure on undefined message'); - t.is(await lib._checkArguments({ message : randomMessage }, callback), false , 'Success on buffer message'); -}); - -test('Key generation',async t => { - t.plan(6); - - const seed = await lib.createSeed(); - - t.is(isBuffer(seed), true, 'Seed is a buffer' ); - t.is(seed.length , 32 , 'Seed\'s length is 32'); - - const keys = await lib.createKeyPair(seed); - - t.is(isBuffer(keys.publicKey), true, 'Public key is a buffer' ); - t.is(keys.publicKey.length , 32 , 'Public key\'s length is 32'); - t.is(isBuffer(keys.secretKey), true, 'Secret key is a buffer' ); - t.is(keys.secretKey.length , 64 , 'Secret key\'s length is 64'); -}); - -test('Signatures',async t => { - t.plan(2); - - const seed = crypto.randomBytes(32); - const keys = await lib.createKeyPair(seed); - const signature = await lib.sign(Buffer.from('hello there m8'), keys.publicKey, keys.secretKey); - - t.is(isBuffer(signature), true, 'Signature is a buffer'); - t.is(signature.length , 64 , 'Signature\'s length is 64 bytes'); -}); - -test('Verify',async t => { - t.plan(4); - - const seed = crypto.randomBytes(32); - const keys = await lib.createKeyPair(seed); - const messageBuf = Buffer.from('hello there m8'); - const messageStr = 'hello there m8'; - const wrongMessage = await lib._randomBytes(messageBuf.length); - - const signatureBuf = await lib.sign(messageBuf, keys.publicKey, keys.secretKey); - const signatureStr = await lib.sign(messageStr, keys.publicKey, keys.secretKey); - - t.is(Buffer.compare(signatureBuf, signatureStr), 0, 'String and buffer sourced signature match'); - - const wrongSeed = crypto.randomBytes(32); - const wrongKeys = await lib.createKeyPair(wrongSeed); - - t.is(await lib.verify(signatureBuf, messageBuf, keys.publicKey) , true , 'Signature verified message'); - t.is(await lib.verify(signatureBuf, wrongMessage, keys.publicKey) , false, 'Different messaged does not verify'); - t.is(await lib.verify(signatureBuf, messageBuf, wrongKeys.publicKey), false, 'Different public key does not verify'); -}); - -test('Key Exchange',async t => { - t.plan(1); - - const AliceSeed = crypto.randomBytes(32); - const BobSeed = crypto.randomBytes(32); - const CharlieSeed = crypto.randomBytes(32); - - const Alice = await lib.createKeyPair(AliceSeed); - const Bob = await lib.createKeyPair(BobSeed); - const Charlie = await lib.createKeyPair(CharlieSeed); - - const AliceBobSecret = await lib.keyExchange(Alice.publicKey, Bob.secretKey); - const BobAliceSecret = await lib.keyExchange(Bob.publicKey, Alice.secretKey); - - t.ok(AliceBobSecret.equals(BobAliceSecret), 'Alice and Bob generate the same shared secret'); -}); diff --git a/test/0000-export-types.js b/test/0000-export-types.js @@ -0,0 +1,13 @@ +const test = require('tape'); +const lib = require('../index'); + +test('Export types', t => { + t.plan(7); + t.is((!!lib) && (typeof lib) , 'object' , 'supercop is an object' ); + t.is(typeof lib._randomBytes , 'function', 'export helper: _randomBytes' ); + t.is(typeof lib._checkArguments, 'function', 'export helper: _checkArguments'); + t.is(typeof lib.createSeed , 'function', 'export method: createSeed' ); + t.is(typeof lib.createKeyPair , 'function', 'export method: createKeyPair' ); + t.is(typeof lib.sign , 'function', 'export method: sign' ); + t.is(typeof lib.verify , 'function', 'export method: verify' ); +}); diff --git a/test/0001-random-byte-generation.js b/test/0001-random-byte-generation.js @@ -0,0 +1,16 @@ +const isBuffer = require('is-buffer'); +const test = require('tape'); +const lib = require('../index'); + +test('Random byte generation',async t => { + t.plan(4); + + const randomBytes32 = await lib._randomBytes(32); + const randomBytes64 = await lib._randomBytes(64); + + t.is(isBuffer(randomBytes32), true, 'Random32 is a buffer'); + t.is(isBuffer(randomBytes64), true, 'Random64 is a buffer'); + t.is(randomBytes32.length , 32 , 'Random32 is 32 bytes long'); + t.is(randomBytes64.length , 64 , 'Random64 is 64 bytes long'); +}); + diff --git a/test/0002-argument-validation.js b/test/0002-argument-validation.js @@ -0,0 +1,39 @@ +const test = require('tape'); +const lib = require('../index'); + +test('Argument validation',async t => { + t.plan(14); + + // We'll not throw in this test + const callback = function(err) { + if (!err) return false; + if (err instanceof Error) return err.message; + return err; + }; + + // Variables to test with + const undef = undefined; + const rightSeed = await lib._randomBytes(32); + const wrongSeed = await lib._randomBytes(33); + const rightPublicKey = await lib._randomBytes(32); + const wrongPublicKey = await lib._randomBytes(33); + const rightSecretKey = await lib._randomBytes(64); + const wrongSecretKey = await lib._randomBytes(65); + const randomMessage = await lib._randomBytes(1024); + + t.is(await lib._checkArguments(null , callback), 'Expected object, null given' , 'Failure on null argument'); + t.is(await lib._checkArguments('some string' , callback), 'Expected object, string given' , 'Failure on string argument'); + t.is(await lib._checkArguments(callback , callback), 'Expected object, function given', 'Failure on function argument'); + t.is(await lib._checkArguments({ seed : undef }, callback), 'Seed is not a buffer' , 'Failure on undefined seed'); + t.is(await lib._checkArguments({ seed : rightSeed }, callback), false , 'Success on 32-byte seed'); + t.is(await lib._checkArguments({ seed : wrongSeed }, callback), 'Seed must be 32 bytes' , 'Failure on 33-byte seed'); + t.is(await lib._checkArguments({ publicKey: undef }, callback), 'Public key is not a buffer' , 'Failure on undefined public key'); + t.is(await lib._checkArguments({ publicKey: rightPublicKey }, callback), false , 'Success on 32-byte public key'); + t.is(await lib._checkArguments({ publicKey: wrongPublicKey }, callback), 'Public key must be 32 bytes' , 'Failure on 33-byte public key'); + t.is(await lib._checkArguments({ secretKey: undef }, callback), 'Secret key is not a buffer' , 'Failure on undefined secret key'); + t.is(await lib._checkArguments({ secretKey: rightSecretKey }, callback), false , 'Success on 64-byte secret key'); + t.is(await lib._checkArguments({ secretKey: wrongSecretKey }, callback), 'Secret key must be 64 bytes' , 'Failure on 65-byte secret key'); + t.is(await lib._checkArguments({ message : undef }, callback), 'Message is not a buffer' , 'Failure on undefined message'); + t.is(await lib._checkArguments({ message : randomMessage }, callback), false , 'Success on buffer message'); +}); + diff --git a/test/0003-key-generation.js b/test/0003-key-generation.js @@ -0,0 +1,20 @@ +const isBuffer = require('is-buffer'); +const test = require('tape'); +const lib = require('../index'); + +test('Key generation',async t => { + t.plan(6); + + const seed = await lib.createSeed(); + + t.is(isBuffer(seed), true, 'Seed is a buffer' ); + t.is(seed.length , 32 , 'Seed\'s length is 32'); + + const keys = await lib.createKeyPair(seed); + + t.is(isBuffer(keys.publicKey), true, 'Public key is a buffer' ); + t.is(keys.publicKey.length , 32 , 'Public key\'s length is 32'); + t.is(isBuffer(keys.secretKey), true, 'Secret key is a buffer' ); + t.is(keys.secretKey.length , 64 , 'Secret key\'s length is 64'); +}); + diff --git a/test/0004-signature-generation.js b/test/0004-signature-generation.js @@ -0,0 +1,16 @@ +const isBuffer = require('is-buffer'); +const crypto = require('crypto'); +const test = require('tape'); +const lib = require('../index'); + +test('Signature generation',async t => { + t.plan(2); + + const seed = crypto.randomBytes(32); + const keys = await lib.createKeyPair(seed); + const signature = await lib.sign(Buffer.from('hello there m8'), keys.publicKey, keys.secretKey); + + t.is(isBuffer(signature), true, 'Signature is a buffer'); + t.is(signature.length , 64 , 'Signature\'s length is 64 bytes'); +}); + diff --git a/test/0005-signature-validation.js b/test/0005-signature-validation.js @@ -0,0 +1,26 @@ +const crypto = require('crypto'); +const test = require('tape'); +const lib = require('../index'); + +test('Verify',async t => { + t.plan(4); + + const seed = crypto.randomBytes(32); + const keys = await lib.createKeyPair(seed); + const messageBuf = Buffer.from('hello there m8'); + const messageStr = 'hello there m8'; + const wrongMessage = await lib._randomBytes(messageBuf.length); + + const signatureBuf = await lib.sign(messageBuf, keys.publicKey, keys.secretKey); + const signatureStr = await lib.sign(messageStr, keys.publicKey, keys.secretKey); + + t.is(Buffer.compare(signatureBuf, signatureStr), 0, 'String and buffer sourced signature match'); + + const wrongSeed = crypto.randomBytes(32); + const wrongKeys = await lib.createKeyPair(wrongSeed); + + t.is(await lib.verify(signatureBuf, messageBuf, keys.publicKey) , true , 'Signature verified message'); + t.is(await lib.verify(signatureBuf, wrongMessage, keys.publicKey) , false, 'Different messaged does not verify'); + t.is(await lib.verify(signatureBuf, messageBuf, wrongKeys.publicKey), false, 'Different public key does not verify'); +}); + diff --git a/test/0006-key-exchange.js b/test/0006-key-exchange.js @@ -0,0 +1,20 @@ +const crypto = require('crypto'); +const test = require('tape'); +const lib = require('../index'); + +test('Key Exchange',async t => { + t.plan(1); + + const AliceSeed = crypto.randomBytes(32); + const BobSeed = crypto.randomBytes(32); + // const CharlieSeed = crypto.randomBytes(32); + + const Alice = await lib.createKeyPair(AliceSeed); + const Bob = await lib.createKeyPair(BobSeed); + // const Charlie = await lib.createKeyPair(CharlieSeed); + + const AliceBobSecret = await lib.keyExchange(Alice.publicKey, Bob.secretKey); + const BobAliceSecret = await lib.keyExchange(Bob.publicKey, Alice.secretKey); + + t.ok(AliceBobSecret.equals(BobAliceSecret), 'Alice and Bob generate the same shared secret'); +});