Skip to content

Instantly share code, notes, and snippets.

@karzak
Last active December 7, 2018 21:27
Show Gist options
  • Save karzak/4b5bdec36d0d0e2f96a1274280416aa5 to your computer and use it in GitHub Desktop.
Save karzak/4b5bdec36d0d0e2f96a1274280416aa5 to your computer and use it in GitHub Desktop.
Benchmark sodium and tweetnacl
const assert = require('assert');
const Benchmark = require('benchmark');
const tweetnacl = require('tweetnacl');
const tweetnaclfast = require('tweetnacl/nacl-fast');
const sodium = require('sodium');
const uSodium = require('sodium-universal')
const jSodium = require('sodium-javascript')
const base64_to_Uint8Array = function(input) {
const raw = new Buffer(input, 'base64');
const arr = new Uint8Array(new ArrayBuffer(raw.length));
for(i = 0; i < raw.length; i++) {
arr[i] = raw[i];
}
return arr;
};
const string_to_Uint8Array = function(str) {
const raw = new Buffer(str, 'utf8');
const arr = new Uint8Array(new ArrayBuffer(raw.length));
for(i = 0; i < raw.length; i++) {
arr[i] = raw[i];
}
return arr;
};
const _seed = 'Aav6yqemxoPNNqxeKJXMlruKxXEHLD931S8pXzxt4mk=';
const _pubkey = 'DsWygyoTcB7/NT5OqRzT0eaFf+6bJBSSBRfDOyU3x9k=';
const _message = "Hi, this is a string that I want signed, will keep it short";
const _sig = 'IvmJ8ntaMtcoVaU3lDToeQPdG/CdL7an4r013gYgJbY+eXJiwVZ9IxU/OC5htH41x2ezZRd83rTwe2+jf1f3CQ==';
/*********************** TweetNaCl tests ***************************/
const test_tweetnacl = function(nacl) {
this.nacl = nacl;
this._seed = base64_to_Uint8Array(_seed);
this.key = null;
this._pubkey = base64_to_Uint8Array(_pubkey);
this._message = string_to_Uint8Array(_message);
this.sig = null;
this._sig = base64_to_Uint8Array(_sig);
};
test_tweetnacl.prototype.fromSeed = function() {
this.key = this.nacl.sign.keyPair.fromSeed(this._seed);
};
test_tweetnacl.prototype.sign = function() {
this.sig = this.nacl.sign.detached(this._message, this.key.secretKey);
};
test_tweetnacl.prototype.verify = function() {
const r = this.nacl.sign.detached.verify(this._message, this.sig, this._pubkey);
assert(r, "Verification failed!");
};
test_tweetnacl.prototype.validate = function() {
assert(new Buffer(this.key.publicKey).toString('base64') === _pubkey, "wrong public key");
assert(new Buffer(this.sig).toString('base64') === _sig, "wrong signature");
};
/*********************** Sodium tests ***************************/
const test_sodium = function() {
this._seed = base64_to_Uint8Array(_seed);
this.key = null;
};
test_sodium.prototype.fromSeed = function() {
this.key = new sodium.Key.Sign.fromSeed(_seed, 'base64');
};
test_sodium.prototype.sign = function() {
// Detached signatures: https://github.com/paixaop/node-sodium/issues/22
const signer = new sodium.Sign(this.key);
const sig = signer.sign(_message, 'utf8');
this.sig = sig.sign.slice(0, 64).toString('base64');
};
test_sodium.prototype.verify = function() {
const input = {
sign: Buffer.concat([
new Buffer(this.sig, 'base64'),
new Buffer(_message, 'utf8')
]),
publicKey: new Buffer(_pubkey, 'base64')
};
const r = sodium.Sign.verify(input);
assert(r, "Verification failed!");
};
test_sodium.prototype.validate = function() {
assert(new Buffer(this.key.pk().get()).toString('base64') === _pubkey, "wrong public key");
assert(this.sig === _sig, "wrong signature");
};
/*********************** Sodium-universal tests ***************************/
const test_sodium_universal = function() {
this._seed = Buffer.from(_seed, 'base64')
this.pubkey = Buffer.alloc(uSodium.crypto_sign_PUBLICKEYBYTES),
this.secretKey = Buffer.alloc(uSodium.crypto_sign_SECRETKEYBYTES)
this.sig = Buffer.alloc(uSodium.crypto_sign_BYTES)
}
test_sodium_universal.prototype.fromSeed = function() {
const key = new uSodium.crypto_sign_seed_keypair(
this.pubkey, this.secretKey, this._seed
)
}
test_sodium_universal.prototype.sign = function() {
const sig = uSodium.crypto_sign_detached(this.sig, Buffer.from(_message), this.secretKey)
}
test_sodium_universal.prototype.verify = function() {
r = uSodium.crypto_sign_verify_detached(this.sig, Buffer.from(_message), this.pubkey)
assert(r, "Verification failed")
}
const test_sodium_javascript = function() {
this._seed = Buffer.from(_seed, 'base64')
this.pubkey = Buffer.alloc(jSodium.crypto_sign_PUBLICKEYBYTES),
this.secretKey = Buffer.alloc(jSodium.crypto_sign_SECRETKEYBYTES)
this.sig = Buffer.alloc(jSodium.crypto_sign_BYTES)
}
test_sodium_javascript.prototype.fromSeed = function() {
const key = new jSodium.crypto_sign_seed_keypair(
this.pubkey, this.secretKey, this._seed
)
}
test_sodium_javascript.prototype.sign = function() {
const sig = jSodium.crypto_sign_detached(this.sig, Buffer.from(_message), this.secretKey)
}
test_sodium_javascript.prototype.verify = function() {
r = jSodium.crypto_sign_verify_detached(this.sig, Buffer.from(_message), this.pubkey)
assert(r, "Verification failed")
}
/*********************** Actual tests ***************************/
console.log("Correctness Testing:");
console.log(" - testing sodium");
const sod = new test_sodium();
sod.fromSeed();
sod.sign();
sod.verify();
sod.validate();
console.log(" - testing tweetnacl");
const tw1 = new test_tweetnacl(tweetnacl);
tw1.fromSeed();
tw1.sign();
tw1.verify();
tw1.validate();
console.log(" - testing tweetnacl-fast");
const tw2 = new test_tweetnacl(tweetnaclfast);
tw2.fromSeed();
tw2.sign();
tw2.verify();
tw2.validate();
console.log(" - testing sodium-universal")
const usod = new test_sodium_universal()
usod.fromSeed()
usod.sign()
usod.verify()
console.log(" - testing sodium-javascript")
const jsod = new test_sodium_javascript()
jsod.fromSeed()
jsod.sign()
jsod.verify()
/*********************** Benchmark FromSeed ***************************/
console.log("\nBenchmarkmark FromSeed:");
new Benchmark.Suite()
.add('sodium.fromSeed', function() {
sod.fromSeed();
})
.add('sodium-universal.fromSeed', function() {
usod.fromSeed();
})
.add('sodium-javascript.fromSeed', function() {
jsod.fromSeed();
})
.add('tweetnacl.fromSeed', function() {
tw1.fromSeed();
})
.add('tweetnacl-fast.fromSeed', function() {
tw2.fromSeed();
})
.on('cycle', function(event) {
console.log(String(event.target));
})
.run();
/*********************** Benchmark sign ***************************/
console.log("\nBenchmarkmark Sign:");
new Benchmark.Suite()
.add('sodium.sign', function() {
sod.sign();
})
.add('sodium-universal.sign', function() {
usod.sign();
})
.add('sodium-javascript.sign', function() {
jsod.sign();
})
.add('tweetnacl.sign', function() {
tw1.sign();
})
.add('tweetnacl-fast.sign', function() {
tw2.sign();
})
.on('cycle', function(event) {
console.log(String(event.target));
})
.run();
/*********************** Benchmark verify ***************************/
console.log("\nBenchmarkmark Verify:");
new Benchmark.Suite()
.add('sodium.verify', function() {
sod.verify();
})
.add('sodium-universal.verify', function() {
usod.verify();
})
.add('sodium-javascript.verify', function() {
jsod.verify();
})
.add('tweetnacl.verify', function() {
tw1.verify();
})
.add('tweetnacl-fast.verify', function() {
tw2.verify();
})
.on('cycle', function(event) {
console.log(String(event.target));
})
.run();
console.log("\nDone");
{
"name": "crypto-benchmarks",
"version": "0.0.0",
"private": true,
"dependencies": {
"asn1.js": "^5.0.1",
"benchmark": "^2.1.4",
"debug": "^4.1.0",
"ecdsa": "^0.7.0",
"eckey": "^1.0.0",
"elliptic": "^6.4.1",
"lodash": "^4.17.11",
"microtime": "^2.1.8",
"promise": "^8.0.2",
"sodium": "^3.0.2",
"sodium-universal": "^2.0.0",
"tweetnacl": "^1.0.0"
}
}
Correctness Testing:
- testing sodium
- testing tweetnacl
- testing tweetnacl-fast
- testing sodium-universal
- testing sodium-javascript
Benchmarkmark FromSeed:
sodium.fromSeed x 19,572 ops/sec ±5.14% (72 runs sampled)
sodium-universal.fromSeed x 48,908 ops/sec ±0.56% (94 runs sampled)
sodium-javascript.fromSeed x 221 ops/sec ±2.44% (64 runs sampled)
tweetnacl.fromSeed x 225 ops/sec ±1.60% (65 runs sampled)
tweetnacl-fast.fromSeed x 224 ops/sec ±1.94% (65 runs sampled)
Benchmarkmark Sign:
sodium.sign x 29,141 ops/sec ±13.24% (70 runs sampled)
sodium-universal.sign x 38,576 ops/sec ±5.90% (83 runs sampled)
sodium-javascript.sign x 213 ops/sec ±5.47% (64 runs sampled)
tweetnacl.sign x 200 ops/sec ±4.83% (62 runs sampled)
tweetnacl-fast.sign x 237 ops/sec ±4.02% (67 runs sampled)
Benchmarkmark Verify:
sodium.verify x 13,368 ops/sec ±5.44% (85 runs sampled)
sodium-universal.verify x 14,389 ops/sec ±2.52% (85 runs sampled)
sodium-javascript.verify x 108 ops/sec ±2.01% (64 runs sampled)
tweetnacl.verify x 102 ops/sec ±4.87% (61 runs sampled)
tweetnacl-fast.verify x 110 ops/sec ±1.66% (65 runs sampled)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment