Skip to content

Commit

Permalink
New tests based on tape.
Browse files Browse the repository at this point in the history
  • Loading branch information
dchest committed Jul 3, 2014
1 parent 9c93575 commit 34cc44b
Show file tree
Hide file tree
Showing 64 changed files with 18,441 additions and 995 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
language: node_js
node_js:
- "0.10"
script: "make test"
script: "npm run testall"
10 changes: 0 additions & 10 deletions Makefile

This file was deleted.

54 changes: 51 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Documentation
* [Utilities](#utilities)
* [Examples](#examples)
* [System requirements](#system-requirements)
* [Development and testing](#development-and-testing)
* [Contributors](#contributors)


Expand Down Expand Up @@ -262,6 +263,12 @@ Decodes Base-64 encoded string and returns `Uint8Array` of bytes.
Encodes `Uint8Array` or `Array` of bytes into string using Base-64 encoding.


Examples
--------

*TODO*


System requirements
-------------------

Expand All @@ -279,10 +286,51 @@ Other systems:
* Node.js (we test on 0.10 and later)


Examples
--------
Development and testing
------------------------

Install NPM modules needed for development:

$ npm install

To build minified version:

$ npm run build

Tests use minified version, so make sure to rebuild it every time you change
`nacl.js`.

### Testing

To run tests in Node.js:

$ npm test

To run full suite of tests in Node.hs, including comparing outputs of
JavaScript port to outputs of the original C version:

$ npm run testall

To prepare tests for browsers:

$ npm run browser

and then open `tests/browser/test.html` to run them.

To run headless browser tests with `testling`:

$ npm run testling

(If you get `Error: spawn ENOENT`, install *xvfb*: `sudo apt-get install xvfb`.)

### Benchmarking

To run benchmarks in Node.js:

$ npm run bench

To run benchmarks in a browser, open `test/benchmark/bench.html`.

*TODO*

Contributors
------------
Expand Down
63 changes: 63 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"name": "tweetnacl",
"version": "0.9.0",
"description": "Port of TweetNaCl cryptographic library to JavaScript",
"main": "nacl.js",
"directories": {
"example": "examples",
"test": "tests"
},
"scripts": {
"build": "./node_modules/.bin/uglifyjs nacl.js -c -m -o nacl.min.js",
"test": "./node_modules/.bin/tape test/*.js | ./node_modules/.bin/faucet",
"testall": "make -C test/c && ./node_modules/.bin/tape test/*.js test/c/*.js | ./node_modules/.bin/faucet",
"browser": "./node_modules/.bin/browserify test/browser/init.js test/*.js > test/browser/_bundle.js",
"testling": "./node_modules/.bin/browserify test/*.js | ./node_modules/.bin/testling",
"bench": "node test/benchmark/bench.js"
},
"testling": {
"files": "test/*.js",
"browsers": [
"ie/11..latest",
"chrome/22..latest",
"firefox/16..latest",
"safari/latest",
"opera/11.0..latest",
"iphone/6..latest",
"ipad/6..latest",
"android-browser/latest"
]
},
"repository": {
"type": "git",
"url": "https://github.com/dchest/tweetnacl-js.git"
},
"keywords": [
"crypto",
"nacl",
"salsa20",
"poly1305",
"curve25519",
"ed25519",
"signatures",
"public",
"key",
"cryptography",
"encrypt",
"hash"
],
"author": "TweetNaCl-js contributors",
"license": "Public domain",
"bugs": {
"url": "https://github.com/dchest/tweetnacl-js/issues"
},
"homepage": "https://dchest.github.io/tweetnacl-js",
"devDependencies": {
"browserify": "^4.2.0",
"faucet": "0.0.1",
"tap-browser-color": "^0.1.2",
"tape": "^2.13.3",
"testling": "^1.7.0",
"uglify-js": "^2.4.14"
}
}
53 changes: 53 additions & 0 deletions test/00-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../nacl.min.js');
var test = require('tape');

var b64Vectors = require('./data/base64.random');

function arraysEqual(t, a, b) {
if (a.length != b.length) {
t.fail('different lengths: ' + a.length + ' and ' + b.length);
return;
}
for (var i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
t.fail('differ:\nexpected: [' + Array.prototype.join.call(b, ',') +
']\nactual: [' + Array.prototype.join.call(a, ',') + ']');
return;
}
}
t.pass('arrays should be equal');
}

var testBytes = new Uint8Array([208,159,209,128,208,184,208,178,208,181,209,130,44,32,78,97,67,108]);
var utf8String = "Привет, NaCl";
var b64String = "0J/RgNC40LLQtdGCLCBOYUNs";

test('nacl.util.decodeUTF8', function(t) {
t.plan(1);
arraysEqual(t, nacl.util.decodeUTF8(utf8String), testBytes);
});

test('nacl.util.encodeUTF8', function(t) {
t.plan(1);
t.equal(nacl.util.encodeUTF8(testBytes), utf8String);
});

test('nacl.util.decodeBase64', function(t) {
t.plan(1);
arraysEqual(t, nacl.util.decodeBase64(b64String), testBytes);
});

test('nacl.util.encodeBase64', function(t) {
t.plan(1);
t.equal(nacl.util.encodeBase64(testBytes), b64String);
});

test('nacl.util.encodeBase64 random test vectors', function(t) {
b64Vectors.forEach(function(vec) {
var b = new Uint8Array(vec[0]);
var s = vec[1];
t.equal(nacl.util.encodeBase64(b), s);
arraysEqual(t, nacl.util.decodeBase64(s), b);
});
t.end();
});
16 changes: 16 additions & 0 deletions test/01-verify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../nacl.min.js');
var test = require('tape');

test('nacl.verify', function(t) {
t.ok(nacl.verify(new Uint8Array(1), new Uint8Array(1)), 'equal arrays of length 1 should verify');
t.ok(nacl.verify(new Uint8Array(1000), new Uint8Array(1000)), 'equal arrays of length 1000 should verify');
var a = new Uint8Array(764), b = new Uint8Array(764);
for (i = 0; i < a.length; i++) a[i] = b[i] = i & 0xff;
t.ok(nacl.verify(a, b), 'equal arrays should verify');
t.ok(nacl.verify(a, a), 'same arrays should verify');
b[0] = 255;
t.notOk(nacl.verify(a, b), 'different arrays don\'t verify');
t.notOk(nacl.verify(new Uint8Array(1), new Uint8Array(10)), 'arrays of different lengths should not verify');
t.notOk(nacl.verify(new Uint8Array(0), new Uint8Array(0)), 'zero-length arrays should not verify');
t.end();
});
16 changes: 16 additions & 0 deletions test/02-randombytes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../nacl.min.js');
var test = require('tape');

test('nacl.randomBytes', function(t) {
t.plan(1);
var set = {}, s, i;
for (i = 0; i < 10000; i++) {
s = nacl.util.encodeBase64(nacl.randomBytes(32));
if (set[s]) {
t.fail("duplicate random sequence! ", s);
return;
}
set[s] = true;
}
t.pass('no collisions');
});
17 changes: 17 additions & 0 deletions test/03-onetimeauth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../nacl.min.js');
var test = require('tape');

var specVectors = require('./data/onetimeauth.spec');

var enc = nacl.util.encodeBase64,
dec = nacl.util.decodeBase64;

test('nacl.lowlevel.crypto_onetimeauth specified vectors', function(t) {
var out = new Uint8Array(16);
specVectors.forEach(function(v) {
nacl.lowlevel.crypto_onetimeauth(out, 0, v.m, 0, v.m.length, v.k);
t.equal(enc(out), enc(v.out));
});
t.end();
});

68 changes: 68 additions & 0 deletions test/04-secretbox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../nacl.min.js');
var test = require('tape');

var randomVectors = require('./data/secretbox.random');

var enc = nacl.util.encodeBase64,
dec = nacl.util.decodeBase64;

test('nacl.secretbox and nacl.secretbox.open', function(t) {
var key = new Uint8Array(nacl.secretbox.keyLength);
var nonce = new Uint8Array(nacl.secretbox.nonceLength);
for (var i = 0; i < key.length; i++) key[i] = i & 0xff;
for (i = 0; i < nonce.length; i++) nonce[i] = (32+i) & 0xff;
var msg = nacl.util.decodeUTF8('message to encrypt');
var box = nacl.secretbox(msg, nonce, key);
var openedMsg = nacl.secretbox.open(box, nonce, key);
t.equal(nacl.util.encodeUTF8(openedMsg), nacl.util.encodeUTF8(msg), 'opened messages should be equal');
t.end();
});

test('nacl.secretbox.open with invalid box', function(t) {
var key = new Uint8Array(nacl.secretbox.keyLength);
var nonce = new Uint8Array(nacl.secretbox.nonceLength);
t.equal(nacl.secretbox.open(new Uint8Array(0), nonce, key), false);
t.equal(nacl.secretbox.open(new Uint8Array(10), nonce, key), false);
t.equal(nacl.secretbox.open(new Uint8Array(100), nonce, key), false);
t.end();
});

test('nacl.secretbox.open with invalid nonce', function(t) {
var key = new Uint8Array(nacl.secretbox.keyLength);
var nonce = new Uint8Array(nacl.secretbox.nonceLength);
for (i = 0; i < nonce.length; i++) nonce[i] = i & 0xff;
var msg = nacl.util.decodeUTF8('message to encrypt');
var box = nacl.secretbox(msg, nonce, key);
t.equal(nacl.util.encodeUTF8(nacl.secretbox.open(box, nonce, key)),
nacl.util.encodeUTF8(msg));
nonce[0] = 255;
t.equal(nacl.secretbox.open(box, nonce, key), false);
t.end();
});

test('nacl.secretbox.open with invalid key', function(t) {
var key = new Uint8Array(nacl.secretbox.keyLength);
for (var i = 0; i < key.length; i++) key[i] = i & 0xff;
var nonce = new Uint8Array(nacl.secretbox.nonceLength);
var msg = nacl.util.decodeUTF8('message to encrypt');
var box = nacl.secretbox(msg, nonce, key);
t.equal(nacl.util.encodeUTF8(nacl.secretbox.open(box, nonce, key)),
nacl.util.encodeUTF8(msg));
key[0] = 255;
t.equal(nacl.secretbox.open(box, nonce, key), false);
t.end();
});

test('nacl.secretbox random test vectors', function(t) {
randomVectors.forEach(function(vec) {
var key = dec(vec[0]);
var nonce = dec(vec[1]);
var msg = dec(vec[2]);
var goodBox = dec(vec[3]);
var box = nacl.secretbox(msg, nonce, key);
t.equal(enc(box), enc(goodBox));
var openedBox = nacl.secretbox.open(goodBox, nonce, key);
t.equal(enc(openedBox), enc(msg));
});
t.end();
});
43 changes: 43 additions & 0 deletions test/05-scalarmult.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
var nacl = (typeof window !== 'undefined') ? window.nacl : require('../nacl.min.js');
var test = require('tape');

var randomVectors = require('./data/scalarmult.random');

var enc = nacl.util.encodeBase64,
dec = nacl.util.decodeBase64;

test('nacl.scalarMult.base', function(t) {
// This takes takes a bit of time.
// Similar to https://code.google.com/p/go/source/browse/curve25519/curve25519_test.go?repo=crypto
var golden = new Uint8Array([0x89, 0x16, 0x1f, 0xde, 0x88, 0x7b, 0x2b, 0x53, 0xde, 0x54,
0x9a, 0xf4, 0x83, 0x94, 0x01, 0x06, 0xec, 0xc1, 0x14, 0xd6, 0x98, 0x2d,
0xaa, 0x98, 0x25, 0x6d, 0xe2, 0x3b, 0xdf, 0x77, 0x66, 0x1a]);
var input = 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]);
for (var i = 0; i < 200; i++) {
input = nacl.scalarMult.base(input);
}
t.equal(enc(input), enc(golden));
t.end();
});

test('nacl.scalarMult and nacl.scalarMult.base random test vectors', function(t) {
randomVectors.forEach(function(vec) {
var pk1 = dec(vec[0]);
var sk1 = dec(vec[1]);
var pk2 = dec(vec[2]);
var sk2 = dec(vec[3]);
var out = dec(vec[4]);

var jpk1 = nacl.scalarMult.base(sk1);
t.equal(enc(jpk1), enc(pk1));
var jpk2 = nacl.scalarMult.base(sk2);
t.equal(enc(jpk2), enc(pk2));
var jout1 = nacl.scalarMult(sk1, pk2);
t.equal(enc(jout1), enc(out));
var jout2 = nacl.scalarMult(sk2, pk1);
t.equal(enc(jout2), enc(out));
});
t.end();
});

Loading

0 comments on commit 34cc44b

Please sign in to comment.