crypto: Move encoding logic to JS, default=buffer
authorisaacs <i@izs.me>
Wed, 10 Oct 2012 22:44:47 +0000 (15:44 -0700)
committerisaacs <i@izs.me>
Tue, 23 Oct 2012 17:22:42 +0000 (10:22 -0700)
crypto: Hash and Hmac default to buffers

crypto: Move Cipher encoding logic to JS

crypto: Move Cipheriv encoding logic to JS

crypto: Move Decipher encoding logic to JS

crypto: Move Decipheriv into JS, default to buffers

crypto: Move Sign class to JS

crypto: Better encoding handling in Hash.update

crypto: Move Verify class to JS

crypto: Move DiffieHellman to JS, default to buffers

crypto: Move DiffieHellmanGroup to JS, default to buffers

Also, create a test for this feature

doc/api/crypto.markdown
lib/crypto.js
test/simple/test-crypto-padding-aes256.js
test/simple/test-crypto.js

index 275e4b7..e3ce72a 100644 (file)
@@ -87,14 +87,15 @@ Returned by `crypto.createHash`.
 
 Updates the hash content with the given `data`, the encoding of which is given
 in `input_encoding` and can be `'buffer'`, `'utf8'`, `'ascii'` or `'binary'`.
-Defaults to `'binary'`.
+Defaults to `'buffer'`.
+
 This can be called many times with new data as it is streamed.
 
 ### hash.digest([encoding])
 
 Calculates the digest of all of the passed data to be hashed.
 The `encoding` can be `'buffer'`, `'hex'`, `'binary'` or `'base64'`.
-Defaults to `'binary'`.
+Defaults to `'buffer'`.
 
 Note: `hash` object can not be used after `digest()` method been called.
 
@@ -121,7 +122,7 @@ This can be called many times with new data as it is streamed.
 
 Calculates the digest of all of the passed data to the hmac.
 The `encoding` can be `'buffer'`, `'hex'`, `'binary'` or `'base64'`.
-Defaults to `'binary'`.
+Defaults to `'buffer'`.
 
 Note: `hmac` object can not be used after `digest()` method been called.
 
@@ -157,17 +158,18 @@ Returned by `crypto.createCipher` and `crypto.createCipheriv`.
 
 Updates the cipher with `data`, the encoding of which is given in
 `input_encoding` and can be `'buffer'`, `'utf8'`, `'ascii'` or `'binary'`.
-Defaults to `'binary'`.
+Defaults to `'buffer'`.
 
 The `output_encoding` specifies the output format of the enciphered data,
-and can be `'buffer'`, `'binary'`, `'base64'` or `'hex'`. Defaults to `'binary'`.
+and can be `'buffer'`, `'binary'`, `'base64'` or `'hex'`. Defaults to
+`'buffer'`.
 
 Returns the enciphered contents, and can be called many times with new data as it is streamed.
 
 ### cipher.final([output_encoding])
 
 Returns any remaining enciphered contents, with `output_encoding` being one of:
-`'buffer'`, `'binary'`, `'base64'` or `'hex'`. Defaults to `'binary'`.
+`'buffer'`, `'binary'`, `'base64'` or `'hex'`. Defaults to `'buffer'`.
 
 Note: `cipher` object can not be used after `final()` method been called.
 
@@ -197,18 +199,18 @@ Returned by `crypto.createDecipher` and `crypto.createDecipheriv`.
 ### decipher.update(data, [input_encoding], [output_encoding])
 
 Updates the decipher with `data`, which is encoded in `'buffer'`, `'binary'`,
-`'base64'` or `'hex'`. Defaults to `'binary'`.
+`'base64'` or `'hex'`. Defaults to `'buffer'`.
 
 The `output_decoding` specifies in what format to return the deciphered
 plaintext: `'buffer'`, `'binary'`, `'ascii'` or `'utf8'`.
-Defaults to `'binary'`.
+Defaults to `'buffer'`.
 
 ### decipher.final([output_encoding])
 
 Returns any remaining plaintext which is deciphered,
 with `output_encoding` being one of: `'buffer'`, `'binary'`, `'ascii'` or
 `'utf8'`.
-Defaults to `'binary'`.
+Defaults to `'buffer'`.
 
 Note: `decipher` object can not be used after `final()` method been called.
 
@@ -241,7 +243,7 @@ Calculates the signature on all the updated data passed through the signer.
 `private_key` is a string containing the PEM encoded private key for signing.
 
 Returns the signature in `output_format` which can be `'buffer'`, `'binary'`,
-`'hex'` or `'base64'`. Defaults to `'binary'`.
+`'hex'` or `'base64'`. Defaults to `'buffer'`.
 
 Note: `signer` object can not be used after `sign()` method been called.
 
@@ -267,7 +269,7 @@ Verifies the signed data by using the `object` and `signature`. `object` is  a
 string containing a PEM encoded object, which can be one of RSA public key,
 DSA public key, or X.509 certificate. `signature` is the previously calculated
 signature for the data, in the `signature_format` which can be `'buffer'`,
-`'binary'`, `'hex'` or `'base64'`. Defaults to `'binary'`.
+`'binary'`, `'hex'` or `'base64'`. Defaults to `'buffer'`.
 
 Returns true or false depending on the validity of the signature for the data and public key.
 
@@ -283,7 +285,7 @@ given bit length. The generator used is `2`.
 Creates a Diffie-Hellman key exchange object using the supplied prime. The
 generator used is `2`. Encoding can be `'buffer'`, `'binary'`, `'hex'`, or
 `'base64'`.
-Defaults to `'binary'`.
+Defaults to `'buffer'`.
 
 ## Class: DiffieHellman
 
@@ -296,7 +298,7 @@ Returned by `crypto.createDiffieHellman`.
 Generates private and public Diffie-Hellman key values, and returns the
 public key in the specified encoding. This key should be transferred to the
 other party. Encoding can be `'binary'`, `'hex'`, or `'base64'`.
-Defaults to `'binary'`.
+Defaults to `'buffer'`.
 
 ### diffieHellman.computeSecret(other_public_key, [input_encoding], [output_encoding])
 
@@ -304,38 +306,39 @@ Computes the shared secret using `other_public_key` as the other party's
 public key and returns the computed shared secret. Supplied key is
 interpreted using specified `input_encoding`, and secret is encoded using
 specified `output_encoding`. Encodings can be `'buffer'`, `'binary'`, `'hex'`,
-or `'base64'`. The input encoding defaults to `'binary'`.
+or `'base64'`. The input encoding defaults to `'buffer'`.
 If no output encoding is given, the input encoding is used as output encoding.
 
 ### diffieHellman.getPrime([encoding])
 
 Returns the Diffie-Hellman prime in the specified encoding, which can be
-`'buffer'`, `'binary'`, `'hex'`, or `'base64'`. Defaults to `'binary'`.
+`'buffer'`, `'binary'`, `'hex'`, or `'base64'`. Defaults to `'buffer'`.
 
 ### diffieHellman.getGenerator([encoding])
 
 Returns the Diffie-Hellman prime in the specified encoding, which can be
-`'buffer'`, `'binary'`, `'hex'`, or `'base64'`. Defaults to `'binary'`.
+`'buffer'`, `'binary'`, `'hex'`, or `'base64'`. Defaults to `'buffer'`.
 
 ### diffieHellman.getPublicKey([encoding])
 
 Returns the Diffie-Hellman public key in the specified encoding, which can
-be `'binary'`, `'hex'`, or `'base64'`. Defaults to `'binary'`.
+be `'binary'`, `'hex'`, or `'base64'`. Defaults to `'buffer'`.
 
 ### diffieHellman.getPrivateKey([encoding])
 
 Returns the Diffie-Hellman private key in the specified encoding, which can
-be `'buffer'`, `'binary'`, `'hex'`, or `'base64'`. Defaults to `'binary'`.
+be `'buffer'`, `'binary'`, `'hex'`, or `'base64'`. Defaults to
+`'buffer'`.
 
 ### diffieHellman.setPublicKey(public_key, [encoding])
 
 Sets the Diffie-Hellman public key. Key encoding can be `'buffer', ``'binary'`,
-`'hex'` or `'base64'`. Defaults to `'binary'`.
+`'hex'` or `'base64'`. Defaults to `'buffer'`.
 
 ### diffieHellman.setPrivateKey(public_key, [encoding])
 
 Sets the Diffie-Hellman private key. Key encoding can be `'buffer'`, `'binary'`,
-`'hex'` or `'base64'`. Defaults to `'binary'`.
+`'hex'` or `'base64'`. Defaults to `'buffer'`.
 
 ## crypto.getDiffieHellman(group_name)
 
@@ -361,8 +364,8 @@ Example (obtaining a shared secret):
     alice.generateKeys();
     bob.generateKeys();
 
-    var alice_secret = alice.computeSecret(bob.getPublicKey(), 'binary', 'hex');
-    var bob_secret = bob.computeSecret(alice.getPublicKey(), 'binary', 'hex');
+    var alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
+    var bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
 
     /* alice_secret and bob_secret should be the same */
     console.log(alice_secret == bob_secret);
index 3d3affa..50e6af5 100644 (file)
 try {
   var binding = process.binding('crypto');
   var SecureContext = binding.SecureContext;
-  var Hmac = binding.Hmac;
-  var Hash = binding.Hash;
-  var Cipher = binding.Cipher;
-  var Decipher = binding.Decipher;
-  var Sign = binding.Sign;
-  var Verify = binding.Verify;
-  var DiffieHellman = binding.DiffieHellman;
-  var DiffieHellmanGroup = binding.DiffieHellmanGroup;
   var PBKDF2 = binding.PBKDF2;
   var randomBytes = binding.randomBytes;
   var pseudoRandomBytes = binding.pseudoRandomBytes;
@@ -42,6 +34,8 @@ try {
   var crypto = false;
 }
 
+var assert = require('assert');
+var StringDecoder = require('string_decoder').StringDecoder;
 
 function Credentials(secureProtocol, flags, context) {
   if (!(this instanceof Credentials)) {
@@ -129,65 +123,285 @@ exports.createCredentials = function(options, context) {
 };
 
 
-exports.Hash = Hash;
-exports.createHash = function(hash) {
-  return new Hash(hash);
+exports.createHash = exports.Hash = Hash;
+function Hash(algorithm) {
+  if (!(this instanceof Hash))
+    return new Hash(algorithm);
+  this._binding = new binding.Hash(algorithm);
+}
+
+Hash.prototype.update = function(data, encoding) {
+  if (encoding === 'buffer')
+    encoding = null;
+  if (encoding || typeof data === 'string')
+    data = new Buffer(data, encoding);
+  this._binding.update(data);
+  return this;
+};
+
+Hash.prototype.digest = function(outputEncoding) {
+  var result = this._binding.digest('buffer');
+  if (outputEncoding && outputEncoding !== 'buffer')
+    result = result.toString(outputEncoding);
+  return result;
 };
 
 
-exports.Hmac = Hmac;
-exports.createHmac = function(hmac, key) {
-  return (new Hmac).init(hmac, key);
+exports.createHmac = exports.Hmac = Hmac;
+
+function Hmac(hmac, key) {
+  if (!(this instanceof Hmac))
+    return new Hmac(hmac, key);
+  this._binding = new binding.Hmac();
+  this._binding.init(hmac, key);
 };
 
+Hmac.prototype.update = Hash.prototype.update;
+Hmac.prototype.digest = Hash.prototype.digest;
+
+
+function getDecoder(decoder, encoding) {
+  decoder = decoder || new StringDecoder(encoding);
+  assert(decoder.encoding === encoding, 'Cannot change encoding');
+  return decoder;
+}
+
 
-exports.Cipher = Cipher;
-exports.createCipher = function(cipher, password) {
-  return (new Cipher).init(cipher, password);
+exports.createCipher = exports.Cipher = Cipher;
+function Cipher(cipher, password) {
+  if (!(this instanceof Cipher))
+    return new Cipher(cipher, password);
+  this._binding = new binding.Cipher;
+  this._binding.init(cipher, password);
+  this._decoder = null;
 };
 
+Cipher.prototype.update = function(data, inputEncoding, outputEncoding) {
+  if (inputEncoding && inputEncoding !== 'buffer')
+    data = new Buffer(data, inputEncoding);
+
+  var ret = this._binding.update(data, 'buffer', 'buffer');
+
+  if (outputEncoding && outputEncoding !== 'buffer') {
+    this._decoder = getDecoder(this._decoder, outputEncoding);
+    ret = this._decoder.write(ret);
+  }
 
-exports.createCipheriv = function(cipher, key, iv) {
-  return (new Cipher).initiv(cipher, key, iv);
+  return ret;
 };
 
+Cipher.prototype.final = function(outputEncoding) {
+  var ret = this._binding.final('buffer');
+
+  if (outputEncoding && outputEncoding !== 'buffer') {
+    this._decoder = getDecoder(this._decoder, outputEncoding);
+    ret = this._decoder.write(ret);
+  }
+
+  return ret;
+};
 
-exports.Decipher = Decipher;
-exports.createDecipher = function(cipher, password) {
-  return (new Decipher).init(cipher, password);
+Cipher.prototype.setAutoPadding = function(ap) {
+  this._binding.setAutoPadding(ap);
+  return this;
 };
 
 
-exports.createDecipheriv = function(cipher, key, iv) {
-  return (new Decipher).initiv(cipher, key, iv);
+
+exports.createCipheriv = exports.Cipheriv = Cipheriv;
+function Cipheriv(cipher, key, iv) {
+  if (!(this instanceof Cipheriv))
+    return new Cipheriv(cipher, key, iv);
+  this._binding = new binding.Cipher();
+  this._binding.initiv(cipher, key, iv);
+  this._decoder = null;
+}
+
+Cipheriv.prototype.update = Cipher.prototype.update;
+Cipheriv.prototype.final = Cipher.prototype.final;
+Cipheriv.prototype.setAutoPadding = Cipher.prototype.setAutoPadding;
+
+
+exports.createDecipher = exports.Decipher = Decipher;
+function Decipher(cipher, password) {
+  if (!(this instanceof Decipher))
+    return new Decipher(cipher, password);
+  this._binding = new binding.Decipher
+  this._binding.init(cipher, password);
+  this._decoder = null;
 };
 
+Decipher.prototype.update = Cipher.prototype.update;
+Decipher.prototype.final = Cipher.prototype.final;
+Decipher.prototype.finaltol = Cipher.prototype.final;
+Decipher.prototype.setAutoPadding = Cipher.prototype.setAutoPadding;
+
 
-exports.Sign = Sign;
-exports.createSign = function(algorithm) {
-  return (new Sign).init(algorithm);
+exports.createDecipheriv = exports.Decipheriv = Decipheriv;
+function Decipheriv(cipher, key, iv) {
+  if (!(this instanceof Decipheriv))
+    return new Decipheriv(cipher, key, iv);
+  this._binding = new binding.Decipher;
+  this._binding.initiv(cipher, key, iv);
+  this._decoder = null;
 };
 
-exports.Verify = Verify;
-exports.createVerify = function(algorithm) {
-  return (new Verify).init(algorithm);
+Decipheriv.prototype.update = Cipher.prototype.update;
+Decipheriv.prototype.final = Cipher.prototype.final;
+Decipheriv.prototype.finaltol = Cipher.prototype.final;
+Decipheriv.prototype.setAutoPadding = Cipher.prototype.setAutoPadding;
+
+
+exports.createSign = exports.Sign = Sign;
+function Sign(algorithm) {
+  if (!(this instanceof Sign))
+    return new Sign(algorithm);
+  this._binding = new binding.Sign();
+  this._binding.init(algorithm);
 };
 
-exports.DiffieHellman = DiffieHellman;
-exports.createDiffieHellman = function(size_or_key, enc) {
-  if (!size_or_key) {
-    return new DiffieHellman();
-  } else if (!enc) {
-    return new DiffieHellman(size_or_key);
-  } else {
-    return new DiffieHellman(size_or_key, enc);
+Sign.prototype.update = Hash.prototype.update;
+
+Sign.prototype.sign = function(key, encoding) {
+  var ret = this._binding.sign(key, 'buffer');
+  if (encoding && encoding !== 'buffer')
+    ret = ret.toString(encoding);
+  return ret;
+};
+
+
+exports.createVerify = exports.Verify = Verify;
+function Verify(algorithm) {
+  if (!(this instanceof Verify))
+    return new Verify(algorithm);
+
+  this._binding = new binding.Verify;
+  this._binding.init(algorithm);
+}
+
+Verify.prototype.update = Hash.prototype.update;
+
+Verify.prototype.verify = function(object, signature, sigEncoding) {
+  if (sigEncoding === 'buffer')
+    sigEncoding = null;
+  if (sigEncoding || typeof signature === 'string')
+    signature = new Buffer(signature, sigEncoding);
+  return this._binding.verify(object, signature, 'buffer');
+};
+
+exports.createDiffieHellman = exports.DiffieHellman = DiffieHellman;
+
+function DiffieHellman(sizeOrKey, encoding) {
+  if (!(this instanceof DiffieHellman))
+    return new DiffieHellman(sizeOrKey, encoding);
+
+  if (!sizeOrKey)
+    this._binding = new binding.DiffieHellman();
+  else {
+    if (encoding === 'buffer')
+      encoding = null;
+    if (encoding || typeof sizeOrKey === 'string')
+      sizeOrKey = new Buffer(sizeOrKey, encoding);
+    this._binding = new binding.DiffieHellman(sizeOrKey, 'buffer');
   }
+}
+
+DiffieHellman.prototype.generateKeys = function(encoding) {
+  var keys = this._binding.generateKeys('buffer');
+  if (encoding)
+    keys = keys.toString(encoding);
+  return keys;
+};
+
+DiffieHellman.prototype.computeSecret = function(key, inEnc, outEnc) {
+  if (inEnc === 'buffer')
+    inEnc = null;
+  if (outEnc === 'buffer')
+    outEnc = null;
+  if (inEnc || typeof key === 'string')
+    key = new Buffer(key, inEnc);
+  var ret = this._binding.computeSecret(key, 'buffer', 'buffer');
+  if (outEnc)
+    ret = ret.toString(outEnc);
+  return ret;
+};
+
+DiffieHellman.prototype.getPrime = function(encoding) {
+  var prime = this._binding.getPrime('buffer');
+  if (encoding && encoding !== 'buffer')
+    prime = prime.toString(encoding);
+  return prime;
+};
+
+DiffieHellman.prototype.getGenerator = function(encoding) {
+  var generator = this._binding.getGenerator('buffer');
+  if (encoding && encoding !== 'buffer')
+    generator = generator.toString(encoding);
+  return generator;
+};
 
+DiffieHellman.prototype.getPublicKey = function(encoding) {
+  var key = this._binding.getPublicKey('buffer');
+  if (encoding && encoding !== 'buffer')
+    key = key.toString(encoding);
+  return key;
 };
-exports.getDiffieHellman = function(group_name) {
-  return new DiffieHellmanGroup(group_name);
+
+DiffieHellman.prototype.getPrivateKey = function(encoding) {
+  var key = this._binding.getPrivateKey('buffer');
+  if (encoding && encoding !== 'buffer')
+    key = key.toString(encoding);
+  return key;
 };
 
+DiffieHellman.prototype.setPublicKey = function(key, encoding) {
+  if (encoding === 'buffer')
+    encoding = null;
+  if (encoding || typeof key === 'string')
+    key = new Buffer(key, encoding);
+  this._binding.setPublicKey(key, 'buffer');
+  return this;
+};
+
+DiffieHellman.prototype.setPrivateKey = function(key, encoding) {
+  if (encoding === 'buffer')
+    encoding = null;
+  if (encoding || typeof key === 'string')
+    key = new Buffer(key, encoding);
+  this._binding.setPrivateKey(key, 'buffer');
+  return this;
+};
+
+
+
+exports.DiffieHellmanGroup =
+  exports.createDiffieHellmanGroup =
+  exports.getDiffieHellman = DiffieHellmanGroup;
+
+function DiffieHellmanGroup(name) {
+  if (!(this instanceof DiffieHellmanGroup))
+    return new DiffieHellmanGroup(name);
+  this._binding = new binding.DiffieHellmanGroup(name);
+};
+
+DiffieHellmanGroup.prototype.generateKeys =
+  DiffieHellman.prototype.generateKeys;
+
+DiffieHellmanGroup.prototype.computeSecret =
+  DiffieHellman.prototype.computeSecret;
+
+DiffieHellmanGroup.prototype.getPrime =
+  DiffieHellman.prototype.getPrime;
+
+DiffieHellmanGroup.prototype.getGenerator =
+  DiffieHellman.prototype.getGenerator;
+
+DiffieHellmanGroup.prototype.getPublicKey =
+  DiffieHellman.prototype.getPublicKey;
+
+DiffieHellmanGroup.prototype.getPrivateKey =
+  DiffieHellman.prototype.getPrivateKey;
+
 exports.pbkdf2 = PBKDF2;
 
 exports.randomBytes = randomBytes;
index e3b5518..20574ec 100644 (file)
@@ -43,7 +43,7 @@ function aes256(decipherFinal) {
   function decrypt(val, pad) {
         var c = crypto.createDecipheriv('aes256', key, iv);
         c.setAutoPadding(pad);
-        return c.update(val, 'binary', 'binary') + c[decipherFinal]('utf8');
+        return c.update(val, 'binary', 'utf8') + c[decipherFinal]('utf8');
   }
 
   // echo 0123456789abcdef0123456789abcdef \
index bbc35ef..0b70ece 100644 (file)
@@ -376,12 +376,16 @@ assert.equal(a1, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' +
              '\u00bd\u008c', 'Test MD5 as binary');
 assert.equal(a2, '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=',
              'Test SHA256 as base64');
-assert.equal(a3, '\u00c1(4\u00f1\u0003\u001fd\u0097!O\'\u00d4C/&Qz\u00d4' +
-                 '\u0094\u0015l\u00b8\u008dQ+\u00db\u001d\u00c4\u00b5}\u00b2' +
-                 '\u00d6\u0092\u00a3\u00df\u00a2i\u00a1\u009b\n\n*\u000f' +
-                 '\u00d7\u00d6\u00a2\u00a8\u0085\u00e3<\u0083\u009c\u0093' +
-                 '\u00c2\u0006\u00da0\u00a1\u00879(G\u00ed\'',
-             'Test SHA512 as assumed binary');
+assert.deepEqual(
+  a3,
+  new Buffer(
+    '\u00c1(4\u00f1\u0003\u001fd\u0097!O\'\u00d4C/&Qz\u00d4' +
+    '\u0094\u0015l\u00b8\u008dQ+\u00db\u001d\u00c4\u00b5}\u00b2' +
+    '\u00d6\u0092\u00a3\u00df\u00a2i\u00a1\u009b\n\n*\u000f' +
+    '\u00d7\u00d6\u00a2\u00a8\u0085\u00e3<\u0083\u009c\u0093' +
+    '\u00c2\u0006\u00da0\u00a1\u00879(G\u00ed\'',
+    'binary'),
+  'Test SHA512 as assumed buffer');
 assert.deepEqual(a4,
                  new Buffer('8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'hex'),
                  'Test SHA1');
@@ -554,10 +558,10 @@ var privkey1 = dh1.getPrivateKey();
 dh3.setPublicKey(key1);
 dh3.setPrivateKey(privkey1);
 
-assert.equal(dh1.getPrime(), dh3.getPrime());
-assert.equal(dh1.getGenerator(), dh3.getGenerator());
-assert.equal(dh1.getPublicKey(), dh3.getPublicKey());
-assert.equal(dh1.getPrivateKey(), dh3.getPrivateKey());
+assert.deepEqual(dh1.getPrime(), dh3.getPrime());
+assert.deepEqual(dh1.getGenerator(), dh3.getGenerator());
+assert.deepEqual(dh1.getPublicKey(), dh3.getPublicKey());
+assert.deepEqual(dh1.getPrivateKey(), dh3.getPrivateKey());
 
 var secret3 = dh3.computeSecret(key2, 'hex', 'base64');
 
@@ -567,6 +571,16 @@ assert.throws(function() {
   dh3.computeSecret('');
 }, /key is too small/i);
 
+// Create a shared using a DH group.
+var alice = crypto.createDiffieHellmanGroup('modp5');
+var bob = crypto.createDiffieHellmanGroup('modp5');
+alice.generateKeys();
+bob.generateKeys();
+var aSecret = alice.computeSecret(bob.getPublicKey()).toString('hex');
+var bSecret = bob.computeSecret(alice.getPublicKey()).toString('hex');
+assert.equal(aSecret, bSecret);
+
+
 // https://github.com/joyent/node/issues/2338
 assert.throws(function() {
   var p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' +