From 636d66a5c701303b24e584511c9c9782028418b1 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 25 Oct 2017 20:07:22 -0700 Subject: [PATCH] bcoin: use bcrypto. remove crypto module. --- bench/bech32.js | 2 +- bench/chacha.js | 6 +- bench/merkle.js | 4 +- bench/script.js | 2 +- bench/tx.js | 2 +- bench/walletdb.js | 2 +- browser/wsproxy.js | 2 +- lib/bcoin-browser.js | 5 +- lib/bcoin.js | 5 +- lib/bip70/paymentrequest.js | 2 +- lib/bip70/pk.js | 7 +- lib/bip70/x509.js | 2 +- lib/blockchain/chainentry.js | 4 +- lib/coins/compress.js | 2 +- lib/crypto/aead.js | 172 ---- lib/crypto/aes-browser.js | 1321 ------------------------------- lib/crypto/aes.js | 49 -- lib/crypto/bn.js | 19 - lib/crypto/ccmp.js | 36 - lib/crypto/chacha20.js | 205 ----- lib/crypto/cleanse.js | 34 - lib/crypto/digest-browser.js | 122 --- lib/crypto/digest.js | 120 --- lib/crypto/ecdsa.js | 65 -- lib/crypto/hkdf.js | 65 -- lib/crypto/hmac-drbg.js | 120 --- lib/crypto/index.js | 51 -- lib/crypto/merkle.js | 115 --- lib/crypto/pbkdf2-browser.js | 101 --- lib/crypto/pbkdf2.js | 49 -- lib/crypto/poly1305.js | 321 -------- lib/crypto/random-browser.js | 63 -- lib/crypto/random.js | 47 -- lib/crypto/rsa-browser.js | 186 ----- lib/crypto/rsa.js | 72 -- lib/crypto/schnorr.js | 342 -------- lib/crypto/scrypt.js | 269 ------- lib/crypto/secp256k1-browser.js | 345 -------- lib/crypto/secp256k1-native.js | 257 ------ lib/crypto/secp256k1.js | 21 - lib/crypto/sha256.js | 399 ---------- lib/crypto/siphash.js | 304 ------- lib/hd/mnemonic.js | 13 +- lib/hd/private.js | 8 +- lib/hd/public.js | 6 +- lib/http/rpc.js | 6 +- lib/http/server.js | 6 +- lib/mempool/mempool.js | 2 +- lib/mining/common.js | 2 +- lib/mining/mine.js | 2 +- lib/mining/template.js | 16 +- lib/net/bip150.js | 8 +- lib/net/bip151.js | 33 +- lib/net/bip152.js | 4 +- lib/net/framer.js | 2 +- lib/net/parser.js | 2 +- lib/net/pool.js | 2 +- lib/net/proxysocket.js | 2 +- lib/node/node.js | 2 +- lib/primitives/abstractblock.js | 2 +- lib/primitives/address.js | 2 +- lib/primitives/block.js | 10 +- lib/primitives/keyring.js | 4 +- lib/primitives/merkleblock.js | 6 +- lib/primitives/tx.js | 4 +- lib/protocol/consensus.js | 2 +- lib/protocol/networks.js | 2 +- lib/script/common.js | 2 +- lib/script/script.js | 6 +- lib/script/sigcache.js | 2 +- lib/utils/asn1.js | 548 ------------- lib/utils/asyncemitter.js | 4 +- lib/utils/gcs.js | 8 +- lib/utils/index.js | 2 - lib/utils/pem.js | 148 ---- lib/wallet/client.js | 2 +- lib/wallet/http.js | 6 +- lib/wallet/masterkey.js | 13 +- lib/wallet/plugin.js | 3 +- lib/wallet/rpc.js | 2 +- lib/wallet/wallet.js | 4 +- lib/wallet/walletdb.js | 21 +- lib/workers/jobs.js | 4 +- migrate/chaindb2to3.js | 4 +- migrate/compress-old.js | 2 +- migrate/ensure-tip-index.js | 4 +- package.json | 8 +- scripts/fuzz.js | 4 +- test/aes-test.js | 49 -- test/bip150-test.js | 2 +- test/chachapoly-test.js | 235 ------ test/consensus-test.js | 2 +- test/gcs-test.js | 2 +- test/hd-test.js | 10 +- test/hkdf-test.js | 84 -- test/mempool-test.js | 2 +- test/schnorr-test.js | 20 - test/scrypt-test.js | 93 --- test/siphash-test.js | 30 - test/tx-test.js | 2 +- test/wallet-test.js | 4 +- 101 files changed, 165 insertions(+), 6632 deletions(-) delete mode 100644 lib/crypto/aead.js delete mode 100644 lib/crypto/aes-browser.js delete mode 100644 lib/crypto/aes.js delete mode 100644 lib/crypto/bn.js delete mode 100644 lib/crypto/ccmp.js delete mode 100644 lib/crypto/chacha20.js delete mode 100644 lib/crypto/cleanse.js delete mode 100644 lib/crypto/digest-browser.js delete mode 100644 lib/crypto/digest.js delete mode 100644 lib/crypto/ecdsa.js delete mode 100644 lib/crypto/hkdf.js delete mode 100644 lib/crypto/hmac-drbg.js delete mode 100644 lib/crypto/index.js delete mode 100644 lib/crypto/merkle.js delete mode 100644 lib/crypto/pbkdf2-browser.js delete mode 100644 lib/crypto/pbkdf2.js delete mode 100644 lib/crypto/poly1305.js delete mode 100644 lib/crypto/random-browser.js delete mode 100644 lib/crypto/random.js delete mode 100644 lib/crypto/rsa-browser.js delete mode 100644 lib/crypto/rsa.js delete mode 100644 lib/crypto/schnorr.js delete mode 100644 lib/crypto/scrypt.js delete mode 100644 lib/crypto/secp256k1-browser.js delete mode 100644 lib/crypto/secp256k1-native.js delete mode 100644 lib/crypto/secp256k1.js delete mode 100644 lib/crypto/sha256.js delete mode 100644 lib/crypto/siphash.js delete mode 100644 lib/utils/asn1.js delete mode 100644 lib/utils/pem.js delete mode 100644 test/aes-test.js delete mode 100644 test/chachapoly-test.js delete mode 100644 test/hkdf-test.js delete mode 100644 test/schnorr-test.js delete mode 100644 test/scrypt-test.js delete mode 100644 test/siphash-test.js diff --git a/bench/bech32.js b/bench/bech32.js index 3b19c307..002f8183 100644 --- a/bench/bech32.js +++ b/bench/bech32.js @@ -1,7 +1,7 @@ 'use strict'; const Address = require('../lib/primitives/address'); -const random = require('../lib/crypto/random'); +const random = require('bcrypto/lib/random'); const bench = require('./bench'); const addrs = []; diff --git a/bench/chacha.js b/bench/chacha.js index 00249d33..4bc66e7c 100644 --- a/bench/chacha.js +++ b/bench/chacha.js @@ -1,8 +1,8 @@ 'use strict'; -const ChaCha20 = require('../lib/crypto/chacha20'); -const Poly1305 = require('../lib/crypto/poly1305'); -const digest = require('../lib/crypto/digest'); +const ChaCha20 = require('bcrypto/lib/chacha20'); +const Poly1305 = require('bcrypto/lib/poly1305'); +const digest = require('bcrypto/lib/digest'); const bench = require('./bench'); console.log('note: rate measured in kb/s'); diff --git a/bench/merkle.js b/bench/merkle.js index 85f6d6a0..b182e02f 100644 --- a/bench/merkle.js +++ b/bench/merkle.js @@ -1,8 +1,8 @@ 'use strict'; const assert = require('assert'); -const merkle = require('../lib/crypto/merkle'); -const random = require('../lib/crypto/random'); +const merkle = require('bcrypto/lib/merkle'); +const random = require('bcrypto/lib/random'); const bench = require('./bench'); const leaves = []; diff --git a/bench/script.js b/bench/script.js index e138b43c..5d64b10f 100644 --- a/bench/script.js +++ b/bench/script.js @@ -1,6 +1,6 @@ 'use strict'; -const random = require('../lib/crypto/random'); +const random = require('bcrypto/lib/random'); const Script = require('../lib/script/script'); const bench = require('./bench'); diff --git a/bench/tx.js b/bench/tx.js index b6baa7ce..68e86623 100644 --- a/bench/tx.js +++ b/bench/tx.js @@ -5,7 +5,7 @@ const TX = require('../lib/primitives/tx'); const Script = require('../lib/script/script'); const MTX = require('../lib/primitives/mtx'); const encoding = require('../lib/utils/encoding'); -const random = require('../lib/crypto/random'); +const random = require('bcrypto/lib/random'); const common = require('../test/util/common'); const bench = require('./bench'); diff --git a/bench/walletdb.js b/bench/walletdb.js index 226024c8..a399919b 100644 --- a/bench/walletdb.js +++ b/bench/walletdb.js @@ -1,7 +1,7 @@ 'use strict'; const bench = require('./bench'); -const random = require('../lib/crypto/random'); +const random = require('bcrypto/lib/random'); const WalletDB = require('../lib/wallet/walletdb'); const MTX = require('../lib/primitives/mtx'); const Outpoint = require('../lib/primitives/outpoint'); diff --git a/browser/wsproxy.js b/browser/wsproxy.js index 35ba5aba..80414435 100644 --- a/browser/wsproxy.js +++ b/browser/wsproxy.js @@ -5,7 +5,7 @@ const net = require('net'); const EventEmitter = require('events'); const bsock = require('bsock'); const util = require('../lib/utils/util'); -const digest = require('../lib/crypto/digest'); +const digest = require('bcrypto/lib/digest'); const IP = require('../lib/utils/ip'); const BufferWriter = require('../lib/utils/writer'); diff --git a/lib/bcoin-browser.js b/lib/bcoin-browser.js index 1bd05f0f..2b4f15a7 100644 --- a/lib/bcoin-browser.js +++ b/lib/bcoin-browser.js @@ -165,10 +165,7 @@ bcoin.coins = require('./coins'); bcoin.coinview = require('./coins/coinview'); // Crypto -bcoin.crypto = require('./crypto'); -bcoin.bn = require('./crypto/bn'); -bcoin.secp256k1 = require('./crypto/secp256k1'); -bcoin.schnorr = require('./crypto/schnorr'); +bcoin.crypto = require('bcrypto'); // DB bcoin.db = require('./db'); diff --git a/lib/bcoin.js b/lib/bcoin.js index 92dc153f..7b080d5e 100644 --- a/lib/bcoin.js +++ b/lib/bcoin.js @@ -202,10 +202,7 @@ bcoin.define('coins', './coins'); bcoin.define('coinview', './coins/coinview'); // Crypto -bcoin.define('crypto', './crypto'); -bcoin.define('bn', './crypto/bn'); -bcoin.define('secp256k1', './crypto/secp256k1'); -bcoin.define('schnorr', './crypto/schnorr'); +bcoin.define('crypto', 'bcrypto'); // DB bcoin.define('db', './db'); diff --git a/lib/bip70/paymentrequest.js b/lib/bip70/paymentrequest.js index 6fb17555..80a9db83 100644 --- a/lib/bip70/paymentrequest.js +++ b/lib/bip70/paymentrequest.js @@ -8,7 +8,7 @@ const assert = require('assert'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); +const digest = require('bcrypto/lib/digest'); const x509 = require('./x509'); const PEM = require('../utils/pem'); const ProtoReader = require('../utils/protoreader'); diff --git a/lib/bip70/pk.js b/lib/bip70/pk.js index cfd5c6c0..9c103477 100644 --- a/lib/bip70/pk.js +++ b/lib/bip70/pk.js @@ -10,8 +10,9 @@ * @module bip70/pk */ -const rsa = require('../crypto/rsa'); -const ecdsa = require('../crypto/ecdsa'); +const digest = require('bcrypto/lib/digest'); +const rsa = require('bcrypto/lib/rsa'); +const ecdsa = require('bcrypto/lib/ecdsa'); /** * Verify signature with public key. @@ -23,6 +24,7 @@ const ecdsa = require('../crypto/ecdsa'); */ exports.verify = function verify(hash, msg, sig, key) { + hash = digest.get(hash); switch (key.alg) { case 'rsa': return rsa.verify(hash, msg, sig, key.data); @@ -42,6 +44,7 @@ exports.verify = function verify(hash, msg, sig, key) { */ exports.sign = function sign(hash, msg, key) { + hash = digest.get(hash); switch (key.alg) { case 'rsa': return rsa.sign(hash, msg, key.data); diff --git a/lib/bip70/x509.js b/lib/bip70/x509.js index 87bf3507..6ae45925 100644 --- a/lib/bip70/x509.js +++ b/lib/bip70/x509.js @@ -10,7 +10,7 @@ const assert = require('assert'); const ASN1 = require('../utils/asn1'); const PEM = require('../utils/pem'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); +const digest = require('bcrypto/lib/digest'); const pk = require('./pk'); const certs = require('./certs'); diff --git a/lib/blockchain/chainentry.js b/lib/blockchain/chainentry.js index d621869b..2fcc5011 100644 --- a/lib/blockchain/chainentry.js +++ b/lib/blockchain/chainentry.js @@ -8,10 +8,10 @@ 'use strict'; const assert = require('assert'); -const BN = require('../crypto/bn'); +const BN = require('bcrypto/lib/bn'); const consensus = require('../protocol/consensus'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); +const digest = require('bcrypto/lib/digest'); const encoding = require('../utils/encoding'); const BufferReader = require('../utils/reader'); const StaticWriter = require('../utils/staticwriter'); diff --git a/lib/coins/compress.js b/lib/coins/compress.js index 00164942..b45ff2a2 100644 --- a/lib/coins/compress.js +++ b/lib/coins/compress.js @@ -12,7 +12,7 @@ */ const assert = require('assert'); -const secp256k1 = require('../crypto/secp256k1'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const encoding = require('../utils/encoding'); const consensus = require('../protocol/consensus'); diff --git a/lib/crypto/aead.js b/lib/crypto/aead.js deleted file mode 100644 index 13a3a583..00000000 --- a/lib/crypto/aead.js +++ /dev/null @@ -1,172 +0,0 @@ -/*! - * aead.js - aead for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -const assert = require('assert'); -const ChaCha20 = require('./chacha20'); -const Poly1305 = require('./poly1305'); - -/** - * AEAD (used for bip151) - * @alias module:crypto.AEAD - * @constructor - * @see https://github.com/openssh/openssh-portable - * @see https://tools.ietf.org/html/rfc7539#section-2.8 - */ - -function AEAD() { - if (!(this instanceof AEAD)) - return new AEAD(); - - this.chacha20 = new ChaCha20(); - this.poly1305 = new Poly1305(); - this.aadLen = 0; - this.cipherLen = 0; - this.polyKey = null; -} - -/** - * Initialize the AEAD with a key and iv. - * @param {Buffer} key - * @param {Buffer} iv - IV / packet sequence number. - */ - -AEAD.prototype.init = function init(key, iv) { - const polyKey = Buffer.allocUnsafe(32); - polyKey.fill(0); - - this.chacha20.init(key, iv); - this.chacha20.encrypt(polyKey); - this.poly1305.init(polyKey); - - // We need to encrypt a full block - // to get the cipher in the correct state. - this.chacha20.encrypt(Buffer.allocUnsafe(32)); - - // Counter should be one. - assert(this.chacha20.getCounter() === 1); - - // Expose for debugging. - this.polyKey = polyKey; - - this.aadLen = 0; - this.cipherLen = 0; -}; - -/** - * Update the aad (will be finalized - * on an encrypt/decrypt call). - * @param {Buffer} aad - */ - -AEAD.prototype.aad = function aad(data) { - assert(this.cipherLen === 0, 'Cannot update aad.'); - this.poly1305.update(data); - this.aadLen += data.length; -}; - -/** - * Encrypt a piece of data. - * @param {Buffer} data - */ - -AEAD.prototype.encrypt = function encrypt(data) { - if (this.cipherLen === 0) - this.pad16(this.aadLen); - - this.chacha20.encrypt(data); - this.poly1305.update(data); - this.cipherLen += data.length; - - return data; -}; - -/** - * Decrypt a piece of data. - * @param {Buffer} data - */ - -AEAD.prototype.decrypt = function decrypt(data) { - if (this.cipherLen === 0) - this.pad16(this.aadLen); - - this.cipherLen += data.length; - this.poly1305.update(data); - this.chacha20.encrypt(data); - - return data; -}; - -/** - * Authenticate data without decrypting. - * @param {Buffer} data - */ - -AEAD.prototype.auth = function auth(data) { - if (this.cipherLen === 0) - this.pad16(this.aadLen); - - this.cipherLen += data.length; - this.poly1305.update(data); - - return data; -}; - -/** - * Finalize the aead and generate a MAC. - * @returns {Buffer} MAC - */ - -AEAD.prototype.finish = function finish() { - const len = Buffer.allocUnsafe(16); - let lo, hi; - - // The RFC says these are supposed to be - // uint32le, but their own fucking test - // cases fail unless they are uint64le's. - lo = this.aadLen % 0x100000000; - hi = (this.aadLen - lo) / 0x100000000; - len.writeUInt32LE(lo, 0, true); - len.writeUInt32LE(hi, 4, true); - - lo = this.cipherLen % 0x100000000; - hi = (this.cipherLen - lo) / 0x100000000; - len.writeUInt32LE(lo, 8, true); - len.writeUInt32LE(hi, 12, true); - - if (this.cipherLen === 0) - this.pad16(this.aadLen); - - this.pad16(this.cipherLen); - this.poly1305.update(len); - - return this.poly1305.finish(); -}; - -/** - * Pad a chunk before updating mac. - * @private - * @param {Number} size - */ - -AEAD.prototype.pad16 = function pad16(size) { - size %= 16; - - if (size === 0) - return; - - const pad = Buffer.allocUnsafe(16 - size); - pad.fill(0); - - this.poly1305.update(pad); -}; - -/* - * Expose - */ - -module.exports = AEAD; diff --git a/lib/crypto/aes-browser.js b/lib/crypto/aes-browser.js deleted file mode 100644 index b0924ec6..00000000 --- a/lib/crypto/aes-browser.js +++ /dev/null @@ -1,1321 +0,0 @@ -/*! - * aes.js - aes128/192/256 for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - * - * Ported from: - * https://github.com/openssl/openssl/blob/master/crypto/aes/aes_core.c - * Entered into the public domain by Vincent Rijmen. - */ - -'use strict'; - -const assert = require('assert'); - -/** - * @exports crypto.aes-browser - * @ignore - */ - -const AES = exports; - -/* - * Tables - */ - -const TE0 = [ - 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, - 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, - 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, - 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, - 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, - 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, - 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, - 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, - 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, - 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, - 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, - 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, - 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, - 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, - 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, - 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, - 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, - 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, - 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, - 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, - 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, - 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, - 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, - 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, - 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, - 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, - 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, - 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, - 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, - 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, - 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, - 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, - 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, - 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, - 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, - 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, - 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, - 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, - 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, - 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, - 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, - 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, - 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, - 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, - 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, - 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, - 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, - 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, - 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, - 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, - 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, - 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, - 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, - 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, - 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, - 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, - 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, - 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, - 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, - 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, - 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, - 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, - 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, - 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a -]; - -const TE1 = [ - 0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, - 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5, - 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, - 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, - 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, - 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0, - 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, - 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0, - 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, - 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc, - 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1, - 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, - 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, - 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a, - 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, - 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, - 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, - 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, - 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, - 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484, - 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, - 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, - 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, - 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, - 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, - 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585, - 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, - 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, - 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, - 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5, - 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, - 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2, - 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, - 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, - 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, - 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, - 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, - 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888, - 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, - 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, - 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, - 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c, - 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, - 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979, - 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, - 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, - 0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea, - 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, - 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, - 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6, - 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, - 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, - 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, - 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e, - 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, - 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e, - 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, - 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, - 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, - 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, - 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, - 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868, - 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, - 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616 -]; - -const TE2 = [ - 0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, - 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5, - 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, - 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, - 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, - 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, - 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, - 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0, - 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, - 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, - 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, - 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, - 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, - 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a, - 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, - 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, - 0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, - 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, - 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, - 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384, - 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, - 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, - 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, - 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, - 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, - 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185, - 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, - 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, - 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, - 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, - 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, - 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2, - 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, - 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, - 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, - 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, - 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, - 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88, - 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, - 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb, - 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a, - 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c, - 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, - 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279, - 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, - 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, - 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, - 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008, - 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, - 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6, - 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, - 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, - 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, - 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e, - 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, - 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e, - 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, - 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, - 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, - 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, - 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, - 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068, - 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, - 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16 -]; - -const TE3 = [ - 0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, - 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491, - 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, - 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, - 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, - 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, - 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, - 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b, - 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, - 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, - 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, - 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, - 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, - 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f, - 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, - 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, - 0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, - 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, - 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, - 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713, - 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, - 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, - 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, - 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, - 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, - 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411, - 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, - 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, - 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, - 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, - 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, - 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf, - 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, - 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, - 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, - 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, - 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, - 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b, - 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, - 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad, - 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14, - 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8, - 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, - 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2, - 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, - 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, - 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, - 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810, - 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, - 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197, - 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, - 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, - 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, - 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c, - 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, - 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927, - 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, - 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, - 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, - 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, - 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, - 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0, - 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, - 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c -]; - -const TD0 = [ - 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, - 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, - 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, - 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, - 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, - 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, - 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, - 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, - 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, - 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, - 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, - 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, - 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, - 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, - 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, - 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, - 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, - 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, - 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, - 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, - 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, - 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, - 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, - 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, - 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, - 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, - 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, - 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, - 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, - 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, - 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, - 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, - 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, - 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, - 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, - 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, - 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, - 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, - 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, - 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, - 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, - 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, - 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, - 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, - 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, - 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, - 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, - 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, - 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, - 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, - 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, - 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, - 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, - 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, - 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, - 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, - 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, - 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, - 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, - 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, - 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, - 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, - 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, - 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742 -]; - -const TD1 = [ - 0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, - 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303, - 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, - 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, - 0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, - 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9, - 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, - 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8, - 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, - 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, - 0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, - 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b, - 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, - 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab, - 0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, - 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, - 0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, - 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe, - 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, - 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10, - 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, - 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015, - 0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, - 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee, - 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, - 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72, - 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, - 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, - 0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91, - 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a, - 0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, - 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9, - 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, - 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, - 0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, - 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611, - 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, - 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3, - 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, - 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, - 0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, - 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf, - 0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, - 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af, - 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, - 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, - 0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a, - 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8, - 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, - 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266, - 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, - 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6, - 0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, - 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551, - 0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, - 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647, - 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, - 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, - 0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, - 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db, - 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, - 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95, - 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, - 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857 -]; - -const TD2 = [ - 0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, - 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3, - 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, - 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, - 0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe, - 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3, - 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, - 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9, - 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, - 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, - 0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, - 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908, - 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, - 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655, - 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, - 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, - 0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, - 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6, - 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, - 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e, - 0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, - 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, - 0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, - 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8, - 0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, - 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a, - 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, - 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, - 0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, - 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12, - 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, - 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e, - 0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, - 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, - 0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, - 0xdccad731, 0x85104263, 0x22401397, 0x112084c6, - 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, - 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1, - 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, - 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, - 0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4, - 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad, - 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, - 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3, - 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, - 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, - 0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, - 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15, - 0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, - 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2, - 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, - 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, - 0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496, - 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665, - 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, - 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6, - 0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, - 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, - 0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, - 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844, - 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, - 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d, - 0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, - 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8 -]; - -const TD3 = [ - 0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, - 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b, - 0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, - 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, - 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, - 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, - 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, - 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e, - 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, - 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, - 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, - 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9, - 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, - 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66, - 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, - 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced, - 0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e, - 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4, - 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, - 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd, - 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, - 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60, - 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, - 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, - 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, - 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c, - 0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, - 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, - 0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, - 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, - 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, - 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814, - 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, - 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, - 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, - 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, - 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, - 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077, - 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, - 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, - 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, - 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, - 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, - 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582, - 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, - 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, - 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, - 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, - 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, - 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035, - 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, - 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, - 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, - 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, - 0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, - 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d, - 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, - 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, - 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, - 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, - 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, - 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff, - 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, - 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0 -]; - -const TD4 = [ - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, - 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, - 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, - 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, - 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, - 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, - 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, - 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, - 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, - 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, - 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, - 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, - 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, - 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, - 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, - 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, - 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, - 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, - 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, - 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, - 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, - 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, - 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, - 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, - 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, - 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d -]; - -const RCON = [ - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1b000000, 0x36000000 -]; - -/** - * An AES key object for encrypting - * and decrypting blocks. - * @constructor - * @ignore - * @param {Buffer} key - * @param {Number} bits - */ - -function AESKey(key, bits) { - if (!(this instanceof AESKey)) - return new AESKey(key, bits); - - this.rounds = null; - this.userKey = key; - this.bits = bits; - - switch (this.bits) { - case 128: - this.rounds = 10; - break; - case 192: - this.rounds = 12; - break; - case 256: - this.rounds = 14; - break; - default: - throw new Error('Bad key size.'); - } - - assert(Buffer.isBuffer(key)); - assert(key.length === this.bits / 8); - - this.decryptKey = null; - this.encryptKey = null; -} - -/** - * Destroy the object and zero the keys. - */ - -AESKey.prototype.destroy = function destroy() { - assert(this.userKey, 'Already destroyed.'); - - // User should zero this. - this.userKey = null; - - if (this.decryptKey) { - for (let i = 0; i < this.decryptKey.length; i++) - this.decryptKey[i] = 0; - this.decryptKey = null; - } - - if (this.encryptKey) { - for (let i = 0; i < this.encryptKey.length; i++) - this.encryptKey[i] = 0; - this.encryptKey = null; - } -}; - -/** - * Convert the user key into an encryption key. - * @returns {Uint32Array} key - */ - -AESKey.prototype.getEncryptKey = function getEncryptKey() { - assert(this.userKey, 'Cannot use key once it is destroyed.'); - - if (this.encryptKey) - return this.encryptKey; - - const key = new Uint32Array(60); - let kp = 0; - let i = 0; - - key[kp + 0] = readU32(this.userKey, 0); - key[kp + 1] = readU32(this.userKey, 4); - key[kp + 2] = readU32(this.userKey, 8); - key[kp + 3] = readU32(this.userKey, 12); - - this.encryptKey = key; - - if (this.bits === 128) { - for (;;) { - const tmp = key[kp + 3]; - - key[kp + 4] = key[kp + 0] - ^ (TE2[(tmp >>> 16) & 0xff] & 0xff000000) - ^ (TE3[(tmp >>> 8) & 0xff] & 0x00ff0000) - ^ (TE0[(tmp >>> 0) & 0xff] & 0x0000ff00) - ^ (TE1[(tmp >>> 24) & 0xff] & 0x000000ff) - ^ RCON[i]; - key[kp + 5] = key[kp + 1] ^ key[kp + 4]; - key[kp + 6] = key[kp + 2] ^ key[kp + 5]; - key[kp + 7] = key[kp + 3] ^ key[kp + 6]; - - if (++i === 10) - return key; - - kp += 4; - } - } - - key[kp + 4] = readU32(this.userKey, 16); - key[kp + 5] = readU32(this.userKey, 20); - - if (this.bits === 192) { - for (;;) { - const tmp = key[kp + 5]; - - key[kp + 6] = key[kp + 0] - ^ (TE2[(tmp >>> 16) & 0xff] & 0xff000000) - ^ (TE3[(tmp >>> 8) & 0xff] & 0x00ff0000) - ^ (TE0[(tmp >>> 0) & 0xff] & 0x0000ff00) - ^ (TE1[(tmp >>> 24) & 0xff] & 0x000000ff) - ^ RCON[i]; - key[kp + 7] = key[kp + 1] ^ key[kp + 6]; - key[kp + 8] = key[kp + 2] ^ key[kp + 7]; - key[kp + 9] = key[kp + 3] ^ key[kp + 8]; - - if (++i === 8) - return key; - - key[kp + 10] = key[kp + 4] ^ key[kp + 9]; - key[kp + 11] = key[kp + 5] ^ key[kp + 10]; - kp += 6; - } - } - - key[kp + 6] = readU32(this.userKey, 24); - key[kp + 7] = readU32(this.userKey, 28); - - if (this.bits === 256) { - for (;;) { - let tmp = key[kp + 7]; - - key[kp + 8] = key[kp + 0] - ^ (TE2[(tmp >>> 16) & 0xff] & 0xff000000) - ^ (TE3[(tmp >>> 8) & 0xff] & 0x00ff0000) - ^ (TE0[(tmp >>> 0) & 0xff] & 0x0000ff00) - ^ (TE1[(tmp >>> 24) & 0xff] & 0x000000ff) - ^ RCON[i]; - key[kp + 9] = key[kp + 1] ^ key[kp + 8]; - key[kp + 10] = key[kp + 2] ^ key[kp + 9]; - key[kp + 11] = key[kp + 3] ^ key[kp + 10]; - - if (++i === 7) - return key; - - tmp = key[kp + 11]; - - key[kp + 12] = key[kp + 4] - ^ (TE2[(tmp >>> 24) & 0xff] & 0xff000000) - ^ (TE3[(tmp >>> 16) & 0xff] & 0x00ff0000) - ^ (TE0[(tmp >>> 8) & 0xff] & 0x0000ff00) - ^ (TE1[(tmp >>> 0) & 0xff] & 0x000000ff); - key[kp + 13] = key[kp + 5] ^ key[kp + 12]; - key[kp + 14] = key[kp + 6] ^ key[kp + 13]; - key[kp + 15] = key[kp + 7] ^ key[kp + 14]; - - kp += 8; - } - } - - return key; -}; - -/** - * Convert the user key into a decryption key. - * @returns {Uint32Array} key - */ - -AESKey.prototype.getDecryptKey = function getDecryptKey() { - assert(this.userKey, 'Cannot use key once it is destroyed.'); - - if (this.decryptKey) - return this.decryptKey; - - // First, start with an encryption schedule. - const enc = this.getEncryptKey(); - const key = new Uint32Array(60); - let kp = 0; - - for (let i = 0; i < enc.length; i++) - key[i] = enc[i]; - - this.decryptKey = key; - - // Invert the order of the round keys. - for (let i = 0, j = 4 * this.rounds; i < j; i += 4, j -= 4) { - let tmp = key[kp + i + 0]; - - key[kp + i + 0] = key[kp + j + 0]; - key[kp + j + 0] = tmp; - - tmp = key[kp + i + 1]; - key[kp + i + 1] = key[kp + j + 1]; - key[kp + j + 1] = tmp; - - tmp = key[kp + i + 2]; - key[kp + i + 2] = key[kp + j + 2]; - key[kp + j + 2] = tmp; - - tmp = key[kp + i + 3]; - key[kp + i + 3] = key[kp + j + 3]; - key[kp + j + 3] = tmp; - } - - // Apply the inverse MixColumn transform to - // all round keys but the first and the last. - for (let i = 1; i < this.rounds; i++) { - kp += 4; - key[kp + 0] = TD0[TE1[(key[kp + 0] >>> 24) & 0xff] & 0xff] - ^ TD1[TE1[(key[kp + 0] >>> 16) & 0xff] & 0xff] - ^ TD2[TE1[(key[kp + 0] >>> 8) & 0xff] & 0xff] - ^ TD3[TE1[(key[kp + 0] >>> 0) & 0xff] & 0xff]; - key[kp + 1] = TD0[TE1[(key[kp + 1] >>> 24) & 0xff] & 0xff] - ^ TD1[TE1[(key[kp + 1] >>> 16) & 0xff] & 0xff] - ^ TD2[TE1[(key[kp + 1] >>> 8) & 0xff] & 0xff] - ^ TD3[TE1[(key[kp + 1] >>> 0) & 0xff] & 0xff]; - key[kp + 2] = TD0[TE1[(key[kp + 2] >>> 24) & 0xff] & 0xff] - ^ TD1[TE1[(key[kp + 2] >>> 16) & 0xff] & 0xff] - ^ TD2[TE1[(key[kp + 2] >>> 8) & 0xff] & 0xff] - ^ TD3[TE1[(key[kp + 2] >>> 0) & 0xff] & 0xff]; - key[kp + 3] = TD0[TE1[(key[kp + 3] >>> 24) & 0xff] & 0xff] - ^ TD1[TE1[(key[kp + 3] >>> 16) & 0xff] & 0xff] - ^ TD2[TE1[(key[kp + 3] >>> 8) & 0xff] & 0xff] - ^ TD3[TE1[(key[kp + 3] >>> 0) & 0xff] & 0xff]; - } - - return key; -}; - -/** - * Encrypt a 16 byte block of data. - * @param {Buffer} input - * @returns {Buffer} - */ - -AESKey.prototype.encryptBlock = function encryptBlock(input) { - assert(this.userKey, 'Cannot use key once it is destroyed.'); - - const key = this.getEncryptKey(); - let kp = 0; - - // Map byte array block to cipher - // state and add initial round key. - let s0 = readU32(input, 0) ^ key[0]; - let s1 = readU32(input, 4) ^ key[1]; - let s2 = readU32(input, 8) ^ key[2]; - let s3 = readU32(input, 12) ^ key[3]; - - // Nr - 1 full rounds - let r = this.rounds >>> 1; - let t0, t1, t2, t3; - - for (;;) { - t0 = TE0[(s0 >>> 24) & 0xff] - ^ TE1[(s1 >>> 16) & 0xff] - ^ TE2[(s2 >>> 8) & 0xff] - ^ TE3[(s3 >>> 0) & 0xff] - ^ key[kp + 4]; - t1 = TE0[(s1 >>> 24) & 0xff] - ^ TE1[(s2 >>> 16) & 0xff] - ^ TE2[(s3 >>> 8) & 0xff] - ^ TE3[(s0 >>> 0) & 0xff] - ^ key[kp + 5]; - t2 = TE0[(s2 >>> 24) & 0xff] - ^ TE1[(s3 >>> 16) & 0xff] - ^ TE2[(s0 >>> 8) & 0xff] - ^ TE3[(s1 >>> 0) & 0xff] - ^ key[kp + 6]; - t3 = TE0[(s3 >>> 24) & 0xff] - ^ TE1[(s0 >>> 16) & 0xff] - ^ TE2[(s1 >>> 8) & 0xff] - ^ TE3[(s2 >>> 0) & 0xff] - ^ key[kp + 7]; - - kp += 8; - - if (--r === 0) - break; - - s0 = TE0[(t0 >>> 24) & 0xff] - ^ TE1[(t1 >>> 16) & 0xff] - ^ TE2[(t2 >>> 8) & 0xff] - ^ TE3[(t3 >>> 0) & 0xff] - ^ key[kp + 0]; - s1 = TE0[(t1 >>> 24) & 0xff] - ^ TE1[(t2 >>> 16) & 0xff] - ^ TE2[(t3 >>> 8) & 0xff] - ^ TE3[(t0 >>> 0) & 0xff] - ^ key[kp + 1]; - s2 = TE0[(t2 >>> 24) & 0xff] - ^ TE1[(t3 >>> 16) & 0xff] - ^ TE2[(t0 >>> 8) & 0xff] - ^ TE3[(t1 >>> 0) & 0xff] - ^ key[kp + 2]; - s3 = TE0[(t3 >>> 24) & 0xff] - ^ TE1[(t0 >>> 16) & 0xff] - ^ TE2[(t1 >>> 8) & 0xff] - ^ TE3[(t2 >>> 0) & 0xff] - ^ key[kp + 3]; - } - - // Apply last round and map cipher - // state to byte array block. - s0 = (TE2[(t0 >>> 24) & 0xff] & 0xff000000) - ^ (TE3[(t1 >>> 16) & 0xff] & 0x00ff0000) - ^ (TE0[(t2 >>> 8) & 0xff] & 0x0000ff00) - ^ (TE1[(t3 >>> 0) & 0xff] & 0x000000ff) - ^ key[kp + 0]; - s1 = (TE2[(t1 >>> 24) & 0xff] & 0xff000000) - ^ (TE3[(t2 >>> 16) & 0xff] & 0x00ff0000) - ^ (TE0[(t3 >>> 8) & 0xff] & 0x0000ff00) - ^ (TE1[(t0 >>> 0) & 0xff] & 0x000000ff) - ^ key[kp + 1]; - s2 = (TE2[(t2 >>> 24) & 0xff] & 0xff000000) - ^ (TE3[(t3 >>> 16) & 0xff] & 0x00ff0000) - ^ (TE0[(t0 >>> 8) & 0xff] & 0x0000ff00) - ^ (TE1[(t1 >>> 0) & 0xff] & 0x000000ff) - ^ key[kp + 2]; - s3 = (TE2[(t3 >>> 24) & 0xff] & 0xff000000) - ^ (TE3[(t0 >>> 16) & 0xff] & 0x00ff0000) - ^ (TE0[(t1 >>> 8) & 0xff] & 0x0000ff00) - ^ (TE1[(t2 >>> 0) & 0xff] & 0x000000ff) - ^ key[kp + 3]; - - const output = Buffer.allocUnsafe(16); - writeU32(output, s0, 0); - writeU32(output, s1, 4); - writeU32(output, s2, 8); - writeU32(output, s3, 12); - - return output; -}; - -/** - * Decrypt a 16 byte block of data. - * @param {Buffer} input - * @returns {Buffer} - */ - -AESKey.prototype.decryptBlock = function decryptBlock(input) { - assert(this.userKey, 'Cannot use AESKey once it is destroyed.'); - - const key = this.getDecryptKey(); - let kp = 0; - - // Map byte array block to cipher - // state and add initial round key. - let s0 = readU32(input, 0) ^ key[kp + 0]; - let s1 = readU32(input, 4) ^ key[kp + 1]; - let s2 = readU32(input, 8) ^ key[kp + 2]; - let s3 = readU32(input, 12) ^ key[kp + 3]; - - // Nr - 1 full rounds - let r = this.rounds >>> 1; - let t0, t1, t2, t3; - - for (;;) { - t0 = TD0[(s0 >>> 24) & 0xff] - ^ TD1[(s3 >>> 16) & 0xff] - ^ TD2[(s2 >>> 8) & 0xff] - ^ TD3[(s1 >>> 0) & 0xff] - ^ key[kp + 4]; - t1 = TD0[(s1 >>> 24) & 0xff] - ^ TD1[(s0 >>> 16) & 0xff] - ^ TD2[(s3 >>> 8) & 0xff] - ^ TD3[(s2 >>> 0) & 0xff] - ^ key[kp + 5]; - t2 = TD0[(s2 >>> 24) & 0xff] - ^ TD1[(s1 >>> 16) & 0xff] - ^ TD2[(s0 >>> 8) & 0xff] - ^ TD3[(s3 >>> 0) & 0xff] - ^ key[kp + 6]; - t3 = TD0[(s3 >>> 24) & 0xff] - ^ TD1[(s2 >>> 16) & 0xff] - ^ TD2[(s1 >>> 8) & 0xff] - ^ TD3[(s0 >>> 0) & 0xff] - ^ key[kp + 7]; - - kp += 8; - - if (--r === 0) - break; - - s0 = TD0[(t0 >>> 24) & 0xff] - ^ TD1[(t3 >>> 16) & 0xff] - ^ TD2[(t2 >>> 8) & 0xff] - ^ TD3[(t1 >>> 0) & 0xff] - ^ key[kp + 0]; - s1 = TD0[(t1 >>> 24) & 0xff] - ^ TD1[(t0 >>> 16) & 0xff] - ^ TD2[(t3 >>> 8) & 0xff] - ^ TD3[(t2 >>> 0) & 0xff] - ^ key[kp + 1]; - s2 = TD0[(t2 >>> 24) & 0xff] - ^ TD1[(t1 >>> 16) & 0xff] - ^ TD2[(t0 >>> 8) & 0xff] - ^ TD3[(t3 >>> 0) & 0xff] - ^ key[kp + 2]; - s3 = TD0[(t3 >>> 24) & 0xff] - ^ TD1[(t2 >>> 16) & 0xff] - ^ TD2[(t1 >>> 8) & 0xff] - ^ TD3[(t0 >>> 0) & 0xff] - ^ key[kp + 3]; - } - - // Apply last round and map cipher - // state to byte array block. - s0 = (TD4[(t0 >>> 24) & 0xff] << 24) - ^ (TD4[(t3 >>> 16) & 0xff] << 16) - ^ (TD4[(t2 >>> 8) & 0xff] << 8) - ^ (TD4[(t1 >>> 0) & 0xff] << 0) - ^ key[kp + 0]; - s1 = (TD4[(t1 >>> 24) & 0xff] << 24) - ^ (TD4[(t0 >>> 16) & 0xff] << 16) - ^ (TD4[(t3 >>> 8) & 0xff] << 8) - ^ (TD4[(t2 >>> 0) & 0xff] << 0) - ^ key[kp + 1]; - s2 = (TD4[(t2 >>> 24) & 0xff] << 24) - ^ (TD4[(t1 >>> 16) & 0xff] << 16) - ^ (TD4[(t0 >>> 8) & 0xff] << 8) - ^ (TD4[(t3 >>> 0) & 0xff] << 0) - ^ key[kp + 2]; - s3 = (TD4[(t3 >>> 24) & 0xff] << 24) - ^ (TD4[(t2 >>> 16) & 0xff] << 16) - ^ (TD4[(t1 >>> 8) & 0xff] << 8) - ^ (TD4[(t0 >>> 0) & 0xff] << 0) - ^ key[kp + 3]; - - const output = Buffer.allocUnsafe(16); - writeU32(output, s0, 0); - writeU32(output, s1, 4); - writeU32(output, s2, 8); - writeU32(output, s3, 12); - - return output; -}; - -/** - * AES cipher. - * @constructor - * @ignore - * @param {Buffer} key - * @param {Buffer} iv - * @param {Number} bits - * @param {String} mode - */ - -function AESCipher(key, iv, bits, mode) { - if (!(this instanceof AESCipher)) - return new AESCipher(key, iv, mode); - - assert(mode === 'ecb' || mode === 'cbc', 'Unknown mode.'); - - this.key = new AESKey(key, bits); - this.mode = mode; - this.prev = iv; - this.waiting = null; -} - -/** - * Encrypt blocks of data. - * @param {Buffer} data - * @returns {Buffer} - */ - -AESCipher.prototype.update = function update(data) { - const blocks = []; - - if (this.waiting) { - data = concat(this.waiting, data); - this.waiting = null; - } - - const trailing = data.length % 16; - const len = data.length - trailing; - - // Encrypt all blocks except for the last. - for (let i = 0; i < len; i += 16) { - let block = data.slice(i, i + 16); - if (this.mode === 'cbc') - block = xor(block, this.prev); - this.prev = this.key.encryptBlock(block); - blocks.push(this.prev); - } - - if (trailing > 0) - this.waiting = data.slice(len); - - return Buffer.concat(blocks); -}; - -/** - * Finalize the cipher. - * @returns {Buffer} - */ - -AESCipher.prototype.final = function final() { - let block; - - // Handle padding on the last block. - if (!this.waiting) { - block = Buffer.allocUnsafe(16); - block.fill(16); - } else { - const left = 16 - this.waiting.length; - const pad = Buffer.allocUnsafe(left); - pad.fill(left); - block = concat(this.waiting, pad); - } - - // Encrypt the last block, - // as well as the padding. - if (this.mode === 'cbc') - block = xor(block, this.prev); - - block = this.key.encryptBlock(block); - - this.key.destroy(); - - return block; -}; - -/** - * AES decipher. - * @constructor - * @ignore - * @param {Buffer} key - * @param {Buffer} iv - * @param {Number} bits - * @param {String} mode - */ - -function AESDecipher(key, iv, bits, mode) { - if (!(this instanceof AESDecipher)) - return new AESDecipher(key, iv, mode); - - assert(mode === 'ecb' || mode === 'cbc', 'Unknown mode.'); - - this.key = new AESKey(key, bits); - this.mode = mode; - this.prev = iv; - this.waiting = null; - this.lastBlock = null; -} - -/** - * Decrypt blocks of data. - * @param {Buffer} data - */ - -AESDecipher.prototype.update = function update(data) { - const blocks = []; - - if (this.waiting) { - data = concat(this.waiting, data); - this.waiting = null; - } - - const trailing = data.length % 16; - const len = data.length - trailing; - - // Decrypt all blocks. - for (let i = 0; i < len; i += 16) { - const chunk = this.prev; - - this.prev = data.slice(i, i + 16); - - let block = this.key.decryptBlock(this.prev); - - if (this.mode === 'cbc') - block = xor(block, chunk); - - blocks.push(block); - } - - if (trailing > 0) - this.waiting = data.slice(len); - - if (this.lastBlock) { - blocks.unshift(this.lastBlock); - this.lastBlock = null; - } - - // Keep a reference to the last - // block for the padding check. - this.lastBlock = blocks.pop(); - - return Buffer.concat(blocks); -}; - -/** - * Finalize the decipher. - * @returns {Buffer} - */ - -AESDecipher.prototype.final = function final() { - this.key.destroy(); - - assert(!this.waiting, 'Bad decrypt (trailing bytes).'); - assert(this.lastBlock, 'Bad decrypt (no data).'); - - // Check padding on the last block. - let block = this.lastBlock; - let b = 16; - const n = block[b - 1]; - - if (n === 0 || n > b) - throw new Error('Bad decrypt (padding).'); - - for (let i = 0; i < n; i++) { - if (block[--b] !== n) - throw new Error('Bad decrypt (padding).'); - } - - // Slice off the padding unless - // the entire block was padding. - if (n === 16) - return Buffer.alloc(0); - - block = block.slice(0, -n); - - return block; -}; - -/** - * Encrypt data with aes 256. - * @param {Buffer} data - * @param {Buffer} key - * @param {Buffer} iv - * @param {String} mode - * @returns {Buffer} - */ - -AES.encrypt = function encrypt(data, key, iv, bits, mode) { - const cipher = new AESCipher(key, iv, bits, mode); - return concat(cipher.update(data), cipher.final()); -}; - -/** - * Decrypt data with aes 256. - * @param {Buffer} data - * @param {Buffer} key - * @param {Buffer|null} iv - * @param {Number} bits - * @param {String} mode - * @returns {Buffer} - */ - -AES.decrypt = function decrypt(data, key, iv, bits, mode) { - const decipher = new AESDecipher(key, iv, bits, mode); - return concat(decipher.update(data), decipher.final()); -}; - -/** - * Encrypt data with aes 256 cbc. - * @param {Buffer} data - * @param {Buffer} key - * @param {Buffer} iv - * @returns {Buffer} - */ - -AES.encipher = function encipher(data, key, iv) { - assert(Buffer.isBuffer(data)); - assert(key.length === 32); - assert(iv.length === 16); - return AES.encrypt(data, key, iv, 256, 'cbc'); -}; - -/** - * Decrypt data with aes 256 cbc. - * @param {Buffer} data - * @param {Buffer} key - * @param {Buffer} iv - * @returns {Buffer} - */ - -AES.decipher = function decipher(data, key, iv) { - assert(Buffer.isBuffer(data)); - assert(key.length === 32); - assert(iv.length === 16); - return AES.decrypt(data, key, iv, 256, 'cbc'); -}; - -/* - * Helpers - */ - -function xor(v1, v2) { - const out = Buffer.allocUnsafe(v1.length); - for (let i = 0; i < v1.length; i++) - out[i] = v1[i] ^ v2[i]; - return out; -} - -function readU32(data, i) { - return (data[i + 0] << 24) - ^ (data[i + 1] << 16) - ^ (data[i + 2] << 8) - ^ data[i + 3]; -} - -function writeU32(data, value, i) { - data[i + 0] = (value >>> 24) & 0xff; - data[i + 1] = (value >>> 16) & 0xff; - data[i + 2] = (value >>> 8) & 0xff; - data[i + 3] = value & 0xff; -} - -function concat(a, b) { - const data = Buffer.allocUnsafe(a.length + b.length); - a.copy(data, 0); - b.copy(data, a.length); - return data; -} diff --git a/lib/crypto/aes.js b/lib/crypto/aes.js deleted file mode 100644 index 15618fcd..00000000 --- a/lib/crypto/aes.js +++ /dev/null @@ -1,49 +0,0 @@ -/*! - * aes.js - aes for bcoin - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto.aes - */ - -const crypto = require('crypto'); -const native = require('../native').binding; - -/** - * Encrypt data with aes 256 cbc. - * @param {Buffer} data - * @param {Buffer} key - * @param {Buffer} iv - * @returns {Buffer} - */ - -exports.encipher = function encipher(data, key, iv) { - const ctx = crypto.createCipheriv('aes-256-cbc', key, iv); - return Buffer.concat([ctx.update(data), ctx.final()]); -}; - -/** - * Decrypt data with aes 256 cbc. - * @param {Buffer} data - * @param {Buffer} key - * @param {Buffer} iv - * @returns {Buffer} - */ - -exports.decipher = function decipher(data, key, iv) { - const ctx = crypto.createDecipheriv('aes-256-cbc', key, iv); - try { - return Buffer.concat([ctx.update(data), ctx.final()]); - } catch (e) { - throw new Error('Bad key for decryption.'); - } -}; - -if (native) { - exports.encipher = native.encipher; - exports.decipher = native.decipher; -} diff --git a/lib/crypto/bn.js b/lib/crypto/bn.js deleted file mode 100644 index 1cfaa76c..00000000 --- a/lib/crypto/bn.js +++ /dev/null @@ -1,19 +0,0 @@ -/*! - * bn.js - big numbers for bcoin - * Copyright (c) 2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto.BN - */ - -/** - * bn.js - * @constructor - * @see https://github.com/indutny/bn.js - */ - -module.exports = require('bn.js'); diff --git a/lib/crypto/ccmp.js b/lib/crypto/ccmp.js deleted file mode 100644 index dfc4ced1..00000000 --- a/lib/crypto/ccmp.js +++ /dev/null @@ -1,36 +0,0 @@ -/*! - * ccmp.js - constant-time compare for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -const assert = require('assert'); - -/** - * memcmp in constant time (can only return true or false). - * This protects us against timing attacks when - * comparing an input against a secret string. - * @alias module:crypto.ccmp - * @see https://cryptocoding.net/index.php/Coding_rules - * @see `$ man 3 memcmp` (NetBSD's consttime_memequal) - * @param {Buffer} a - * @param {Buffer} b - * @returns {Boolean} - */ - -module.exports = function ccmp(a, b) { - assert(Buffer.isBuffer(a)); - assert(Buffer.isBuffer(b)); - - if (b.length === 0) - return a.length === 0; - - let res = a.length ^ b.length; - - for (let i = 0; i < a.length; i++) - res |= a[i] ^ b[i % b.length]; - - return res === 0; -}; diff --git a/lib/crypto/chacha20.js b/lib/crypto/chacha20.js deleted file mode 100644 index 42e8db16..00000000 --- a/lib/crypto/chacha20.js +++ /dev/null @@ -1,205 +0,0 @@ -/*! - * chacha20.js - chacha20 for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -const assert = require('assert'); -const native = require('../native').binding; - -const BIG_ENDIAN = new Int8Array(new Int16Array([1]).buffer)[0] === 0; - -/** - * ChaCha20 (used for bip151) - * @alias module:crypto.ChaCha20 - * @constructor - * @see https://tools.ietf.org/html/rfc7539#section-2 - */ - -function ChaCha20() { - if (!(this instanceof ChaCha20)) - return new ChaCha20(); - - this.state = new Uint32Array(16); - this.stream = new Uint32Array(16); - this.bytes = new Uint8Array(this.stream.buffer); - - if (BIG_ENDIAN) - this.bytes = Buffer.allocUnsafe(64); - - this.pos = 0; - this.ivSize = 0; -} - -/** - * Initialize chacha20 with a key, iv, and counter. - * @param {Buffer} key - * @param {Buffer} iv - * @param {Number} counter - */ - -ChaCha20.prototype.init = function init(key, iv, counter) { - if (key) - this.initKey(key); - - if (iv) - this.initIV(iv, counter); -}; - -/** - * Set key. - * @param {Buffer} key - */ - -ChaCha20.prototype.initKey = function initKey(key) { - this.state[0] = 0x61707865; - this.state[1] = 0x3320646e; - this.state[2] = 0x79622d32; - this.state[3] = 0x6b206574; - - this.state[4] = key.readUInt32LE(0, true); - this.state[5] = key.readUInt32LE(4, true); - this.state[6] = key.readUInt32LE(8, true); - this.state[7] = key.readUInt32LE(12, true); - this.state[8] = key.readUInt32LE(16, true); - this.state[9] = key.readUInt32LE(20, true); - this.state[10] = key.readUInt32LE(24, true); - this.state[11] = key.readUInt32LE(28, true); - - this.state[12] = 0; - - this.pos = 0xffffffff; -}; - -/** - * Set IV and counter. - * @param {Buffer} iv - * @param {Number} counter - */ - -ChaCha20.prototype.initIV = function initIV(iv, counter) { - if (iv.length === 8) { - this.state[13] = 0; - this.state[14] = iv.readUInt32LE(0, true); - this.state[15] = iv.readUInt32LE(4, true); - } else if (iv.length === 12) { - this.state[13] = iv.readUInt32LE(0, true); - this.state[14] = iv.readUInt32LE(4, true); - this.state[15] = iv.readUInt32LE(8, true); - } else { - assert(false, 'Bad iv size.'); - } - - this.ivSize = iv.length * 8; - - this.setCounter(counter); -}; - -/** - * Encrypt/decrypt data. - * @param {Buffer} data - Will be mutated. - */ - -ChaCha20.prototype.encrypt = function encrypt(data) { - for (let i = 0; i < data.length; i++) { - if (this.pos >= 64) { - for (let j = 0; j < 16; j++) - this.stream[j] = this.state[j]; - - for (let j = 0; j < 10; j++) { - qround(this.stream, 0, 4, 8, 12); - qround(this.stream, 1, 5, 9, 13); - qround(this.stream, 2, 6, 10, 14); - qround(this.stream, 3, 7, 11, 15); - qround(this.stream, 0, 5, 10, 15); - qround(this.stream, 1, 6, 11, 12); - qround(this.stream, 2, 7, 8, 13); - qround(this.stream, 3, 4, 9, 14); - } - - for (let j = 0; j < 16; j++) { - this.stream[j] += this.state[j]; - if (BIG_ENDIAN) - this.bytes.writeUInt32LE(this.stream[j], j * 4, true); - } - - this.state[12]++; - - if (this.state[12] === 0) { - assert(this.ivSize === 64, 'Counter overflow.'); - this.state[13]++; - assert(this.state[13] !== 0, 'Counter overflow.'); - } - - this.pos = 0; - } - - data[i] ^= this.bytes[this.pos++]; - } - - return data; -}; - -/** - * Artificially set the counter. - * @param {Number} counter - */ - -ChaCha20.prototype.setCounter = function setCounter(counter) { - if (!counter) - counter = 0; - - const lo = counter % 0x100000000; - const hi = (counter - lo) / 0x100000000; - - this.state[12] = lo; - - if (this.ivSize === 64) - this.state[13] = hi; -}; - -/** - * Get the counter as a uint64. - * @returns {Number} - */ - -ChaCha20.prototype.getCounter = function getCounter() { - const lo = this.state[12]; - const hi = this.state[13]; - if (this.ivSize === 64) - return hi * 0x100000000 + lo; - return lo; -}; - -if (native) - ChaCha20 = native.ChaCha20; - -/* - * Helpers - */ - -function qround(x, a, b, c, d) { - x[a] += x[b]; - x[d] = rotl32(x[d] ^ x[a], 16); - - x[c] += x[d]; - x[b] = rotl32(x[b] ^ x[c], 12); - - x[a] += x[b]; - x[d] = rotl32(x[d] ^ x[a], 8); - - x[c] += x[d]; - x[b] = rotl32(x[b] ^ x[c], 7); -} - -function rotl32(w, b) { - return (w << b) | (w >>> (32 - b)); -} - -/* - * Expose - */ - -module.exports = ChaCha20; diff --git a/lib/crypto/cleanse.js b/lib/crypto/cleanse.js deleted file mode 100644 index de77100d..00000000 --- a/lib/crypto/cleanse.js +++ /dev/null @@ -1,34 +0,0 @@ -/*! - * cleanse.js - memzero for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto.cleanse - */ - -const native = require('../native').binding; - -let counter = 0; - -/** - * A maybe-secure memzero. - * @param {Buffer} data - */ - -module.exports = function cleanse(data) { - let ctr = counter; - - for (let i = 0; i < data.length; i++) { - data[i] = ctr & 0xff; - ctr += i; - } - - counter = ctr >>> 0; -}; - -if (native) - exports.cleanse = native.cleanse; diff --git a/lib/crypto/digest-browser.js b/lib/crypto/digest-browser.js deleted file mode 100644 index 4f7f4557..00000000 --- a/lib/crypto/digest-browser.js +++ /dev/null @@ -1,122 +0,0 @@ -/*! - * digest-browser.js - hash functions for bcoin - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto.digest-browser - * @ignore - */ - -const assert = require('assert'); -const hashjs = require('hash.js'); -const SHA256 = require('./sha256'); -const POOL64 = Buffer.allocUnsafe(64); - -/** - * Hash with chosen algorithm. - * @param {String} alg - * @param {Buffer} data - * @returns {Buffer} - */ - -exports.hash = function hash(alg, data) { - if (alg === 'sha256') - return SHA256.digest(data); - - const algo = hashjs[alg]; - - assert(algo != null, 'Unknown algorithm.'); - - return Buffer.from(algo().update(data).digest()); -}; - -/** - * Hash with ripemd160. - * @param {Buffer} data - * @returns {Buffer} - */ - -exports.ripemd160 = function ripemd160(data) { - return exports.hash('ripemd160', data); -}; - -/** - * Hash with sha1. - * @param {Buffer} data - * @returns {Buffer} - */ - -exports.sha1 = function sha1(data) { - return exports.hash('sha1', data); -}; - -/** - * Hash with sha256. - * @param {Buffer} data - * @returns {Buffer} - */ - -exports.sha256 = function sha256(data) { - return SHA256.digest(data); -}; - -/** - * Hash with sha256 and ripemd160 (OP_HASH160). - * @param {Buffer} data - * @returns {Buffer} - */ - -exports.hash160 = function hash160(data) { - return exports.hash('ripemd160', SHA256.digest(data)); -}; - -/** - * Hash with sha256 twice (OP_HASH256). - * @param {Buffer} data - * @returns {Buffer} - */ - -exports.hash256 = function hash256(data) { - return SHA256.hash256(data); -}; - -/** - * Hash left and right hashes with hash256. - * @param {Buffer} left - * @param {Buffer} right - * @returns {Buffer} - */ - -exports.root256 = function root256(left, right) { - const data = POOL64; - - assert(left.length === 32); - assert(right.length === 32); - - left.copy(data, 0); - right.copy(data, 32); - - return exports.hash256(data); -}; - -/** - * Create an HMAC. - * @param {String} alg - * @param {Buffer} data - * @param {Buffer} key - * @returns {Buffer} HMAC - */ - -exports.hmac = function hmac(alg, data, key) { - const algo = hashjs[alg]; - - assert(algo != null, 'Unknown algorithm.'); - - const ctx = hashjs.hmac(algo, key); - - return Buffer.from(ctx.update(data).digest()); -}; diff --git a/lib/crypto/digest.js b/lib/crypto/digest.js deleted file mode 100644 index d65d72a5..00000000 --- a/lib/crypto/digest.js +++ /dev/null @@ -1,120 +0,0 @@ -/*! - * digest.js - hash functions for bcoin - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto.digest - */ - -const assert = require('assert'); -const crypto = require('crypto'); -const native = require('../native').binding; -const POOL64 = Buffer.allocUnsafe(64); - -/** - * Hash with chosen algorithm. - * @param {String} alg - * @param {Buffer} data - * @returns {Buffer} - */ - -exports.hash = function hash(alg, data) { - return crypto.createHash(alg).update(data).digest(); -}; - -/** - * Hash with ripemd160. - * @param {Buffer} data - * @returns {Buffer} - */ - -exports.ripemd160 = function ripemd160(data) { - return exports.hash('ripemd160', data); -}; - -/** - * Hash with sha1. - * @param {Buffer} data - * @returns {Buffer} - */ - -exports.sha1 = function sha1(data) { - return exports.hash('sha1', data); -}; - -/** - * Hash with sha256. - * @param {Buffer} data - * @returns {Buffer} - */ - -exports.sha256 = function sha256(data) { - return exports.hash('sha256', data); -}; - -/** - * Hash with sha256 and ripemd160 (OP_HASH160). - * @param {Buffer} data - * @returns {Buffer} - */ - -exports.hash160 = function hash160(data) { - return exports.ripemd160(exports.sha256(data)); -}; - -/** - * Hash with sha256 twice (OP_HASH256). - * @param {Buffer} data - * @returns {Buffer} - */ - -exports.hash256 = function hash256(data) { - return exports.sha256(exports.sha256(data)); -}; - -/** - * Hash left and right hashes with hash256. - * @param {Buffer} left - * @param {Buffer} right - * @returns {Buffer} - */ - -exports.root256 = function root256(left, right) { - const data = POOL64; - - assert(left.length === 32); - assert(right.length === 32); - - left.copy(data, 0); - right.copy(data, 32); - - return exports.hash256(data); -}; - -/** - * Create an HMAC. - * @param {String} alg - * @param {Buffer} data - * @param {Buffer} key - * @returns {Buffer} HMAC - */ - -exports.hmac = function hmac(alg, data, key) { - const ctx = crypto.createHmac(alg, key); - return ctx.update(data).digest(); -}; - -if (native) { - exports.hash = native.hash; - exports.hmac = native.hmac; - exports.ripemd160 = native.ripemd160; - exports.sha1 = native.sha1; - exports.sha256 = native.sha256; - exports.hash160 = native.hash160; - exports.hash256 = native.hash256; - exports.root256 = native.root256; -} diff --git a/lib/crypto/ecdsa.js b/lib/crypto/ecdsa.js deleted file mode 100644 index 4639156b..00000000 --- a/lib/crypto/ecdsa.js +++ /dev/null @@ -1,65 +0,0 @@ -/*! - * ecdsa.js - ecdsa for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto/ecdsa - */ - -const assert = require('assert'); -const elliptic = require('elliptic'); -const digest = require('./digest'); - -/** - * Verify ECDSA signature. - * @param {String} curve - Curve name. - * @param {String} alg - Hash algorithm. - * @param {Buffer} msg - Signed message. - * @param {Buffer} sig - Signature. - * @param {Buffer} key - ASN1 serialized ECDSA key. - * @returns {Boolean} - */ - -exports.verify = function verify(curve, alg, msg, sig, key) { - assert(typeof curve === 'string', 'No curve selected.'); - assert(typeof alg === 'string', 'No algorithm selected.'); - assert(Buffer.isBuffer(msg)); - assert(Buffer.isBuffer(sig)); - assert(Buffer.isBuffer(key)); - - const ec = elliptic.ec(curve); - const hash = digest.hash(alg, msg); - - try { - return ec.verify(hash, sig, key); - } catch (e) { - return false; - } -}; - -/** - * Sign message with ECDSA key. - * @memberof module:crypto/pk.ecdsa - * @param {String} curve - Curve name. - * @param {String} alg - Hash algorithm. - * @param {Buffer} msg - Signed message. - * @param {Buffer} key - ASN1 serialized ECDSA key. - * @returns {Buffer} Signature (DER) - */ - -exports.sign = function sign(curve, alg, msg, key) { - assert(typeof curve === 'string', 'No curve selected.'); - assert(typeof alg === 'string', 'No algorithm selected.'); - assert(Buffer.isBuffer(msg)); - assert(Buffer.isBuffer(key)); - - const ec = elliptic.ec(curve); - const hash = digest.hash(alg, msg); - const sig = ec.sign(hash, key, { canonical: true }); - - return Buffer.from(sig.toDER()); -}; diff --git a/lib/crypto/hkdf.js b/lib/crypto/hkdf.js deleted file mode 100644 index 64f4c9df..00000000 --- a/lib/crypto/hkdf.js +++ /dev/null @@ -1,65 +0,0 @@ -/*! - * hkdf.js - hkdf for bcoin - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto/hkdf - */ - -const digest = require('./digest'); - -/** - * Perform hkdf extraction. - * @param {Buffer} ikm - * @param {Buffer} key - * @param {String} alg - * @returns {Buffer} - */ - -exports.extract = function extract(ikm, key, alg) { - return digest.hmac(alg, ikm, key); -}; - -/** - * Perform hkdf expansion. - * @param {Buffer} prk - * @param {Buffer} info - * @param {Number} len - * @param {String} alg - * @returns {Buffer} - */ - -exports.expand = function expand(prk, info, len, alg) { - const size = digest.hash(alg, Buffer.alloc(0)).length; - const blocks = Math.ceil(len / size); - - if (blocks > 255) - throw new Error('Too many blocks.'); - - const okm = Buffer.allocUnsafe(len); - - if (blocks === 0) - return okm; - - const buf = Buffer.allocUnsafe(size + info.length + 1); - - // First round: - info.copy(buf, size); - buf[buf.length - 1] = 1; - - let out = digest.hmac(alg, buf.slice(size), prk); - out.copy(okm, 0); - - for (let i = 1; i < blocks; i++) { - out.copy(buf, 0); - buf[buf.length - 1]++; - out = digest.hmac(alg, buf, prk); - out.copy(okm, i * size); - } - - return okm; -}; diff --git a/lib/crypto/hmac-drbg.js b/lib/crypto/hmac-drbg.js deleted file mode 100644 index 55980794..00000000 --- a/lib/crypto/hmac-drbg.js +++ /dev/null @@ -1,120 +0,0 @@ -/*! - * hmac-drbg.js - hmac-drbg implementation for bcoin - * Copyright (c) 2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - * Parts of this software based on hmac-drbg. - */ - -'use strict'; - -const assert = require('assert'); -const digest = require('./digest'); - -/* - * Constants - */ - -const HASH_ALG = 'sha256'; -const HASH_SIZE = 32; -const RESEED_INTERVAL = 0x1000000000000; -const POOL33 = Buffer.allocUnsafe(HASH_SIZE + 1); -const POOL112 = Buffer.allocUnsafe(HASH_SIZE * 2 + 48); -const POOL145 = Buffer.allocUnsafe(POOL33.length + POOL112.length); - -/** - * HmacDRBG - * @constructor - */ - -function HmacDRBG(entropy, nonce, pers) { - if (!(this instanceof HmacDRBG)) - return new HmacDRBG(entropy, nonce, pers); - - this.K = Buffer.allocUnsafe(HASH_SIZE); - this.V = Buffer.allocUnsafe(HASH_SIZE); - this.rounds = 0; - - this.init(entropy, nonce, pers); -} - -HmacDRBG.prototype.init = function init(entropy, nonce, pers) { - for (let i = 0; i < this.V.length; i++) { - this.K[i] = 0x00; - this.V[i] = 0x01; - } - - this.reseed(entropy, nonce, pers); -}; - -HmacDRBG.prototype.reseed = function reseed(entropy, nonce, pers) { - const seed = POOL112; - - assert(Buffer.isBuffer(entropy)); - assert(Buffer.isBuffer(nonce)); - assert(Buffer.isBuffer(pers)); - - assert(entropy.length === HASH_SIZE); - assert(nonce.length === HASH_SIZE); - assert(pers.length === 48); - - entropy.copy(seed, 0); - nonce.copy(seed, HASH_SIZE); - pers.copy(seed, HASH_SIZE * 2); - - this.update(seed); - this.rounds = 1; -}; - -HmacDRBG.prototype.iterate = function iterate() { - const data = POOL33; - - this.V.copy(data, 0); - data[HASH_SIZE] = 0x00; - - this.K = digest.hmac(HASH_ALG, data, this.K); - this.V = digest.hmac(HASH_ALG, this.V, this.K); -}; - -HmacDRBG.prototype.update = function update(seed) { - const data = POOL145; - - assert(Buffer.isBuffer(seed)); - assert(seed.length === HASH_SIZE * 2 + 48); - - this.V.copy(data, 0); - data[HASH_SIZE] = 0x00; - seed.copy(data, HASH_SIZE + 1); - - this.K = digest.hmac(HASH_ALG, data, this.K); - this.V = digest.hmac(HASH_ALG, this.V, this.K); - - data[HASH_SIZE] = 0x01; - - this.K = digest.hmac(HASH_ALG, data, this.K); - this.V = digest.hmac(HASH_ALG, this.V, this.K); -}; - -HmacDRBG.prototype.generate = function generate(len) { - if (this.rounds > RESEED_INTERVAL) - throw new Error('Reseed is required.'); - - const data = Buffer.allocUnsafe(len); - let pos = 0; - - while (pos < len) { - this.V = digest.hmac(HASH_ALG, this.V, this.K); - this.V.copy(data, pos); - pos += HASH_SIZE; - } - - this.iterate(); - this.rounds++; - - return data; -}; - -/* - * Expose - */ - -module.exports = HmacDRBG; diff --git a/lib/crypto/index.js b/lib/crypto/index.js deleted file mode 100644 index 1112ed0f..00000000 --- a/lib/crypto/index.js +++ /dev/null @@ -1,51 +0,0 @@ -/*! - * crypto/index.js - crypto for bcoin - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto - */ - -const digest = require('./digest'); -const random = require('./random'); -const aes = require('./aes'); - -exports.aes = require('./aes'); -exports.AEAD = require('./aead'); -exports.BN = require('./bn'); -exports.ccmp = require('./ccmp'); -exports.ChaCha20 = require('./chacha20'); -exports.cleanse = require('./cleanse'); -exports.digest = require('./digest'); -exports.ecdsa = require('./ecdsa'); -exports.hkdf = require('./hkdf'); -exports.HmacDRBG = require('./hmac-drbg'); -exports.merkle = require('./merkle'); -exports.pbkdf2 = require('./pbkdf2'); -exports.Poly1305 = require('./poly1305'); -exports.random = require('./random'); -exports.rsa = require('./rsa'); -exports.schnorr = require('./schnorr'); -exports.scrypt = require('./scrypt'); -exports.secp256k1 = require('./secp256k1'); -exports.siphash = require('./siphash'); - -exports.hash = digest.hash; -exports.ripemd160 = digest.ripemd160; -exports.sha1 = digest.sha1; -exports.sha256 = digest.sha256; -exports.hash160 = digest.hash160; -exports.hash256 = digest.hash256; -exports.root256 = digest.root256; -exports.hmac = digest.hmac; - -exports.encipher = aes.encipher; -exports.decipher = aes.decipher; - -exports.randomBytes = random.randomBytes; -exports.randomInt = random.randomInt; -exports.randomRange = random.randomRange; diff --git a/lib/crypto/merkle.js b/lib/crypto/merkle.js deleted file mode 100644 index 1adeeca1..00000000 --- a/lib/crypto/merkle.js +++ /dev/null @@ -1,115 +0,0 @@ -/*! - * merkle.js - merkle trees for bcoin - * Copyright (c) 2014-2015, Fedor Indutny (MIT License) - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto/merkle - */ - -const digest = require('./digest'); - -/** - * Build a merkle tree from leaves. - * Note that this will mutate the `leaves` array! - * @param {Buffer[]} leaves - * @returns {Array} [nodes, malleated] - */ - -exports.createTree = function createTree(leaves) { - const nodes = leaves; - let size = leaves.length; - let malleated = false; - let i = 0; - - if (size === 0) { - nodes.push(Buffer.alloc(32)); - return [nodes, malleated]; - } - - while (size > 1) { - for (let j = 0; j < size; j += 2) { - const k = Math.min(j + 1, size - 1); - const left = nodes[i + j]; - const right = nodes[i + k]; - - if (k === j + 1 && k + 1 === size - && left.equals(right)) { - malleated = true; - } - - const hash = digest.root256(left, right); - - nodes.push(hash); - } - i += size; - size += 1; - size >>>= 1; - } - - return [nodes, malleated]; -}; - -/** - * Calculate merkle root from leaves. - * @param {Buffer[]} leaves - * @returns {Array} [root, malleated] - */ - -exports.createRoot = function createRoot(leaves) { - const [nodes, malleated] = exports.createTree(leaves); - const root = nodes[nodes.length - 1]; - return [root, malleated]; -}; - -/** - * Collect a merkle branch from vector index. - * @param {Number} index - * @param {Buffer[]} leaves - * @returns {Buffer[]} branch - */ - -exports.createBranch = function createBranch(index, leaves) { - let size = leaves.length; - const [nodes] = exports.createTree(leaves); - const branch = []; - let i = 0; - - while (size > 1) { - const j = Math.min(index ^ 1, size - 1); - branch.push(nodes[i + j]); - index >>>= 1; - i += size; - size += 1; - size >>>= 1; - } - - return branch; -}; - -/** - * Derive merkle root from branch. - * @param {Buffer} hash - * @param {Buffer[]} branch - * @param {Number} index - * @returns {Buffer} root - */ - -exports.deriveRoot = function deriveRoot(hash, branch, index) { - let root = hash; - - for (const hash of branch) { - if (index & 1) - root = digest.root256(hash, root); - else - root = digest.root256(root, hash); - - index >>>= 1; - } - - return root; -}; diff --git a/lib/crypto/pbkdf2-browser.js b/lib/crypto/pbkdf2-browser.js deleted file mode 100644 index 92b879cf..00000000 --- a/lib/crypto/pbkdf2-browser.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * pbkdf2.js - pbkdf2 for bcoin - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto.pbkdf2-browser - * @ignore - */ - -const digest = require('./digest'); -const crypto = global.crypto || global.msCrypto || {}; -const subtle = crypto.subtle || {}; - -/** - * Perform key derivation using PBKDF2. - * @param {Buffer} key - * @param {Buffer} salt - * @param {Number} iter - * @param {Number} len - * @param {String} alg - * @returns {Buffer} - */ - -exports.derive = function derive(key, salt, iter, len, alg) { - const size = digest.hash(alg, Buffer.alloc(0)).length; - const blocks = Math.ceil(len / size); - const out = Buffer.allocUnsafe(len); - const buf = Buffer.allocUnsafe(salt.length + 4); - const block = Buffer.allocUnsafe(size); - let pos = 0; - - salt.copy(buf, 0); - - for (let i = 0; i < blocks; i++) { - buf.writeUInt32BE(i + 1, salt.length, true); - let mac = digest.hmac(alg, buf, key); - mac.copy(block, 0); - for (let j = 1; j < iter; j++) { - mac = digest.hmac(alg, mac, key); - for (let k = 0; k < size; k++) - block[k] ^= mac[k]; - } - block.copy(out, pos); - pos += size; - } - - return out; -}; - -/** - * Execute pbkdf2 asynchronously. - * @param {Buffer} key - * @param {Buffer} salt - * @param {Number} iter - * @param {Number} len - * @param {String} alg - * @returns {Promise} - */ - -exports.deriveAsync = async function deriveAsync(key, salt, iter, len, alg) { - const algo = { name: 'PBKDF2' }; - const use = ['deriveBits']; - - if (!subtle.importKey || !subtle.deriveBits) - return exports.derive(key, salt, iter, len, alg); - - const options = { - name: 'PBKDF2', - salt: salt, - iterations: iter, - hash: getHash(alg) - }; - - const imported = await subtle.importKey('raw', key, algo, false, use); - const data = await subtle.deriveBits(options, imported, len * 8); - - return Buffer.from(data); -}; - -/* - * Helpers - */ - -function getHash(name) { - switch (name) { - case 'sha1': - return 'SHA-1'; - case 'sha256': - return 'SHA-256'; - case 'sha384': - return 'SHA-384'; - case 'sha512': - return 'SHA-512'; - default: - throw new Error(`Algorithm not supported: ${name}.`); - } -} diff --git a/lib/crypto/pbkdf2.js b/lib/crypto/pbkdf2.js deleted file mode 100644 index 5e25a11f..00000000 --- a/lib/crypto/pbkdf2.js +++ /dev/null @@ -1,49 +0,0 @@ -/*! - * pbkdf2.js - pbkdf2 for bcoin - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto.pbkdf2 - */ - -const crypto = require('crypto'); - -/** - * Perform key derivation using PBKDF2. - * @param {Buffer} key - * @param {Buffer} salt - * @param {Number} iter - * @param {Number} len - * @param {String} alg - * @returns {Buffer} - */ - -exports.derive = function derive(key, salt, iter, len, alg) { - return crypto.pbkdf2Sync(key, salt, iter, len, alg); -}; - -/** - * Execute pbkdf2 asynchronously. - * @param {Buffer} key - * @param {Buffer} salt - * @param {Number} iter - * @param {Number} len - * @param {String} alg - * @returns {Promise} - */ - -exports.deriveAsync = function deriveAsync(key, salt, iter, len, alg) { - return new Promise((resolve, reject) => { - crypto.pbkdf2(key, salt, iter, len, alg, (err, result) => { - if (err) { - reject(err); - return; - } - resolve(result); - }); - }); -}; diff --git a/lib/crypto/poly1305.js b/lib/crypto/poly1305.js deleted file mode 100644 index 50ecdda9..00000000 --- a/lib/crypto/poly1305.js +++ /dev/null @@ -1,321 +0,0 @@ -/*! - * poly1305.js - poly1305 for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -const native = require('../native').binding; - -/** - * Poly1305 (used for bip151) - * @alias module:crypto/chachapoly.Poly1305 - * @constructor - * @see https://github.com/floodyberry/poly1305-donna - * @see https://tools.ietf.org/html/rfc7539#section-2.5 - */ - -function Poly1305() { - if (!(this instanceof Poly1305)) - return new Poly1305(); - - this.r = new Uint16Array(10); - this.h = new Uint16Array(10); - this.pad = new Uint16Array(8); - this.fin = 0; - this.leftover = 0; - this.buffer = Buffer.allocUnsafe(16); -} - -/** - * Initialize poly1305 with a key. - * @param {Buffer} key - */ - -Poly1305.prototype.init = function init(key) { - // r &= 0xffffffc0ffffffc0ffffffc0fffffff - const t0 = key.readUInt16LE(0, true); - const t1 = key.readUInt16LE(2, true); - const t2 = key.readUInt16LE(4, true); - const t3 = key.readUInt16LE(6, true); - const t4 = key.readUInt16LE(8, true); - const t5 = key.readUInt16LE(10, true); - const t6 = key.readUInt16LE(12, true); - const t7 = key.readUInt16LE(14, true); - - this.r[0] = t0 & 0x1fff; - this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; - this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; - this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; - this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; - this.r[5] = (t4 >>> 1) & 0x1ffe; - this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; - this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; - this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; - this.r[9] = (t7 >>> 5) & 0x007f; - - // h = 0 - for (let i = 0; i < 10; i++) - this.h[i] = 0; - - // save pad for later - for (let i = 0; i < 8; i++) - this.pad[i] = key.readUInt16LE(16 + (2 * i), true); - - this.leftover = 0; - this.fin = 0; -}; - -/** - * Process 16 byte blocks. - * @param {Buffer} data - Blocks. - * @param {Number} bytes - Size. - * @param {Number} m - Offset pointer. - */ - -Poly1305.prototype.blocks = function blocks(data, bytes, m) { - const hibit = this.fin ? 0 : (1 << 11); // 1 << 128 - const d = new Uint32Array(10); - - while (bytes >= 16) { - // h += m[i] - const t0 = data.readUInt16LE(m + 0, true); - const t1 = data.readUInt16LE(m + 2, true); - const t2 = data.readUInt16LE(m + 4, true); - const t3 = data.readUInt16LE(m + 6, true); - const t4 = data.readUInt16LE(m + 8, true); - const t5 = data.readUInt16LE(m + 10, true); - const t6 = data.readUInt16LE(m + 12, true); - const t7 = data.readUInt16LE(m + 14, true); - - this.h[0] += t0 & 0x1fff; - this.h[1] += ((t0 >>> 13) | (t1 << 3)) & 0x1fff; - this.h[2] += ((t1 >>> 10) | (t2 << 6)) & 0x1fff; - this.h[3] += ((t2 >>> 7) | (t3 << 9)) & 0x1fff; - this.h[4] += ((t3 >>> 4) | (t4 << 12)) & 0x1fff; - this.h[5] += ((t4 >>> 1)) & 0x1fff; - this.h[6] += ((t4 >>> 14) | (t5 << 2)) & 0x1fff; - this.h[7] += ((t5 >>> 11) | (t6 << 5)) & 0x1fff; - this.h[8] += ((t6 >>> 8) | (t7 << 8)) & 0x1fff; - this.h[9] += ((t7 >>> 5)) | hibit; - - // h *= r, (partial) h %= p - let c = 0; - for (let i = 0; i < 10; i++) { - d[i] = c; - - for (let j = 0; j < 10; j++) { - let a = this.h[j]; - - if (j <= i) - a *= this.r[i - j]; - else - a *= 5 * this.r[i + 10 - j]; - - d[i] += a; - - // Sum(h[i] * r[i] * 5) will overflow slightly - // above 6 products with an unclamped r, so - // carry at 5 - if (j === 4) { - c = d[i] >>> 13; - d[i] &= 0x1fff; - } - } - - c += d[i] >>> 13; - d[i] &= 0x1fff; - } - - c = (c << 2) + c; // c *= 5 - c += d[0]; - d[0] = (c & 0x1fff); - c = c >>> 13; - d[1] += c; - - for (let i = 0; i < 10; i++) - this.h[i] = d[i]; - - m += 16; - bytes -= 16; - } -}; - -/** - * Update the MAC with data (will be - * processed as 16 byte blocks). - * @param {Buffer} data - */ - -Poly1305.prototype.update = function update(data) { - let bytes = data.length; - let m = 0; - - // handle leftover - if (this.leftover) { - let want = 16 - this.leftover; - - if (want > bytes) - want = bytes; - - for (let i = 0; i < want; i++) - this.buffer[this.leftover + i] = data[m + i]; - - bytes -= want; - m += want; - - this.leftover += want; - - if (this.leftover < 16) - return; - - this.blocks(this.buffer, 16, 0); - this.leftover = 0; - } - - // process full blocks - if (bytes >= 16) { - const want = bytes & ~(16 - 1); - this.blocks(data, want, m); - m += want; - bytes -= want; - } - - // store leftover - if (bytes) { - for (let i = 0; i < bytes; i++) - this.buffer[this.leftover + i] = data[m + i]; - this.leftover += bytes; - } -}; - -/** - * Finalize and return a 16-byte MAC. - * @returns {Buffer} - */ - -Poly1305.prototype.finish = function finish() { - const mac = Buffer.allocUnsafe(16); - const g = new Uint16Array(10); - - // process the remaining block - if (this.leftover) { - let i = this.leftover; - this.buffer[i++] = 1; - for (; i < 16; i++) - this.buffer[i] = 0; - this.fin = 1; - this.blocks(this.buffer, 16, 0); - } - - // fully carry h - let c = this.h[1] >>> 13; - this.h[1] &= 0x1fff; - for (let i = 2; i < 10; i++) { - this.h[i] += c; - c = this.h[i] >>> 13; - this.h[i] &= 0x1fff; - } - this.h[0] += c * 5; - c = this.h[0] >>> 13; - this.h[0] &= 0x1fff; - this.h[1] += c; - c = this.h[1] >>> 13; - this.h[1] &= 0x1fff; - this.h[2] += c; - - // compute h + -p - g[0] = this.h[0] + 5; - c = g[0] >>> 13; - g[0] &= 0x1fff; - for (let i = 1; i < 10; i++) { - g[i] = this.h[i] + c; - c = g[i] >>> 13; - g[i] &= 0x1fff; - } - - // select h if h < p, or h + -p if h >= p - let mask = (c ^ 1) - 1; - for (let i = 0; i < 10; i++) - g[i] &= mask; - mask = ~mask; - for (let i = 0; i < 10; i++) - this.h[i] = (this.h[i] & mask) | g[i]; - - // h = h % (2^128) - this.h[0] = ((this.h[0]) | (this.h[1] << 13)) & 0xffff; - this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10)) & 0xffff; - this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7)) & 0xffff; - this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4)) & 0xffff; - this.h[4] = ((this.h[4] >>> 12) - | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff; - this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11)) & 0xffff; - this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8)) & 0xffff; - this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5)) & 0xffff; - - // mac = (h + pad) % (2^128) - let f = this.h[0] + this.pad[0]; - this.h[0] = f; - for (let i = 1; i < 8; i++) { - f = this.h[i] + this.pad[i] + (f >>> 16); - this.h[i] = f; - } - - for (let i = 0; i < 8; i++) - mac.writeUInt16LE(this.h[i], i * 2, true); - - // zero out the state - for (let i = 0; i < 10; i++) - this.h[i] = 0; - - for (let i = 0; i < 10; i++) - this.r[i] = 0; - - for (let i = 0; i < 8; i++) - this.pad[i] = 0; - - return mac; -}; - -/** - * Return a MAC for a message and key. - * @param {Buffer} msg - * @param {Buffer} key - * @returns {Buffer} MAC - */ - -Poly1305.auth = function auth(msg, key) { - const poly = new Poly1305(); - poly.init(key); - poly.update(msg); - return poly.finish(); -}; - -/** - * Compare two MACs in constant time. - * @param {Buffer} mac1 - * @param {Buffer} mac2 - * @returns {Boolean} - */ - -Poly1305.verify = function verify(mac1, mac2) { - let dif = 0; - - // Compare in constant time. - for (let i = 0; i < 16; i++) - dif |= mac1[i] ^ mac2[i]; - - dif = (dif - 1) >>> 31; - - return (dif & 1) !== 0; -}; - -if (native) - Poly1305 = native.Poly1305; - -/* - * Expose - */ - -module.exports = Poly1305; diff --git a/lib/crypto/random-browser.js b/lib/crypto/random-browser.js deleted file mode 100644 index 0f102b05..00000000 --- a/lib/crypto/random-browser.js +++ /dev/null @@ -1,63 +0,0 @@ -/*! - * random-browser.js - randomness for bcoin - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto.random-browser - * @ignore - */ - -const crypto = global.crypto || global.msCrypto || {}; - -/** - * Generate pseudo-random bytes. - * @param {Number} size - * @returns {Buffer} - */ - -exports.randomBytes = function randomBytes(size) { - const data = new Uint8Array(size); - crypto.getRandomValues(data); - return Buffer.from(data.buffer); -}; - -if (!crypto.getRandomValues) { - // Out of luck here. Use bad randomness for now. - exports.randomBytes = function randomBytes(size) { - const data = Buffer.allocUnsafe(size); - - for (let i = 0; i < data.length; i++) - data[i] = Math.floor(Math.random() * 256); - - return data; - }; -} - -/** - * Generate a random uint32. - * Probably more cryptographically sound than - * `Math.random()`. - * @returns {Number} - */ - -exports.randomInt = function randomInt() { - return exports.randomBytes(4).readUInt32LE(0, true); -}; - -/** - * Generate a random number within a range. - * Probably more cryptographically sound than - * `Math.random()`. - * @param {Number} min - Inclusive. - * @param {Number} max - Exclusive. - * @returns {Number} - */ - -exports.randomRange = function randomRange(min, max) { - const num = exports.randomInt(); - return Math.floor((num / 0x100000000) * (max - min) + min); -}; diff --git a/lib/crypto/random.js b/lib/crypto/random.js deleted file mode 100644 index e98c2919..00000000 --- a/lib/crypto/random.js +++ /dev/null @@ -1,47 +0,0 @@ -/*! - * random.js - randomness for bcoin - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto.random - */ - -const crypto = require('crypto'); - -/** - * Generate pseudo-random bytes. - * @function - * @param {Number} size - * @returns {Buffer} - */ - -exports.randomBytes = crypto.randomBytes; - -/** - * Generate a random uint32. - * Probably more cryptographically sound than - * `Math.random()`. - * @returns {Number} - */ - -exports.randomInt = function randomInt() { - return exports.randomBytes(4).readUInt32LE(0, true); -}; - -/** - * Generate a random number within a range. - * Probably more cryptographically sound than - * `Math.random()`. - * @param {Number} min - Inclusive. - * @param {Number} max - Exclusive. - * @returns {Number} - */ - -exports.randomRange = function randomRange(min, max) { - const num = exports.randomInt(); - return Math.floor((num / 0x100000000) * (max - min) + min); -}; diff --git a/lib/crypto/rsa-browser.js b/lib/crypto/rsa-browser.js deleted file mode 100644 index 6029fafc..00000000 --- a/lib/crypto/rsa-browser.js +++ /dev/null @@ -1,186 +0,0 @@ -/*! - * rsa-browser.js - rsa for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -const assert = require('assert'); -const BN = require('./bn'); -const ASN1 = require('../utils/asn1'); -const digest = require('./digest'); -const ccmp = require('./ccmp'); - -/** - * @exports crypto/rsa - * @ignore - */ - -const rsa = exports; - -/** - * PKCS signature prefixes. - * @type {Object} - */ - -rsa.prefixes = { - md5: Buffer.from('3020300c06082a864886f70d020505000410', 'hex'), - sha1: Buffer.from('3021300906052b0e03021a05000414', 'hex'), - sha224: Buffer.from('302d300d06096086480165030402040500041c', 'hex'), - sha256: Buffer.from('3031300d060960864801650304020105000420', 'hex'), - sha384: Buffer.from('3041300d060960864801650304020205000430', 'hex'), - sha512: Buffer.from('3051300d060960864801650304020305000440', 'hex'), - ripemd160: Buffer.from('30203008060628cf060300310414', 'hex') -}; - -/** - * Verify RSA signature. - * @param {String} alg - Hash algorithm. - * @param {Buffer} msg - Signed message. - * @param {Buffer} sig - Signature. - * @param {Buffer} key - ASN1 serialized RSA key. - * @returns {Boolean} - */ - -rsa.verify = function verify(alg, msg, sig, key) { - assert(typeof alg === 'string', 'No algorithm selected.'); - assert(Buffer.isBuffer(msg)); - assert(Buffer.isBuffer(sig)); - assert(Buffer.isBuffer(key)); - - const prefix = rsa.prefixes[alg]; - - if (!prefix) - throw new Error('Unknown PKCS prefix.'); - - const hash = digest.hash(alg, msg); - const len = prefix.length + hash.length; - const pub = ASN1.parseRSAPublic(key); - - const N = new BN(pub.modulus); - const e = new BN(pub.publicExponent); - const k = Math.ceil(N.bitLength() / 8); - - if (k < len + 11) - throw new Error('Message too long.'); - - const m = rsa.encrypt(N, e, sig); - const em = leftpad(m, k); - - let ok = ceq(em[0], 0x00); - ok &= ceq(em[1], 0x01); - ok &= ccmp(em.slice(k - hash.length, k), hash); - ok &= ccmp(em.slice(k - len, k - hash.length), prefix); - ok &= ceq(em[k - len - 1], 0x00); - - for (let i = 2; i < k - len - 1; i++) - ok &= ceq(em[i], 0xff); - - return ok === 1; -}; - -/** - * Sign message with RSA key. - * @param {String} alg - Hash algorithm. - * @param {Buffer} msg - Signed message. - * @param {Buffer} key - ASN1 serialized RSA key. - * @returns {Buffer} Signature (DER) - */ - -rsa.sign = function sign(alg, msg, key) { - assert(typeof alg === 'string', 'No algorithm selected.'); - assert(Buffer.isBuffer(msg)); - assert(Buffer.isBuffer(key)); - - const prefix = rsa.prefixes[alg]; - - if (!prefix) - throw new Error('Unknown PKCS prefix.'); - - const hash = digest.hash(alg, msg); - const len = prefix.length + hash.length; - const priv = ASN1.parseRSAPrivate(key); - - const N = new BN(priv.modulus); - const D = new BN(priv.privateExponent); - const k = Math.ceil(N.bitLength() / 8); - - if (k < len + 11) - throw new Error('Message too long.'); - - const em = Buffer.allocUnsafe(k); - em.fill(0); - - em[1] = 0x01; - for (let i = 2; i < k - len - 1; i++) - em[i] = 0xff; - - prefix.copy(em, k - len); - hash.copy(em, k - hash.length); - - return rsa.decrypt(N, D, em); -}; - -/** - * Decrypt with modulus and exponent. - * @param {BN} N - * @param {BN} D - * @param {Buffer} m - * @returns {Buffer} - */ - -rsa.decrypt = function decrypt(N, D, m) { - const c = new BN(m); - - if (c.cmp(N) > 0) - throw new Error('Cannot decrypt.'); - - return c - .toRed(BN.red(N)) - .redPow(D) - .fromRed() - .toArrayLike(Buffer, 'be'); -}; - -/** - * Encrypt with modulus and exponent. - * @param {BN} N - * @param {BN} e - * @param {Buffer} m - * @returns {Buffer} - */ - -rsa.encrypt = function encrypt(N, e, m) { - return new BN(m) - .toRed(BN.red(N)) - .redPow(e) - .fromRed() - .toArrayLike(Buffer, 'be'); -}; - -/* - * Helpers - */ - -function leftpad(input, size) { - let n = input.length; - - if (n > size) - n = size; - - const out = Buffer.allocUnsafe(size); - out.fill(0); - - input.copy(out, out.length - n); - - return out; -} - -function ceq(a, b) { - let r = ~(a ^ b) & 0xff; - r &= r >>> 4; - r &= r >>> 2; - r &= r >>> 1; - return r === 1; -} diff --git a/lib/crypto/rsa.js b/lib/crypto/rsa.js deleted file mode 100644 index c8a3b57c..00000000 --- a/lib/crypto/rsa.js +++ /dev/null @@ -1,72 +0,0 @@ -/*! - * rsa.js - RSA for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -/** - * @module crypto/rsa - */ - -const assert = require('assert'); -const crypto = require('crypto'); -const PEM = require('../utils/pem'); - -/** - * Verify RSA signature. - * @param {String} alg - Hash algorithm. - * @param {Buffer} msg - Signed message. - * @param {Buffer} sig - Signature. - * @param {Buffer} key - ASN1 serialized RSA key. - * @returns {Boolean} - */ - -exports.verify = function verify(alg, msg, sig, key) { - assert(typeof alg === 'string', 'No algorithm selected.'); - assert(Buffer.isBuffer(msg)); - assert(Buffer.isBuffer(sig)); - assert(Buffer.isBuffer(key)); - - const name = normalizeAlg('rsa', alg); - const pem = PEM.encode(key, 'rsa', 'public key'); - const ctx = crypto.createVerify(name); - - try { - ctx.update(msg); - return ctx.verify(pem, sig); - } catch (e) { - return false; - } -}; - -/** - * Sign message with RSA key. - * @param {String} alg - Hash algorithm. - * @param {Buffer} msg - Signed message. - * @param {Buffer} key - ASN1 serialized RSA key. - * @returns {Buffer} Signature (DER) - */ - -exports.sign = function sign(alg, msg, key) { - assert(typeof alg === 'string', 'No algorithm selected.'); - assert(Buffer.isBuffer(msg)); - assert(Buffer.isBuffer(key)); - - const name = normalizeAlg('rsa', alg); - const pem = PEM.encode(key, 'rsa', 'private key'); - const ctx = crypto.createSign(name); - - ctx.update(msg); - - return ctx.sign(pem); -}; - -/* - * Helpers - */ - -function normalizeAlg(alg, hash) { - return `${alg.toUpperCase()}-${hash.toUpperCase()}`; -} diff --git a/lib/crypto/schnorr.js b/lib/crypto/schnorr.js deleted file mode 100644 index c5c67be7..00000000 --- a/lib/crypto/schnorr.js +++ /dev/null @@ -1,342 +0,0 @@ -/*! - * schnorr.js - schnorr signatures for bcoin - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -const assert = require('assert'); -const elliptic = require('elliptic'); -const Signature = require('elliptic/lib/elliptic/ec/signature'); -const BN = require('./bn'); -const HmacDRBG = require('./hmac-drbg'); -const sha256 = require('./digest').sha256; -const curve = elliptic.ec('secp256k1').curve; -const POOL64 = Buffer.allocUnsafe(64); - -/** - * @exports crypto/schnorr - */ - -const schnorr = exports; - -/** - * Hash (r | M). - * @param {Buffer} msg - * @param {BN} r - * @returns {Buffer} - */ - -schnorr.hash = function hash(msg, r) { - const R = r.toArrayLike(Buffer, 'be', 32); - const B = POOL64; - - R.copy(B, 0); - msg.copy(B, 32); - - return new BN(sha256(B)); -}; - -/** - * Sign message. - * @private - * @param {Buffer} msg - * @param {BN} priv - * @param {BN} k - * @param {Buffer} pn - * @returns {Signature|null} - */ - -schnorr.trySign = function trySign(msg, prv, k, pn) { - if (prv.isZero()) - throw new Error('Bad private key.'); - - if (prv.gte(curve.n)) - throw new Error('Bad private key.'); - - if (k.isZero()) - return null; - - if (k.gte(curve.n)) - return null; - - let r = curve.g.mul(k); - - if (pn) - r = r.add(pn); - - if (r.y.isOdd()) { - k = k.umod(curve.n); - k = curve.n.sub(k); - } - - const h = schnorr.hash(msg, r.getX()); - - if (h.isZero()) - return null; - - if (h.gte(curve.n)) - return null; - - let s = h.imul(prv); - s = k.isub(s); - s = s.umod(curve.n); - - if (s.isZero()) - return null; - - return new Signature({ r: r.getX(), s: s }); -}; - -/** - * Sign message. - * @param {Buffer} msg - * @param {Buffer} key - * @param {Buffer} pubNonce - * @returns {Signature} - */ - -schnorr.sign = function sign(msg, key, pubNonce) { - const prv = new BN(key); - const drbg = schnorr.drbg(msg, key, pubNonce); - const len = curve.n.byteLength(); - - let pn; - if (pubNonce) - pn = curve.decodePoint(pubNonce); - - let sig; - while (!sig) { - const k = new BN(drbg.generate(len)); - sig = schnorr.trySign(msg, prv, k, pn); - } - - return sig; -}; - -/** - * Verify signature. - * @param {Buffer} msg - * @param {Buffer} signature - * @param {Buffer} key - * @returns {Buffer} - */ - -schnorr.verify = function verify(msg, signature, key) { - const sig = new Signature(signature); - const h = schnorr.hash(msg, sig.r); - - if (h.gte(curve.n)) - throw new Error('Invalid hash.'); - - if (h.isZero()) - throw new Error('Invalid hash.'); - - if (sig.s.gte(curve.n)) - throw new Error('Invalid S value.'); - - if (sig.r.gt(curve.p)) - throw new Error('Invalid R value.'); - - const k = curve.decodePoint(key); - const l = k.mul(h); - const r = curve.g.mul(sig.s); - const rl = l.add(r); - - if (rl.y.isOdd()) - throw new Error('Odd R value.'); - - return rl.getX().eq(sig.r); -}; - -/** - * Recover public key. - * @param {Buffer} msg - * @param {Buffer} signature - * @returns {Buffer} - */ - -schnorr.recover = function recover(signature, msg) { - const sig = new Signature(signature); - const h = schnorr.hash(msg, sig.r); - - if (h.gte(curve.n)) - throw new Error('Invalid hash.'); - - if (h.isZero()) - throw new Error('Invalid hash.'); - - if (sig.s.gte(curve.n)) - throw new Error('Invalid S value.'); - - if (sig.r.gt(curve.p)) - throw new Error('Invalid R value.'); - - let hinv = h.invm(curve.n); - hinv = hinv.umod(curve.n); - - let s = sig.s; - s = curve.n.sub(s); - s = s.umod(curve.n); - - s = s.imul(hinv); - s = s.umod(curve.n); - - const R = curve.pointFromX(sig.r, false); - let l = R.mul(hinv); - let r = curve.g.mul(s); - const k = l.add(r); - - l = k.mul(h); - r = curve.g.mul(sig.s); - - const rl = l.add(r); - - if (rl.y.isOdd()) - throw new Error('Odd R value.'); - - if (!rl.getX().eq(sig.r)) - throw new Error('Could not recover pubkey.'); - - return Buffer.from(k.encode('array', true)); -}; - -/** - * Combine signatures. - * @param {Buffer[]} sigs - * @returns {Signature} - */ - -schnorr.combineSigs = function combineSigs(sigs) { - let s = new BN(0); - let r, last; - - for (let i = 0; i < sigs.length; i++) { - const sig = new Signature(sigs[i]); - - if (sig.s.isZero()) - throw new Error('Bad S value.'); - - if (sig.s.gte(curve.n)) - throw new Error('Bad S value.'); - - if (!r) - r = sig.r; - - if (last && !last.r.eq(sig.r)) - throw new Error('Bad signature combination.'); - - s = s.iadd(sig.s); - s = s.umod(curve.n); - - last = sig; - } - - if (s.isZero()) - throw new Error('Bad combined signature.'); - - return new Signature({ r: r, s: s }); -}; - -/** - * Combine public keys. - * @param {Buffer[]} keys - * @returns {Buffer} - */ - -schnorr.combineKeys = function combineKeys(keys) { - if (keys.length === 0) - throw new Error(); - - if (keys.length === 1) - return keys[0]; - - let point = curve.decodePoint(keys[0]); - - for (let i = 1; i < keys.length; i++) { - const key = curve.decodePoint(keys[i]); - point = point.add(key); - } - - return Buffer.from(point.encode('array', true)); -}; - -/** - * Partially sign. - * @param {Buffer} msg - * @param {Buffer} priv - * @param {Buffer} privNonce - * @param {Buffer} pubNonce - * @returns {Buffer} - */ - -schnorr.partialSign = function partialSign(msg, priv, privNonce, pubNonce) { - const prv = new BN(priv); - const k = new BN(privNonce); - const pn = curve.decodePoint(pubNonce); - const sig = schnorr.trySign(msg, prv, k, pn); - - if (!sig) - throw new Error('Bad K value.'); - - return sig; -}; - -/** - * Schnorr personalization string. - * @const {Buffer} - */ - -schnorr.alg = Buffer.from('Schnorr+SHA256 ', 'ascii'); - -/** - * Instantiate an HMAC-DRBG. - * @param {Buffer} msg - * @param {Buffer} priv - * @param {Buffer} data - * @returns {HmacDRBG} - */ - -schnorr.drbg = function drbg(msg, priv, data) { - const pers = Buffer.allocUnsafe(48); - - pers.fill(0); - - if (data) { - assert(data.length === 32); - data.copy(pers, 0); - } - - schnorr.alg.copy(pers, 32); - - return new HmacDRBG(priv, msg, pers); -}; - -/** - * Generate pub+priv nonce pair. - * @param {Buffer} msg - * @param {Buffer} priv - * @param {Buffer} data - * @returns {Buffer} - */ - -schnorr.generateNoncePair = function generateNoncePair(msg, priv, data) { - const drbg = schnorr.drbg(msg, priv, data); - const len = curve.n.byteLength(); - - let k; - for (;;) { - k = new BN(drbg.generate(len)); - - if (k.isZero()) - continue; - - if (k.gte(curve.n)) - continue; - - break; - } - - return Buffer.from(curve.g.mul(k).encode('array', true)); -}; diff --git a/lib/crypto/scrypt.js b/lib/crypto/scrypt.js deleted file mode 100644 index b9fbe89e..00000000 --- a/lib/crypto/scrypt.js +++ /dev/null @@ -1,269 +0,0 @@ -/*! - * scrypt.js - scrypt for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - * - * Ported from: - * https://github.com/Tarsnap/scrypt/blob/master/lib/crypto/crypto_scrypt-ref.c - * - * Copyright 2009 Colin Percival - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* eslint camelcase: "off" */ - -'use strict'; - -/** - * @module crypto/scrypt - */ - -const pbkdf2 = require('./pbkdf2'); -const native = require('../native').binding; - -/** - * Javascript scrypt implementation. Scrypt is - * used in bip38. Bcoin doesn't support bip38 - * yet, but here it is, just in case. - * @alias module:crypto/scrypt.derive - * @param {Buffer} passwd - * @param {Buffer} salt - * @param {Number} N - * @param {Number} r - * @param {Number} p - * @param {Number} len - * @returns {Buffer} - */ - -function derive(passwd, salt, N, r, p, len) { - if (r * p >= (1 << 30)) - throw new Error('EFBIG'); - - if ((N & (N - 1)) !== 0 || N === 0) - throw new Error('EINVAL'); - - if (N > 0xffffffff) - throw new Error('EINVAL'); - - const XY = Buffer.allocUnsafe(256 * r); - const V = Buffer.allocUnsafe(128 * r * N); - - const B = pbkdf2.derive(passwd, salt, 1, p * 128 * r, 'sha256'); - - for (let i = 0; i < p; i++) - smix(B, i * 128 * r, r, N, V, XY); - - return pbkdf2.derive(passwd, B, 1, len, 'sha256'); -} - -if (native) - derive = native.scrypt; - -/** - * Asynchronous scrypt implementation. - * @alias module:crypto/scrypt.deriveAsync - * @function - * @param {Buffer} passwd - * @param {Buffer} salt - * @param {Number} N - * @param {Number} r - * @param {Number} p - * @param {Number} len - * @returns {Promise} - */ - -async function deriveAsync(passwd, salt, N, r, p, len) { - if (r * p >= (1 << 30)) - throw new Error('EFBIG'); - - if ((N & (N - 1)) !== 0 || N === 0) - throw new Error('EINVAL'); - - if (N > 0xffffffff) - throw new Error('EINVAL'); - - const XY = Buffer.allocUnsafe(256 * r); - const V = Buffer.allocUnsafe(128 * r * N); - - const B = await pbkdf2.deriveAsync(passwd, salt, 1, p * 128 * r, 'sha256'); - - for (let i = 0; i < p; i++) - await smixAsync(B, i * 128 * r, r, N, V, XY); - - return await pbkdf2.deriveAsync(passwd, B, 1, len, 'sha256'); -} - -if (native) - deriveAsync = native.scryptAsync; - -/* - * Helpers - */ - -function salsa20_8(B) { - const B32 = new Uint32Array(16); - const x = new Uint32Array(16); - - for (let i = 0; i < 16; i++) - B32[i] = B.readUInt32LE(i * 4, true); - - for (let i = 0; i < 16; i++) - x[i] = B32[i]; - - for (let i = 0; i < 8; i += 2) { - x[4] ^= R(x[0] + x[12], 7); - x[8] ^= R(x[4] + x[0], 9); - x[12] ^= R(x[8] + x[4], 13); - x[0] ^= R(x[12] + x[8], 18); - - x[9] ^= R(x[5] + x[1], 7); - x[13] ^= R(x[9] + x[5], 9); - x[1] ^= R(x[13] + x[9], 13); - x[5] ^= R(x[1] + x[13], 18); - - x[14] ^= R(x[10] + x[6], 7); - x[2] ^= R(x[14] + x[10], 9); - x[6] ^= R(x[2] + x[14], 13); - x[10] ^= R(x[6] + x[2], 18); - - x[3] ^= R(x[15] + x[11], 7); - x[7] ^= R(x[3] + x[15], 9); - x[11] ^= R(x[7] + x[3], 13); - x[15] ^= R(x[11] + x[7], 18); - - x[1] ^= R(x[0] + x[3], 7); - x[2] ^= R(x[1] + x[0], 9); - x[3] ^= R(x[2] + x[1], 13); - x[0] ^= R(x[3] + x[2], 18); - - x[6] ^= R(x[5] + x[4], 7); - x[7] ^= R(x[6] + x[5], 9); - x[4] ^= R(x[7] + x[6], 13); - x[5] ^= R(x[4] + x[7], 18); - - x[11] ^= R(x[10] + x[9], 7); - x[8] ^= R(x[11] + x[10], 9); - x[9] ^= R(x[8] + x[11], 13); - x[10] ^= R(x[9] + x[8], 18); - - x[12] ^= R(x[15] + x[14], 7); - x[13] ^= R(x[12] + x[15], 9); - x[14] ^= R(x[13] + x[12], 13); - x[15] ^= R(x[14] + x[13], 18); - } - - for (let i = 0; i < 16; i++) - B32[i] += x[i]; - - for (let i = 0; i < 16; i++) - B.writeUInt32LE(B32[i], 4 * i, true); -} - -function R(a, b) { - return (a << b) | (a >>> (32 - b)); -} - -function blockmix_salsa8(B, Y, Yo, r) { - const X = Buffer.allocUnsafe(64); - - blkcpy(X, B, 0, (2 * r - 1) * 64, 64); - - for (let i = 0; i < 2 * r; i++) { - blkxor(X, B, 0, i * 64, 64); - salsa20_8(X); - blkcpy(Y, X, Yo + i * 64, 0, 64); - } - - for (let i = 0; i < r; i++) - blkcpy(B, Y, i * 64, Yo + (i * 2) * 64, 64); - - for (let i = 0; i < r; i++) - blkcpy(B, Y, (i + r) * 64, Yo + (i * 2 + 1) * 64, 64); -} - -function integerify(B, r) { - return B.readUInt32LE((2 * r - 1) * 64, true); -} - -function smix(B, Bo, r, N, V, XY) { - const X = XY; - const Y = XY; - - blkcpy(X, B, 0, Bo, 128 * r); - - for (let i = 0; i < N; i++) { - blkcpy(V, X, i * (128 * r), 0, 128 * r); - blockmix_salsa8(X, Y, 128 * r, r); - } - - for (let i = 0; i < N; i++) { - const j = integerify(X, r) & (N - 1); - blkxor(X, V, 0, j * (128 * r), 128 * r); - blockmix_salsa8(X, Y, 128 * r, r); - } - - blkcpy(B, X, Bo, 0, 128 * r); -} - -async function smixAsync(B, Bo, r, N, V, XY) { - const X = XY; - const Y = XY; - - blkcpy(X, B, 0, Bo, 128 * r); - - for (let i = 0; i < N; i++) { - blkcpy(V, X, i * (128 * r), 0, 128 * r); - blockmix_salsa8(X, Y, 128 * r, r); - await wait(); - } - - for (let i = 0; i < N; i++) { - const j = integerify(X, r) & (N - 1); - blkxor(X, V, 0, j * (128 * r), 128 * r); - blockmix_salsa8(X, Y, 128 * r, r); - await wait(); - } - - blkcpy(B, X, Bo, 0, 128 * r); -} - -function blkcpy(dest, src, s1, s2, len) { - src.copy(dest, s1, s2, s2 + len); -} - -function blkxor(dest, src, s1, s2, len) { - for (let i = 0; i < len; i++) - dest[s1 + i] ^= src[s2 + i]; -} - -function wait() { - return new Promise(r => setImmediate(r)); -} - -/* - * Expose - */ - -exports.derive = derive; -exports.deriveAsync = deriveAsync; diff --git a/lib/crypto/secp256k1-browser.js b/lib/crypto/secp256k1-browser.js deleted file mode 100644 index d71dd6d6..00000000 --- a/lib/crypto/secp256k1-browser.js +++ /dev/null @@ -1,345 +0,0 @@ -/*! - * secp256k1-elliptic.js - wrapper for elliptic - * Copyright (c) 2014-2015, Fedor Indutny (MIT License) - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -const assert = require('assert'); -const elliptic = require('elliptic'); -const secp256k1 = elliptic.ec('secp256k1'); -const Signature = require('elliptic/lib/elliptic/ec/signature'); -const BN = require('./bn'); -const curve = secp256k1.curve; - -/** - * @exports crypto/secp256k1-elliptic - * @ignore - */ - -const ec = exports; - -/** - * Whether we're using native bindings. - * @const {Boolean} - */ - -ec.binding = false; - -/** - * Generate a private key. - * @returns {Buffer} Private key. - */ - -ec.generatePrivateKey = function generatePrivateKey() { - const key = secp256k1.genKeyPair(); - return key.getPrivate().toArrayLike(Buffer, 'be', 32); -}; - -/** - * Create a public key from a private key. - * @param {Buffer} priv - * @param {Boolean?} compress - * @returns {Buffer} - */ - -ec.publicKeyCreate = function publicKeyCreate(priv, compress) { - if (compress == null) - compress = true; - - assert(Buffer.isBuffer(priv)); - - const key = secp256k1.keyPair({ priv: priv }); - - return Buffer.from(key.getPublic(compress, 'array')); -}; - -/** - * Compress or decompress public key. - * @param {Buffer} pub - * @returns {Buffer} - */ - -ec.publicKeyConvert = function publicKeyConvert(key, compress) { - if (compress == null) - compress = true; - - const point = curve.decodePoint(key); - - return Buffer.from(point.encode('array', compress)); -}; - -/** - * ((tweak + key) % n) - * @param {Buffer} privateKey - * @param {Buffer} tweak - * @returns {Buffer} privateKey - */ - -ec.privateKeyTweakAdd = function privateKeyTweakAdd(privateKey, tweak) { - const key = new BN(tweak) - .add(new BN(privateKey)) - .mod(curve.n) - .toArrayLike(Buffer, 'be', 32); - - // Only a 1 in 2^127 chance of happening. - if (!ec.privateKeyVerify(key)) - throw new Error('Private key is invalid.'); - - return key; -}; - -/** - * ((g * tweak) + key) - * @param {Buffer} publicKey - * @param {Buffer} tweak - * @returns {Buffer} publicKey - */ - -ec.publicKeyTweakAdd = function publicKeyTweakAdd(publicKey, tweak, compress) { - if (compress == null) - compress = true; - - const key = curve.decodePoint(publicKey); - const point = curve.g.mul(new BN(tweak)).add(key); - const pub = Buffer.from(point.encode('array', compress)); - - if (!ec.publicKeyVerify(pub)) - throw new Error('Public key is invalid.'); - - return pub; -}; - -/** - * Create an ecdh. - * @param {Buffer} pub - * @param {Buffer} priv - * @returns {Buffer} - */ - -ec.ecdh = function ecdh(pub, priv) { - priv = secp256k1.keyPair({ priv: priv }); - pub = secp256k1.keyPair({ pub: pub }); - return priv.derive(pub.getPublic()).toArrayLike(Buffer, 'be', 32); -}; - -/** - * Recover a public key. - * @param {Buffer} msg - * @param {Buffer} sig - * @param {Number?} j - * @param {Boolean?} compress - * @returns {Buffer[]|Buffer|null} - */ - -ec.recover = function recover(msg, sig, j, compress) { - if (!j) - j = 0; - - if (compress == null) - compress = true; - - let point; - try { - point = secp256k1.recoverPubKey(msg, sig, j); - } catch (e) { - return null; - } - - return Buffer.from(point.encode('array', compress)); -}; - -/** - * Verify a signature. - * @param {Buffer} msg - * @param {Buffer} sig - DER formatted. - * @param {Buffer} key - * @returns {Boolean} - */ - -ec.verify = function verify(msg, sig, key) { - assert(Buffer.isBuffer(msg)); - assert(Buffer.isBuffer(sig)); - assert(Buffer.isBuffer(key)); - - if (sig.length === 0) - return false; - - if (key.length === 0) - return false; - - // Attempt to normalize the signature - // length before passing to elliptic. - // https://github.com/indutny/elliptic/issues/78 - sig = normalizeLength(sig); - - try { - return secp256k1.verify(msg, sig, key); - } catch (e) { - return false; - } -}; - -/** - * Validate a public key. - * @param {Buffer} key - * @returns {Boolean} True if buffer is a valid public key. - */ - -ec.publicKeyVerify = function publicKeyVerify(key) { - try { - const pub = secp256k1.keyPair({ pub: key }); - return pub.validate(); - } catch (e) { - return false; - } -}; - -/** - * Validate a private key. - * @param {Buffer} key - * @returns {Boolean} True if buffer is a valid private key. - */ - -ec.privateKeyVerify = function privateKeyVerify(key) { - if (key.length !== 32) - return false; - - key = new BN(key); - - return !key.isZero() && key.lt(curve.n); -}; - -/** - * Sign a message. - * @param {Buffer} msg - * @param {Buffer} key - Private key. - * @returns {Buffer} DER-formatted signature. - */ - -ec.sign = function sign(msg, key) { - assert(Buffer.isBuffer(msg)); - assert(Buffer.isBuffer(key)); - - // Sign message and ensure low S value - const sig = secp256k1.sign(msg, key, { canonical: true }); - - // Convert to DER - return Buffer.from(sig.toDER()); -}; - -/** - * Convert DER signature to R/S. - * @param {Buffer} raw - * @returns {Buffer} R/S-formatted signature. - */ - -ec.fromDER = function fromDER(raw) { - assert(Buffer.isBuffer(raw)); - - const sig = new Signature(raw); - const out = Buffer.allocUnsafe(64); - - sig.r.toArrayLike(Buffer, 'be', 32).copy(out, 0); - sig.s.toArrayLike(Buffer, 'be', 32).copy(out, 32); - - return out; -}; - -/** - * Convert R/S signature to DER. - * @param {Buffer} sig - * @returns {Buffer} DER-formatted signature. - */ - -ec.toDER = function toDER(raw) { - assert(Buffer.isBuffer(raw)); - - const sig = new Signature({ - r: new BN(raw.slice(0, 32), 'be'), - s: new BN(raw.slice(32, 64), 'be') - }); - - return Buffer.from(sig.toDER()); -}; - -/** - * Test whether a signature has a low S value. - * @param {Buffer} sig - * @returns {Boolean} - */ - -ec.isLowS = function isLowS(raw) { - let sig; - try { - sig = new Signature(raw); - } catch (e) { - return false; - } - - if (sig.s.isZero()) - return false; - - // If S is greater than half the order, - // it's too high. - if (sig.s.gt(secp256k1.nh)) - return false; - - return true; -}; - -/* - * Helpers - */ - -function normalizeLength(sig) { - let data = sig; - let pos = 0; - let len; - - if (data[pos++] !== 0x30) - return sig; - - [len, pos] = getLength(data, pos); - - if (data.length > len + pos) - data = data.slice(0, len + pos); - - if (data[pos++] !== 0x02) - return sig; - - // R length. - [len, pos] = getLength(data, pos); - - pos += len; - - if (data[pos++] !== 0x02) - return sig; - - // S length. - [len, pos] = getLength(data, pos); - - if (data.length > len + pos) - data = data.slice(0, len + pos); - - return data; -} - -function getLength(buf, pos) { - const initial = buf[pos++]; - - if (!(initial & 0x80)) - return [initial, pos]; - - const len = initial & 0xf; - let val = 0; - - for (let i = 0; i < len; i++) { - val <<= 8; - val |= buf[pos++]; - } - - return [val, pos]; -} diff --git a/lib/crypto/secp256k1-native.js b/lib/crypto/secp256k1-native.js deleted file mode 100644 index 8e2f58ce..00000000 --- a/lib/crypto/secp256k1-native.js +++ /dev/null @@ -1,257 +0,0 @@ -/*! - * secp256k1-native.js - wrapper for secp256k1-node - * Copyright (c) 2014-2015, Fedor Indutny (MIT License) - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -const assert = require('assert'); -const secp256k1 = require('secp256k1'); -const random = require('./random'); - -/** - * @exports crypto/secp256k1 - */ - -const ec = exports; - -/* - * Constants - */ - -const ZERO_S = Buffer.from( - '0000000000000000000000000000000000000000000000000000000000000000', - 'hex' -); - -const HALF_ORDER = Buffer.from( - '7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', - 'hex'); - -/** - * Whether we're using native bindings. - * @const {Boolean} - * @private - */ - -ec.binding = true; - -/** - * Generate a private key. - * @returns {Buffer} Private key. - */ - -ec.generatePrivateKey = function generatePrivateKey() { - let priv; - - do { - priv = random.randomBytes(32); - } while (!secp256k1.privateKeyVerify(priv)); - - return priv; -}; - -/** - * Create a public key from a private key. - * @param {Buffer} priv - * @param {Boolean?} compress - * @returns {Buffer} - */ - -ec.publicKeyCreate = function publicKeyCreate(priv, compress) { - assert(Buffer.isBuffer(priv)); - return secp256k1.publicKeyCreate(priv, compress); -}; - -/** - * Compress or decompress public key. - * @param {Buffer} pub - * @returns {Buffer} - */ - -ec.publicKeyConvert = function publicKeyConvert(key, compress) { - return secp256k1.publicKeyConvert(key, compress); -}; - -/** - * ((tweak + key) % n) - * @param {Buffer} privateKey - * @param {Buffer} tweak - * @returns {Buffer} privateKey - */ - -ec.privateKeyTweakAdd = function privateKeyTweakAdd(privateKey, tweak) { - return secp256k1.privateKeyTweakAdd(privateKey, tweak); -}; - -/** - * ((g * tweak) + key) - * @param {Buffer} publicKey - * @param {Buffer} tweak - * @returns {Buffer} publicKey - */ - -ec.publicKeyTweakAdd = function publicKeyTweakAdd(publicKey, tweak, compress) { - return secp256k1.publicKeyTweakAdd(publicKey, tweak, compress); -}; - -/** - * Create an ecdh. - * @param {Buffer} pub - * @param {Buffer} priv - * @returns {Buffer} - */ - -ec.ecdh = function ecdh(pub, priv) { - const point = secp256k1.ecdhUnsafe(pub, priv, true); - return point.slice(1, 33); -}; - -/** - * Recover a public key. - * @param {Buffer} msg - * @param {Buffer} sig - * @param {Number?} j - * @param {Boolean?} compress - * @returns {Buffer[]|Buffer|null} - */ - -ec.recover = function recover(msg, sig, j, compress) { - if (!j) - j = 0; - - try { - sig = secp256k1.signatureImport(sig); - } catch (e) { - return null; - } - - let key; - try { - key = secp256k1.recover(msg, sig, j, compress); - } catch (e) { - return null; - } - - return key; -}; - -/** - * Verify a signature. - * @param {Buffer} msg - * @param {Buffer} sig - DER formatted. - * @param {Buffer} key - * @returns {Boolean} - */ - -ec.verify = function verify(msg, sig, key) { - assert(Buffer.isBuffer(msg)); - assert(Buffer.isBuffer(sig)); - assert(Buffer.isBuffer(key)); - - if (sig.length === 0) - return false; - - if (key.length === 0) - return false; - - try { - sig = secp256k1.signatureImportLax(sig); - sig = secp256k1.signatureNormalize(sig); - return secp256k1.verify(msg, sig, key); - } catch (e) { - return false; - } -}; - -/** - * Validate a public key. - * @param {Buffer} key - * @returns {Boolean} True if buffer is a valid public key. - */ - -ec.publicKeyVerify = function publicKeyVerify(key) { - return secp256k1.publicKeyVerify(key); -}; - -/** - * Validate a private key. - * @param {Buffer} key - * @returns {Boolean} True if buffer is a valid private key. - */ - -ec.privateKeyVerify = function privateKeyVerify(key) { - return secp256k1.privateKeyVerify(key); -}; - -/** - * Sign a message. - * @param {Buffer} msg - * @param {Buffer} key - Private key. - * @returns {Buffer} DER-formatted signature. - */ - -ec.sign = function sign(msg, key) { - assert(Buffer.isBuffer(msg)); - assert(Buffer.isBuffer(key)); - - // Sign message - let sig = secp256k1.sign(msg, key); - - // Ensure low S value - sig = secp256k1.signatureNormalize(sig.signature); - - // Convert to DER - return secp256k1.signatureExport(sig); -}; - -/** - * Convert DER signature to R/S. - * @param {Buffer} sig - * @returns {Buffer} R/S-formatted signature. - */ - -ec.fromDER = function fromDER(sig) { - assert(Buffer.isBuffer(sig)); - return secp256k1.signatureImport(sig); -}; - -/** - * Convert R/S signature to DER. - * @param {Buffer} sig - * @returns {Buffer} DER-formatted signature. - */ - -ec.toDER = function toDER(sig) { - assert(Buffer.isBuffer(sig)); - return secp256k1.signatureExport(sig); -}; - -/** - * Test whether a signature has a low S value. - * @param {Buffer} sig - * @returns {Boolean} - */ - -ec.isLowS = function isLowS(sig) { - let s; - - try { - const rs = secp256k1.signatureImport(sig); - s = rs.slice(32, 64); - } catch (e) { - return false; - } - - if (s.equals(ZERO_S)) - return false; - - // If S is greater than half the order, - // it's too high. - if (s.compare(HALF_ORDER) > 0) - return false; - - return true; -}; diff --git a/lib/crypto/secp256k1.js b/lib/crypto/secp256k1.js deleted file mode 100644 index d2ee2f83..00000000 --- a/lib/crypto/secp256k1.js +++ /dev/null @@ -1,21 +0,0 @@ -/*! - * secp256k1.js - ecdsa wrapper for secp256k1 and elliptic - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -let native; - -if (Number(process.env.BCOIN_NO_SECP256K1) !== 1) { - try { - native = require('secp256k1/bindings'); - } catch (e) { - ; - } -} - -module.exports = native - ? require('./secp256k1-native') - : require('./secp256k1-browser'); diff --git a/lib/crypto/sha256.js b/lib/crypto/sha256.js deleted file mode 100644 index 9a25ade1..00000000 --- a/lib/crypto/sha256.js +++ /dev/null @@ -1,399 +0,0 @@ -/*! - * sha256.js - SHA256 implementation for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - * Parts of this software based on hash.js. - */ - -'use strict'; - -/** - * @module crypto/sha256 - * @ignore - */ - -/* - * Constants - */ - -const DESC = Buffer.allocUnsafe(8); -const BUFFER64 = Buffer.allocUnsafe(64); -const PADDING = Buffer.allocUnsafe(64); - -const K = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -]; - -PADDING.fill(0); -PADDING[0] = 0x80; - -/** - * SHA256 - * @alias module:crypto/sha256.SHA256 - * @constructor - * @property {Number[]} s - * @property {Number[]} w - * @property {Buffer} block - * @property {Number} bytes - */ - -function SHA256() { - if (!(this instanceof SHA256)) - return new SHA256(); - - this.s = new Array(8); - this.w = new Array(64); - this.block = Buffer.allocUnsafe(64); - this.bytes = 0; -} - -/** - * Initialize SHA256 context. - */ - -SHA256.prototype.init = function init() { - this.s[0] = 0x6a09e667; - this.s[1] = 0xbb67ae85; - this.s[2] = 0x3c6ef372; - this.s[3] = 0xa54ff53a; - this.s[4] = 0x510e527f; - this.s[5] = 0x9b05688c; - this.s[6] = 0x1f83d9ab; - this.s[7] = 0x5be0cd19; - this.bytes = 0; -}; - -/** - * Update SHA256 context. - * @param {Buffer} data - */ - -SHA256.prototype.update = function update(data) { - return this._update(data, data.length); -}; - -/** - * Finalize SHA256 context. - * @returns {Buffer} - */ - -SHA256.prototype.finish = function finish() { - return this._finish(Buffer.allocUnsafe(32)); -}; - -/** - * Update SHA256 context. - * @private - * @param {Buffer} data - * @param {Number} len - */ - -SHA256.prototype._update = function _update(data, len) { - let size = this.bytes & 0x3f; - let pos = 0; - - this.bytes += len; - - if (size > 0) { - let want = 64 - size; - - if (want > len) - want = len; - - for (let i = 0; i < want; i++) - this.block[size + i] = data[i]; - - size += want; - len -= want; - pos += want; - - if (size < 64) - return; - - this.transform(this.block, 0); - } - - while (len >= 64) { - this.transform(data, pos); - pos += 64; - len -= 64; - } - - for (let i = 0; i < len; i++) - this.block[i] = data[pos + i]; -}; - -/** - * Finalize SHA256 context. - * @private - * @param {Buffer} out - * @returns {Buffer} - */ - -SHA256.prototype._finish = function _finish(out) { - writeU32(DESC, this.bytes >>> 29, 0); - writeU32(DESC, this.bytes << 3, 4); - - this._update(PADDING, 1 + ((119 - (this.bytes % 64)) % 64)); - this._update(DESC, 8); - - for (let i = 0; i < 8; i++) { - writeU32(out, this.s[i], i * 4); - this.s[i] = 0; - } - - return out; -}; - -/** - * Transform SHA256 block. - * @param {Buffer} chunk - * @param {Number} pos - */ - -SHA256.prototype.transform = function transform(chunk, pos) { - const w = this.w; - let a = this.s[0]; - let b = this.s[1]; - let c = this.s[2]; - let d = this.s[3]; - let e = this.s[4]; - let f = this.s[5]; - let g = this.s[6]; - let h = this.s[7]; - let i = 0; - - for (; i < 16; i++) - w[i] = readU32(chunk, pos + i * 4); - - for (; i < 64; i++) - w[i] = sigma1(w[i - 2]) + w[i - 7] + sigma0(w[i - 15]) + w[i - 16]; - - for (i = 0; i < 64; i++) { - let t1 = h + Sigma1(e); - t1 += Ch(e, f, g); - t1 += K[i] + w[i]; - - let t2 = Sigma0(a); - t2 += Maj(a, b, c); - - h = g; - g = f; - f = e; - - e = d + t1; - - d = c; - c = b; - b = a; - - a = t1 + t2; - } - - this.s[0] += a; - this.s[1] += b; - this.s[2] += c; - this.s[3] += d; - this.s[4] += e; - this.s[5] += f; - this.s[6] += g; - this.s[7] += h; - - this.s[0] >>>= 0; - this.s[1] >>>= 0; - this.s[2] >>>= 0; - this.s[3] >>>= 0; - this.s[4] >>>= 0; - this.s[5] >>>= 0; - this.s[6] >>>= 0; - this.s[7] >>>= 0; -}; - -/** - * SHA256Hmac - * @alias module:crypto/sha256.SHA256Hmac - * @constructor - * @property {SHA256} inner - * @property {SHA256} outer - */ - -function SHA256Hmac() { - if (!(this instanceof SHA256Hmac)) - return new SHA256Hmac(); - - this.inner = new SHA256(); - this.outer = new SHA256(); -} - -/** - * Initialize HMAC context. - * @param {Buffer} data - */ - -SHA256Hmac.prototype.init = function init(data) { - const key = BUFFER64; - - if (data.length > 64) { - this.inner.init(); - this.inner.update(data); - this.inner._finish(key); - key.fill(0, 32, 64); - } else { - data.copy(key, 0); - key.fill(0, data.length, 64); - } - - for (let i = 0; i < key.length; i++) - key[i] ^= 0x36; - - this.inner.init(); - this.inner.update(key); - - for (let i = 0; i < key.length; i++) - key[i] ^= 0x6a; - - this.outer.init(); - this.outer.update(key); -}; - -/** - * Update HMAC context. - * @param {Buffer} data - */ - -SHA256Hmac.prototype.update = function update(data) { - this.inner.update(data); -}; - -/** - * Finalize HMAC context. - * @returns {Buffer} - */ - -SHA256Hmac.prototype.finish = function finish() { - this.outer.update(this.inner.finish()); - return this.outer.finish(); -}; - -/* - * Helpers - * @see https://github.com/bitcoin-core/secp256k1/blob/master/src/hash_impl.h - */ - -function Sigma0(x) { - return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10); -} - -function Sigma1(x) { - return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7); -} - -function sigma0(x) { - return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3); -} - -function sigma1(x) { - return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10); -} - -function Ch(x, y, z) { - return z ^ (x & (y ^ z)); -} - -function Maj(x, y, z) { - return (x & y) | (z & (x | y)); -} - -function writeU32(buf, value, offset) { - buf[offset] = value >>> 24; - buf[offset + 1] = (value >> 16) & 0xff; - buf[offset + 2] = (value >> 8) & 0xff; - buf[offset + 3] = value & 0xff; -} - -function readU32(buf, offset) { - return ((buf[offset] & 0xff) * 0x1000000) - + ((buf[offset + 1] & 0xff) << 16) - | ((buf[offset + 2] & 0xff) << 8) - | (buf[offset + 3] & 0xff); -} - -/* - * Context Helpers - */ - -const ctx = new SHA256(); -const mctx = new SHA256Hmac(); - -/** - * Hash buffer with sha256. - * @alias module:crypto/sha256.sha256 - * @param {Buffer} data - * @returns {Buffer} - */ - -function sha256(data) { - ctx.init(); - ctx.update(data); - return ctx.finish(); -} - -/** - * Hash buffer with double sha256. - * @alias module:crypto/sha256.hash256 - * @param {Buffer} data - * @returns {Buffer} - */ - -function hash256(data) { - const out = Buffer.allocUnsafe(32); - ctx.init(); - ctx.update(data); - ctx._finish(out); - ctx.init(); - ctx.update(out); - ctx._finish(out); - return out; -} - -/** - * Create a sha256 HMAC from buffer and key. - * @alias module:crypto/sha256.hmac - * @param {Buffer} data - * @param {Buffer} key - * @returns {Buffer} - */ - -function hmac(data, key) { - mctx.init(key); - mctx.update(data); - return mctx.finish(); -} - -/* - * Expose - */ - -exports = SHA256; -exports.SHA256 = SHA256; -exports.SHA256Hmac = SHA256Hmac; -exports.digest = sha256; -exports.hmac = hmac; -exports.hash256 = hash256; - -module.exports = exports; diff --git a/lib/crypto/siphash.js b/lib/crypto/siphash.js deleted file mode 100644 index 8f45f575..00000000 --- a/lib/crypto/siphash.js +++ /dev/null @@ -1,304 +0,0 @@ -/*! - * siphash.js - siphash for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - * - * Ported from: - * https://github.com/bitcoin/bitcoin/blob/master/src/hash.cpp - */ - -'use strict'; - -/** - * @module crypto/siphash - */ - -const native = require('../native').binding; - -/** - * Javascript siphash 2-4 implementation. - * @private - * @param {Buffer} data - * @param {Buffer} key - 128 bit key. - * @param {Number} shift - * @returns {Array} [hi, lo] - */ - -function _siphash(data, key, shift) { - const blocks = Math.floor(data.length / 8); - const c0 = U64(0x736f6d65, 0x70736575); - const c1 = U64(0x646f7261, 0x6e646f6d); - const c2 = U64(0x6c796765, 0x6e657261); - const c3 = U64(0x74656462, 0x79746573); - const f0 = U64(blocks << (shift - 32), 0); - const f1 = U64(0, 0xff); - const k0 = U64.fromRaw(key, 0); - const k1 = U64.fromRaw(key, 8); - - // Init - const v0 = c0.ixor(k0); - const v1 = c1.ixor(k1); - const v2 = c2.ixor(k0); - const v3 = c3.ixor(k1); - - // Blocks - let p = 0; - for (let i = 0; i < blocks; i++) { - const d = U64.fromRaw(data, p); - p += 8; - v3.ixor(d); - sipround(v0, v1, v2, v3); - sipround(v0, v1, v2, v3); - v0.ixor(d); - } - - switch (data.length & 7) { - case 7: - f0.hi |= data[p + 6] << 16; - case 6: - f0.hi |= data[p + 5] << 8; - case 5: - f0.hi |= data[p + 4]; - case 4: - f0.lo |= data[p + 3] << 24; - case 3: - f0.lo |= data[p + 2] << 16; - case 2: - f0.lo |= data[p + 1] << 8; - case 1: - f0.lo |= data[p]; - } - - // Finalization - v3.ixor(f0); - sipround(v0, v1, v2, v3); - sipround(v0, v1, v2, v3); - v0.ixor(f0); - v2.ixor(f1); - sipround(v0, v1, v2, v3); - sipround(v0, v1, v2, v3); - sipround(v0, v1, v2, v3); - sipround(v0, v1, v2, v3); - v0.ixor(v1); - v0.ixor(v2); - v0.ixor(v3); - - return [v0.hi, v0.lo]; -} - -/** - * Javascript siphash 2-4 implementation (64 bit ints). - * @private - * @param {Number} hi - * @param {Number} lo - * @param {Buffer} key - 128 bit key. - * @returns {Array} [hi, lo] - */ - -function _siphash64(hi, lo, key) { - const c0 = U64(0x736f6d65, 0x70736575); - const c1 = U64(0x646f7261, 0x6e646f6d); - const c2 = U64(0x6c796765, 0x6e657261); - const c3 = U64(0x74656462, 0x79746573); - const f0 = U64(hi, lo); - const f1 = U64(0, 0xff); - const k0 = U64.fromRaw(key, 0); - const k1 = U64.fromRaw(key, 8); - - // Init - const v0 = c0.ixor(k0); - const v1 = c1.ixor(k1); - const v2 = c2.ixor(k0); - const v3 = c3.ixor(k1); - - // Finalization - v3.ixor(f0); - sipround(v0, v1, v2, v3); - sipround(v0, v1, v2, v3); - v0.ixor(f0); - v2.ixor(f1); - sipround(v0, v1, v2, v3); - sipround(v0, v1, v2, v3); - sipround(v0, v1, v2, v3); - sipround(v0, v1, v2, v3); - v0.ixor(v1); - v0.ixor(v2); - v0.ixor(v3); - - return [v0.hi, v0.lo]; -} - -/** - * Javascript siphash 2-4 implementation (shift=56). - * @alias module:crypto/siphash.siphash - * @param {Buffer} data - * @param {Buffer} key - 128 bit key. - * @returns {Array} [hi, lo] - */ - -function siphash(data, key) { - return _siphash(data, key, 56); -} - -/** - * Javascript siphash 2-4 implementation (shift=59). - * @alias module:crypto/siphash.siphash256 - * @param {Buffer} data - * @param {Buffer} key - 128 bit key. - * @returns {Array} [hi, lo] - */ - -function siphash256(data, key) { - return _siphash(data, key, 59); -} - -/** - * Javascript siphash 2-4 implementation (32 bit ints). - * @alias module:crypto/siphash.siphash32 - * @param {Number} num - * @param {Buffer} key - 128 bit key. - * @returns {Number} - */ - -function siphash32(num, key) { - return _siphash64(0, num, key)[1]; -} - -/** - * Javascript siphash 2-4 implementation (64 bit ints). - * @alias module:crypto/siphash.siphash64 - * @param {Number} hi - * @param {Number} lo - * @param {Buffer} key - 128 bit key. - * @returns {Array} [hi, lo] - */ - -function siphash64(hi, lo, key) { - return _siphash64(hi, lo, key); -} - -if (native) { - siphash = native.siphash; - siphash256 = native.siphash256; - siphash32 = native.siphash32; - siphash64 = native.siphash64; -} - -/* - * U64 - * @constructor - * @ignore - */ - -function U64(hi, lo) { - if (!(this instanceof U64)) - return new U64(hi, lo); - - this.hi = hi | 0; - this.lo = lo | 0; -} - -U64.prototype.iadd = function iadd(b) { - const a = this; - - // Credit to @indutny for this method. - const lo = (a.lo + b.lo) | 0; - - const s = lo >> 31; - const as = a.lo >> 31; - const bs = b.lo >> 31; - - const c = ((as & bs) | (~s & (as ^ bs))) & 1; - - const hi = ((a.hi + b.hi) | 0) + c; - - a.hi = hi | 0; - a.lo = lo; - - return a; -}; - -U64.prototype.ixor = function ixor(b) { - this.hi ^= b.hi; - this.lo ^= b.lo; - return this; -}; - -U64.prototype.irotl = function irotl(bits) { - let ahi = this.hi; - let alo = this.lo; - let bhi = this.hi; - let blo = this.lo; - - // a = x << b - if (bits < 32) { - ahi <<= bits; - ahi |= alo >>> (32 - bits); - alo <<= bits; - } else { - ahi = alo << (bits - 32); - alo = 0; - } - - bits = 64 - bits; - - // b = x >> (64 - b) - if (bits < 32) { - blo >>>= bits; - blo |= bhi << (32 - bits); - bhi >>>= bits; - } else { - blo = bhi >>> (bits - 32); - bhi = 0; - } - - // a | b - this.hi = ahi | bhi; - this.lo = alo | blo; - - return this; -}; - -U64.fromRaw = function fromRaw(data, off) { - const lo = data.readUInt32LE(off, true); - const hi = data.readUInt32LE(off + 4, true); - return new U64(hi, lo); -}; - -/* - * Helpers - */ - -function sipround(v0, v1, v2, v3) { - v0.iadd(v1); - v1.irotl(13); - v1.ixor(v0); - - v0.irotl(32); - - v2.iadd(v3); - v3.irotl(16); - v3.ixor(v2); - - v0.iadd(v3); - v3.irotl(21); - v3.ixor(v0); - - v2.iadd(v1); - v1.irotl(17); - v1.ixor(v2); - - v2.irotl(32); -} - -/* - * Expose - */ - -exports = siphash; -exports.siphash = siphash; -exports.siphash256 = siphash256; -exports.siphash32 = siphash32; -exports.siphash64 = siphash64; - -module.exports = exports; diff --git a/lib/hd/mnemonic.js b/lib/hd/mnemonic.js index 49101e91..ba8e6858 100644 --- a/lib/hd/mnemonic.js +++ b/lib/hd/mnemonic.js @@ -8,10 +8,11 @@ const assert = require('assert'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); -const cleanse = require('../crypto/cleanse'); -const random = require('../crypto/random'); -const pbkdf2 = require('../crypto/pbkdf2'); +const digest = require('bcrypto/lib/digest'); +const cleanse = require('bcrypto/lib/cleanse'); +const random = require('bcrypto/lib/random'); +const pbkdf2 = require('bcrypto/lib/pbkdf2'); +const sha512 = require('bcrypto/lib/sha512'); const StaticWriter = require('../utils/staticwriter'); const BufferReader = require('../utils/reader'); const encoding = require('../utils/encoding'); @@ -154,10 +155,10 @@ Mnemonic.prototype.toSeed = function toSeed(passphrase) { const phrase = nfkd(this.getPhrase()); const passwd = nfkd('mnemonic' + passphrase); - return pbkdf2.derive( + return pbkdf2.derive(sha512, Buffer.from(phrase, 'utf8'), Buffer.from(passwd, 'utf8'), - 2048, 64, 'sha512'); + 2048, 64); }; /** diff --git a/lib/hd/private.js b/lib/hd/private.js index 662bd01d..d80591f0 100644 --- a/lib/hd/private.js +++ b/lib/hd/private.js @@ -8,10 +8,10 @@ const assert = require('assert'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); -const cleanse = require('../crypto/cleanse'); -const random = require('../crypto/random'); -const secp256k1 = require('../crypto/secp256k1'); +const digest = require('bcrypto/lib/digest'); +const cleanse = require('bcrypto/lib/cleanse'); +const random = require('bcrypto/lib/random'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const Network = require('../protocol/network'); const StaticWriter = require('../utils/staticwriter'); const BufferReader = require('../utils/reader'); diff --git a/lib/hd/public.js b/lib/hd/public.js index e2104294..f0b1fc54 100644 --- a/lib/hd/public.js +++ b/lib/hd/public.js @@ -8,9 +8,9 @@ const assert = require('assert'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); -const cleanse = require('../crypto/cleanse'); -const secp256k1 = require('../crypto/secp256k1'); +const digest = require('bcrypto/lib/digest'); +const cleanse = require('bcrypto/lib/cleanse'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const Network = require('../protocol/network'); const StaticWriter = require('../utils/staticwriter'); const BufferReader = require('../utils/reader'); diff --git a/lib/http/rpc.js b/lib/http/rpc.js index 2dc572b6..77afc4cc 100644 --- a/lib/http/rpc.js +++ b/lib/http/rpc.js @@ -10,10 +10,10 @@ const assert = require('assert'); const bweb = require('bweb'); const util = require('../utils/util'); const co = require('../utils/co'); -const digest = require('../crypto/digest'); -const ccmp = require('../crypto/ccmp'); +const digest = require('bcrypto/lib/digest'); +const ccmp = require('bcrypto/lib/ccmp'); const common = require('../blockchain/common'); -const secp256k1 = require('../crypto/secp256k1'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const Amount = require('../btc/amount'); const NetAddress = require('../primitives/netaddress'); const Script = require('../script/script'); diff --git a/lib/http/server.js b/lib/http/server.js index 5ab20361..214d1024 100644 --- a/lib/http/server.js +++ b/lib/http/server.js @@ -15,9 +15,9 @@ const base58 = require('../utils/base58'); const Bloom = require('../utils/bloom'); const TX = require('../primitives/tx'); const Outpoint = require('../primitives/outpoint'); -const digest = require('../crypto/digest'); -const random = require('../crypto/random'); -const ccmp = require('../crypto/ccmp'); +const digest = require('bcrypto/lib/digest'); +const random = require('bcrypto/lib/random'); +const ccmp = require('bcrypto/lib/ccmp'); const Network = require('../protocol/network'); const Validator = require('../utils/validator'); const pkg = require('../pkg'); diff --git a/lib/mempool/mempool.js b/lib/mempool/mempool.js index 04cb55cd..34b62667 100644 --- a/lib/mempool/mempool.js +++ b/lib/mempool/mempool.js @@ -13,7 +13,7 @@ const common = require('../blockchain/common'); const consensus = require('../protocol/consensus'); const policy = require('../protocol/policy'); const util = require('../utils/util'); -const random = require('../crypto/random'); +const random = require('bcrypto/lib/random'); const {VerifyError} = require('../protocol/errors'); const RollingFilter = require('../utils/rollingfilter'); const Address = require('../primitives/address'); diff --git a/lib/mining/common.js b/lib/mining/common.js index 3b43c7f6..9bb7c6d4 100644 --- a/lib/mining/common.js +++ b/lib/mining/common.js @@ -8,7 +8,7 @@ const assert = require('assert'); const consensus = require('../protocol/consensus'); -const BN = require('../crypto/bn'); +const BN = require('bcrypto/lib/bn'); /** * @exports mining/common diff --git a/lib/mining/mine.js b/lib/mining/mine.js index 464c1c3a..3def1d5f 100644 --- a/lib/mining/mine.js +++ b/lib/mining/mine.js @@ -7,7 +7,7 @@ 'use strict'; const assert = require('assert'); -const digest = require('../crypto/digest'); +const digest = require('bcrypto/lib/digest'); /** * Hash until the nonce overflows. diff --git a/lib/mining/template.js b/lib/mining/template.js index a1a3477b..e1f367c7 100644 --- a/lib/mining/template.js +++ b/lib/mining/template.js @@ -9,8 +9,8 @@ const assert = require('assert'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); -const merkle = require('../crypto/merkle'); +const hash256 = require('bcrypto/lib/hash256'); +const merkle = require('bcrypto/lib/merkle'); const StaticWriter = require('../utils/staticwriter'); const Address = require('../primitives/address'); const TX = require('../primitives/tx'); @@ -178,11 +178,11 @@ BlockTemplate.prototype.getWitnessHash = function getWitnessHash() { for (const item of this.items) leaves.push(item.tx.witnessHash()); - const [root, malleated] = merkle.createRoot(leaves); + const [root, malleated] = merkle.createRoot(hash256, leaves); assert(!malleated); - return digest.root256(root, nonce); + return hash256.root(root, nonce); }; /** @@ -381,7 +381,7 @@ BlockTemplate.prototype.getRawCoinbase = function getRawCoinbase(nonce1, nonce2) BlockTemplate.prototype.getRoot = function getRoot(nonce1, nonce2) { const raw = this.getRawCoinbase(nonce1, nonce2); - const hash = digest.hash256(raw); + const hash = hash256.digest(raw); return this.tree.withFirst(hash); }; @@ -418,7 +418,7 @@ BlockTemplate.prototype.getHeader = function getHeader(root, time, nonce) { BlockTemplate.prototype.getProof = function getProof(nonce1, nonce2, time, nonce) { const root = this.getRoot(nonce1, nonce2); const data = this.getHeader(root, time, nonce); - const hash = digest.hash256(data); + const hash = hash256.digest(data); return new BlockProof(hash, root, nonce1, nonce2, time, nonce); }; @@ -685,7 +685,7 @@ function MerkleTree() { MerkleTree.prototype.withFirst = function withFirst(hash) { for (const step of this.steps) - hash = digest.root256(hash, step); + hash = hash256.root(hash, step); return hash; }; @@ -742,7 +742,7 @@ MerkleTree.prototype.fromLeaves = function fromLeaves(leaves) { leaves.push(leaves[len - 1]); for (let i = 2; i < len; i += 2) { - const hash = digest.root256(leaves[i], leaves[i + 1]); + const hash = hash256.root(leaves[i], leaves[i + 1]); hashes.push(hash); } diff --git a/lib/net/bip150.js b/lib/net/bip150.js index 62d807ef..4a10036b 100644 --- a/lib/net/bip150.js +++ b/lib/net/bip150.js @@ -12,11 +12,11 @@ const assert = require('assert'); const path = require('path'); const EventEmitter = require('events'); const co = require('../utils/co'); -const digest = require('../crypto/digest'); -const random = require('../crypto/random'); -const ccmp = require('../crypto/ccmp'); +const digest = require('bcrypto/lib/digest'); +const random = require('bcrypto/lib/random'); +const ccmp = require('bcrypto/lib/ccmp'); const packets = require('./packets'); -const secp256k1 = require('../crypto/secp256k1'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const StaticWriter = require('../utils/staticwriter'); const base58 = require('../utils/base58'); const encoding = require('../utils/encoding'); diff --git a/lib/net/bip151.js b/lib/net/bip151.js index d6a91ec2..13d85c44 100644 --- a/lib/net/bip151.js +++ b/lib/net/bip151.js @@ -16,12 +16,13 @@ const assert = require('assert'); const EventEmitter = require('events'); const util = require('../utils/util'); const co = require('../utils/co'); -const digest = require('../crypto/digest'); -const ChaCha20 = require('../crypto/chacha20'); -const Poly1305 = require('../crypto/poly1305'); -const AEAD = require('../crypto/aead'); -const hkdf = require('../crypto/hkdf'); -const secp256k1 = require('../crypto/secp256k1'); +const hash256 = require('bcrypto/lib/hash256'); +const sha256 = require('bcrypto/lib/sha256'); +const ChaCha20 = require('bcrypto/lib/chacha20'); +const Poly1305 = require('bcrypto/lib/poly1305'); +const AEAD = require('bcrypto/lib/aead'); +const hkdf = require('bcrypto/lib/hkdf'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const packets = require('./packets'); const StaticWriter = require('../utils/staticwriter'); const BufferReader = require('../utils/reader'); @@ -104,11 +105,11 @@ BIP151Stream.prototype.init = function init(publicKey) { bw.writeU8(this.cipher); const data = bw.render(); - const prk = hkdf.extract(data, HKDF_SALT, 'sha256'); + const prk = hkdf.extract(sha256, data, HKDF_SALT); - this.k1 = hkdf.expand(prk, INFO_KEY1, 32, 'sha256'); - this.k2 = hkdf.expand(prk, INFO_KEY2, 32, 'sha256'); - this.sid = hkdf.expand(prk, INFO_SID, 32, 'sha256'); + this.k1 = hkdf.expand(sha256, prk, INFO_KEY1, 32); + this.k2 = hkdf.expand(sha256, prk, INFO_KEY2, 32); + this.sid = hkdf.expand(sha256, prk, INFO_SID, 32); this.seq = 0; @@ -151,8 +152,8 @@ BIP151Stream.prototype.rekey = function rekey(k1, k2) { assert(this.sid, 'Cannot rekey before initialization.'); if (!k1) { - this.k1 = digest.root256(this.sid, this.k1); - this.k2 = digest.root256(this.sid, this.k2); + this.k1 = hash256.root(this.sid, this.k1); + this.k2 = hash256.root(this.sid, this.k2); } else { this.k1 = k1; this.k2 = k2; @@ -263,8 +264,8 @@ BIP151Stream.prototype.auth = function auth(data) { * @returns {Buffer} */ -BIP151Stream.prototype.finish = function finish() { - this.tag = this.aead.finish(); +BIP151Stream.prototype.final = function final() { + this.tag = this.aead.final(); return this.tag; }; @@ -608,7 +609,7 @@ BIP151.prototype.packet = function packet(cmd, body) { this.output.encryptSize(msg); this.output.encrypt(payload); - this.output.finish().copy(msg, 4 + payloadSize); + this.output.final().copy(msg, 4 + payloadSize); this.output.sequence(); return msg; @@ -719,7 +720,7 @@ BIP151.prototype.parse = function parse(data) { // This ensures the cipher state isn't altered // if the payload integrity has been compromised. this.input.auth(payload); - this.input.finish(); + this.input.final(); if (!this.input.verify(tag)) { this.input.sequence(); diff --git a/lib/net/bip152.js b/lib/net/bip152.js index 1a33af0d..c3c0b0bd 100644 --- a/lib/net/bip152.js +++ b/lib/net/bip152.js @@ -16,8 +16,8 @@ const BufferReader = require('../utils/reader'); const StaticWriter = require('../utils/staticwriter'); const encoding = require('../utils/encoding'); const consensus = require('../protocol/consensus'); -const digest = require('../crypto/digest'); -const siphash256 = require('../crypto/siphash').siphash256; +const digest = require('bcrypto/lib/digest'); +const siphash256 = require('bcrypto/lib/siphash').siphash256; const AbstractBlock = require('../primitives/abstractblock'); const TX = require('../primitives/tx'); const Headers = require('../primitives/headers'); diff --git a/lib/net/framer.js b/lib/net/framer.js index 7a568f72..b90b3944 100644 --- a/lib/net/framer.js +++ b/lib/net/framer.js @@ -9,7 +9,7 @@ const assert = require('assert'); const Network = require('../protocol/network'); -const digest = require('../crypto/digest'); +const digest = require('bcrypto/lib/digest'); /** * Protocol packet framer diff --git a/lib/net/parser.js b/lib/net/parser.js index 94d1ff2f..42cdb640 100644 --- a/lib/net/parser.js +++ b/lib/net/parser.js @@ -13,7 +13,7 @@ const assert = require('assert'); const EventEmitter = require('events'); const Network = require('../protocol/network'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); +const digest = require('bcrypto/lib/digest'); const common = require('./common'); const packets = require('./packets'); diff --git a/lib/net/pool.js b/lib/net/pool.js index 7732f506..8dd5edae 100644 --- a/lib/net/pool.js +++ b/lib/net/pool.js @@ -21,7 +21,7 @@ const BIP151 = require('./bip151'); const BIP152 = require('./bip152'); const Bloom = require('../utils/bloom'); const RollingFilter = require('../utils/rollingfilter'); -const secp256k1 = require('../crypto/secp256k1'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const Lock = require('../utils/lock'); const Network = require('../protocol/network'); const Peer = require('./peer'); diff --git a/lib/net/proxysocket.js b/lib/net/proxysocket.js index 7b3a2f2e..927229fa 100644 --- a/lib/net/proxysocket.js +++ b/lib/net/proxysocket.js @@ -10,7 +10,7 @@ const assert = require('assert'); const EventEmitter = require('events'); const bsock = require('bsock'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); +const digest = require('bcrypto/lib/digest'); const BufferWriter = require('../utils/writer'); function ProxySocket(uri) { diff --git a/lib/node/node.js b/lib/node/node.js index 4615be3e..dc3d7a79 100644 --- a/lib/node/node.js +++ b/lib/node/node.js @@ -13,7 +13,7 @@ const util = require('../utils/util'); const Network = require('../protocol/network'); const Logger = require('./logger'); const WorkerPool = require('../workers/workerpool'); -const secp256k1 = require('../crypto/secp256k1'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const native = require('../native'); const Config = require('./config'); diff --git a/lib/primitives/abstractblock.js b/lib/primitives/abstractblock.js index 298c90be..9668ddc9 100644 --- a/lib/primitives/abstractblock.js +++ b/lib/primitives/abstractblock.js @@ -9,7 +9,7 @@ const assert = require('assert'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); +const digest = require('bcrypto/lib/digest'); const BufferReader = require('../utils/reader'); const StaticWriter = require('../utils/staticwriter'); const InvItem = require('./invitem'); diff --git a/lib/primitives/address.js b/lib/primitives/address.js index f4637802..104e9745 100644 --- a/lib/primitives/address.js +++ b/lib/primitives/address.js @@ -11,7 +11,7 @@ const assert = require('assert'); const Network = require('../protocol/network'); const encoding = require('../utils/encoding'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); +const digest = require('bcrypto/lib/digest'); const BufferReader = require('../utils/reader'); const StaticWriter = require('../utils/staticwriter'); const base58 = require('../utils/base58'); diff --git a/lib/primitives/block.js b/lib/primitives/block.js index 2853f6e3..e225c0da 100644 --- a/lib/primitives/block.js +++ b/lib/primitives/block.js @@ -10,8 +10,8 @@ const assert = require('assert'); const util = require('../utils/util'); const encoding = require('../utils/encoding'); -const digest = require('../crypto/digest'); -const merkle = require('../crypto/merkle'); +const hash256 = require('bcrypto/lib/hash256'); +const merkle = require('bcrypto/lib/merkle'); const consensus = require('../protocol/consensus'); const AbstractBlock = require('./abstractblock'); const BufferReader = require('../utils/reader'); @@ -280,7 +280,7 @@ Block.prototype.createMerkleRoot = function createMerkleRoot(enc) { for (const tx of this.txs) leaves.push(tx.hash()); - const [root, malleated] = merkle.createRoot(leaves); + const [root, malleated] = merkle.createRoot(hash256, leaves); if (malleated) return null; @@ -317,12 +317,12 @@ Block.prototype.createCommitmentHash = function createCommitmentHash(enc) { leaves.push(tx.witnessHash()); } - const [root] = merkle.createRoot(leaves); + const [root] = merkle.createRoot(hash256, leaves); // Note: malleation check ignored here. // assert(!malleated); - const hash = digest.root256(root, nonce); + const hash = hash256.root(root, nonce); return enc === 'hex' ? hash.toString('hex') diff --git a/lib/primitives/keyring.js b/lib/primitives/keyring.js index e74897ca..a8039653 100644 --- a/lib/primitives/keyring.js +++ b/lib/primitives/keyring.js @@ -9,7 +9,7 @@ const assert = require('assert'); const encoding = require('../utils/encoding'); -const digest = require('../crypto/digest'); +const digest = require('bcrypto/lib/digest'); const Network = require('../protocol/network'); const BufferReader = require('../utils/reader'); const StaticWriter = require('../utils/staticwriter'); @@ -17,7 +17,7 @@ const base58 = require('../utils/base58'); const Script = require('../script/script'); const Address = require('./address'); const Output = require('./output'); -const secp256k1 = require('../crypto/secp256k1'); +const secp256k1 = require('bcrypto/lib/secp256k1'); /** * Represents a key ring which amounts to an address. diff --git a/lib/primitives/merkleblock.js b/lib/primitives/merkleblock.js index 73731349..8e4d7175 100644 --- a/lib/primitives/merkleblock.js +++ b/lib/primitives/merkleblock.js @@ -12,7 +12,7 @@ const util = require('../utils/util'); const BufferReader = require('../utils/reader'); const StaticWriter = require('../utils/staticwriter'); const encoding = require('../utils/encoding'); -const digest = require('../crypto/digest'); +const hash256 = require('bcrypto/lib/hash256'); const consensus = require('../protocol/consensus'); const AbstractBlock = require('./abstractblock'); const Headers = require('./headers'); @@ -238,7 +238,7 @@ MerkleBlock.prototype.extractTree = function extractTree() { right = left; } - return digest.root256(left, right); + return hash256.root(left, right); }; if (totalTX === 0) @@ -571,7 +571,7 @@ MerkleBlock.fromMatches = function fromMatches(block, matches) { else right = left; - return digest.root256(left, right); + return hash256.root(left, right); }; const traverse = (height, pos, leaves, matches) => { diff --git a/lib/primitives/tx.js b/lib/primitives/tx.js index 46c2acae..8732cbe3 100644 --- a/lib/primitives/tx.js +++ b/lib/primitives/tx.js @@ -10,8 +10,8 @@ const assert = require('assert'); const util = require('../utils/util'); const encoding = require('../utils/encoding'); -const digest = require('../crypto/digest'); -const secp256k1 = require('../crypto/secp256k1'); +const digest = require('bcrypto/lib/digest'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const Amount = require('../btc/amount'); const Network = require('../protocol/network'); const Script = require('../script/script'); diff --git a/lib/protocol/consensus.js b/lib/protocol/consensus.js index 74e5132a..8a3d8608 100644 --- a/lib/protocol/consensus.js +++ b/lib/protocol/consensus.js @@ -12,7 +12,7 @@ */ const assert = require('assert'); -const BN = require('../crypto/bn'); +const BN = require('bcrypto/lib/bn'); /** * One bitcoin in satoshis. diff --git a/lib/protocol/networks.js b/lib/protocol/networks.js index e035baf2..8031338a 100644 --- a/lib/protocol/networks.js +++ b/lib/protocol/networks.js @@ -11,7 +11,7 @@ * @module protocol/networks */ -const BN = require('../crypto/bn'); +const BN = require('bcrypto/lib/bn'); const network = exports; diff --git a/lib/script/common.js b/lib/script/common.js index 4313a329..45fa39ab 100644 --- a/lib/script/common.js +++ b/lib/script/common.js @@ -13,7 +13,7 @@ const assert = require('assert'); const util = require('../utils/util'); -const secp256k1 = require('../crypto/secp256k1'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const ScriptNum = require('./scriptnum'); /** diff --git a/lib/script/script.js b/lib/script/script.js index 751ea81e..6f64ddba 100644 --- a/lib/script/script.js +++ b/lib/script/script.js @@ -11,8 +11,8 @@ const assert = require('assert'); const consensus = require('../protocol/consensus'); const policy = require('../protocol/policy'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); -const merkle = require('../crypto/merkle'); +const digest = require('bcrypto/lib/digest'); +const merkle = require('bcrypto/lib/merkle'); const BufferWriter = require('../utils/writer'); const BufferReader = require('../utils/reader'); const StaticWriter = require('../utils/staticwriter'); @@ -23,7 +23,7 @@ const ScriptError = require('./scripterror'); const ScriptNum = require('./scriptnum'); const common = require('./common'); const encoding = require('../utils/encoding'); -const secp256k1 = require('../crypto/secp256k1'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const Address = require('../primitives/address'); const opcodes = common.opcodes; const scriptTypes = common.types; diff --git a/lib/script/sigcache.js b/lib/script/sigcache.js index 378613bd..c44c2f32 100644 --- a/lib/script/sigcache.js +++ b/lib/script/sigcache.js @@ -8,7 +8,7 @@ const assert = require('assert'); const util = require('../utils/util'); -const secp256k1 = require('../crypto/secp256k1'); +const secp256k1 = require('bcrypto/lib/secp256k1'); /** * Signature cache. diff --git a/lib/utils/asn1.js b/lib/utils/asn1.js deleted file mode 100644 index 8dae485b..00000000 --- a/lib/utils/asn1.js +++ /dev/null @@ -1,548 +0,0 @@ -/*! - * asn1.js - asn1 parsing for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - * - * Parts of this software are based on asn1.js. - * https://github.com/indutny/asn1.js - * - * Copyright Fedor Indutny, 2013. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -'use strict'; - -const BufferReader = require('./reader'); - -/** - * @exports utils/asn1 - */ - -const ASN1 = exports; - -/** - * Read next tag. - * @param {BufferReader} br - * @returns {Object} - */ - -ASN1.readTag = function readTag(br) { - let type = br.readU8(); - const primitive = (type & 0x20) === 0; - - if ((type & 0x1f) === 0x1f) { - let oct = type; - type = 0; - while ((oct & 0x80) === 0x80) { - oct = br.readU8(); - type <<= 7; - type |= oct & 0x7f; - } - } else { - type &= 0x1f; - } - - return { - type: type, - primitive: primitive, - size: ASN1.readSize(br, primitive) - }; -}; - -/** - * Read tag size. - * @param {BufferReader} br - * @param {Boolean} primitive - * @returns {Number} - * @throws on indefinite size - */ - -ASN1.readSize = function readSize(br, primitive) { - let size = br.readU8(); - - // Indefinite form - if (!primitive && size === 0x80) - throw new Error('Indefinite size.'); - - // Definite form - if ((size & 0x80) === 0) { - // Short form - return size; - } - - // Long form - const bytes = size & 0x7f; - - if (bytes > 3) - throw new Error('Length octet is too long.'); - - size = 0; - for (let i = 0; i < bytes; i++) { - size <<= 8; - size |= br.readU8(); - } - - return size; -}; - -/** - * Read implicit SEQ. - * @param {BufferReader} br - * @returns {Buffer} - */ - -ASN1.readSeq = function readSeq(br) { - const tag = ASN1.implicit(br, 0x10); - return br.readBytes(tag.size); -}; - -/** - * Read next tag and assert implicit. - * @param {BufferReader} br - * @param {Number} type - * @returns {Object} - * @throws on unexpected tag - */ - -ASN1.implicit = function implicit(br, type) { - const tag = ASN1.readTag(br); - - if (tag.type !== type) - throw new Error(`Unexpected tag: ${tag.type}.`); - - return tag; -}; - -/** - * Read implicit tag. - * @param {BufferReader} br - * @param {Number} type - * @returns {Boolean} - */ - -ASN1.explicit = function explicit(br, type) { - const offset = br.offset; - const tag = ASN1.readTag(br); - - if (tag.type !== type) { - br.offset = offset; - return false; - } - - return true; -}; - -/** - * Read next implicit SEQ and return a new reader. - * @param {BufferReader} br - * @returns {BufferReader} - */ - -ASN1.seq = function seq(br) { - return new BufferReader(ASN1.readSeq(br), true); -}; - -/** - * Read implicit int. - * @param {BufferReader} br - * @param {Boolean?} cast - * @returns {Buffer|Number} - */ - -ASN1.readInt = function readInt(br, cast) { - const tag = ASN1.implicit(br, 0x02); - const num = br.readBytes(tag.size); - - if (cast) - return num.readUIntBE(0, num.length); - - return num; -}; - -/** - * Read explicit int. - * @param {BufferReader} br - * @param {Number} type - * @param {Boolean?} readNum - * @returns {Buffer|Number} `-1` on not present. - */ - -ASN1.readExplicitInt = function readExplicitInt(br, type, readNum) { - if (!ASN1.explicit(br, type)) - return -1; - - return ASN1.readInt(br, readNum); -}; - -/** - * Read and align an implicit bitstr. - * @param {BufferReader} br - * @returns {Buffer} - */ - -ASN1.readBitstr = function readBitstr(br) { - const tag = ASN1.implicit(br, 0x03); - const str = br.readBytes(tag.size); - return ASN1.alignBitstr(str); -}; - -/** - * Read an implicit string (any type). - * @param {BufferReader} br - * @returns {String} - */ - -ASN1.readString = function readString(br) { - const tag = ASN1.readTag(br); - - switch (tag.type) { - case 0x03: { // bitstr - const str = br.readBytes(tag.size); - return ASN1.alignBitstr(str).toString('utf8'); - } - // Note: - // Fuck all these. - case 0x04: // octstr - case 0x12: // numstr - case 0x13: // prinstr - case 0x14: // t61str - case 0x15: // videostr - case 0x16: // ia5str - case 0x19: // graphstr - case 0x0c: // utf8str - case 0x1a: // iso646str - case 0x1b: // genstr - case 0x1c: // unistr - case 0x1d: // charstr - case 0x1e: { // bmpstr - return br.readString('utf8', tag.size); - } - default: { - throw new Error(`Unexpected tag: ${tag.type}.`); - } - } -}; - -/** - * Align a bitstr. - * @param {Buffer} data - * @returns {Buffer} - */ - -ASN1.alignBitstr = function alignBitstr(data) { - const padding = data[0]; - const bits = (data.length - 1) * 8 - padding; - const buf = data.slice(1); - const shift = 8 - (bits % 8); - - if (shift === 8 || buf.length === 0) - return buf; - - const out = Buffer.allocUnsafe(buf.length); - out[0] = buf[0] >>> shift; - - for (let i = 1; i < buf.length; i++) { - out[i] = buf[i - 1] << (8 - shift); - out[i] |= buf[i] >>> shift; - } - - return out; -}; - -/** - * Read an entire certificate. - * @param {BufferReader} br - * @returns {Object} - */ - -ASN1.readCert = function readCert(br) { - const buf = br; - - buf.start(); - - br = ASN1.seq(buf); - - return { - tbs: ASN1.readTBS(br), - sigAlg: ASN1.readAlgIdent(br), - sig: ASN1.readBitstr(br), - raw: buf.endData(true) - }; -}; - -/** - * Read only the TBS certificate. - * @param {BufferReader} br - * @returns {Object} - */ - -ASN1.readTBS = function readTBS(br) { - const buf = br; - - buf.start(); - - br = ASN1.seq(buf); - - return { - version: ASN1.readExplicitInt(br, 0x00, true), - serial: ASN1.readInt(br), - sig: ASN1.readAlgIdent(br), - issuer: ASN1.readName(br), - validity: ASN1.readValidity(br), - subject: ASN1.readName(br), - pubkey: ASN1.readPubkey(br), - raw: buf.endData(true) - }; -}; - -/** - * Read an implicit pubkey. - * @param {BufferReader} br - * @returns {Object} - */ - -ASN1.readPubkey = function readPubkey(br) { - br = ASN1.seq(br); - return { - alg: ASN1.readAlgIdent(br), - pubkey: ASN1.readBitstr(br) - }; -}; - -/** - * Read implicit name. - * @param {BufferReader} br - * @returns {Object[]} - */ - -ASN1.readName = function readName(br) { - const values = []; - - br = ASN1.seq(br); - - while (br.left()) { - ASN1.implicit(br, 0x11); // set - ASN1.implicit(br, 0x10); // seq - values.push({ - type: ASN1.readOID(br), - value: ASN1.readString(br) - }); - } - - return values; -}; - -/** - * Read implicit validity timerange. - * @param {BufferReader} br - * @returns {Object} - */ - -ASN1.readValidity = function readValidity(br) { - br = ASN1.seq(br); - return { - notBefore: ASN1.readTime(br), - notAfter: ASN1.readTime(br) - }; -}; - -/** - * Read implicit timestamp. - * @param {BufferReader} br - * @returns {Number} - */ - -ASN1.readTime = function readTime(br) { - const tag = ASN1.readTag(br); - const str = br.readString('ascii', tag.size); - let year, mon, day, hour, min, sec; - - switch (tag.type) { - case 0x17: // utctime - year = str.slice(0, 2) | 0; - mon = str.slice(2, 4) | 0; - day = str.slice(4, 6) | 0; - hour = str.slice(6, 8) | 0; - min = str.slice(8, 10) | 0; - sec = str.slice(10, 12) | 0; - if (year < 70) - year = 2000 + year; - else - year = 1900 + year; - break; - case 0x18: // gentime - year = str.slice(0, 4) | 0; - mon = str.slice(4, 6) | 0; - day = str.slice(6, 8) | 0; - hour = str.slice(8, 10) | 0; - min = str.slice(10, 12) | 0; - sec = str.slice(12, 14) | 0; - break; - default: - throw new Error(`Unexpected tag: ${tag.type}.`); - } - - return Date.UTC(year, mon - 1, day, hour, min, sec, 0) / 1000; -}; - -/** - * Read and format OID to string. - * @param {BufferReader} br - * @returns {String} - */ - -ASN1.readOID = function readOID(br) { - const tag = ASN1.implicit(br, 0x06); - const data = br.readBytes(tag.size); - return ASN1.formatOID(data); -}; - -/** - * Format an OID buffer to a string. - * @param {Buffer} data - * @returns {String} - */ - -ASN1.formatOID = function formatOID(data) { - const br = new BufferReader(data); - const ids = []; - let ident = 0; - let subident = 0; - - while (br.left()) { - subident = br.readU8(); - ident <<= 7; - ident |= subident & 0x7f; - if ((subident & 0x80) === 0) { - ids.push(ident); - ident = 0; - } - } - - if (subident & 0x80) - ids.push(ident); - - const first = (ids[0] / 40) | 0; - const second = ids[0] % 40; - const result = [first, second].concat(ids.slice(1)); - - return result.join('.'); -}; - -/** - * Read algorithm identifier. - * @param {BufferReader} br - * @returns {Object} - */ - -ASN1.readAlgIdent = function readAlgIdent(br) { - let params = null; - - br = ASN1.seq(br); - - const alg = ASN1.readOID(br); - - if (br.left() > 0) { - const tag = ASN1.readTag(br); - params = br.readBytes(tag.size); - if (params.length === 0) - params = null; - } - - return { - alg: alg, - params: params - }; -}; - -/** - * Read RSA public key. - * @param {BufferReader} br - * @returns {Object} - */ - -ASN1.readRSAPublic = function readRSAPublic(br) { - br = ASN1.seq(br); - return { - modulus: ASN1.readInt(br), - publicExponent: ASN1.readInt(br) - }; -}; - -/** - * Read RSA private key. - * @param {BufferReader} br - * @returns {Object} - */ - -ASN1.readRSAPrivate = function readRSAPrivate(br) { - br = ASN1.seq(br); - return { - version: ASN1.readInt(br, true), - modulus: ASN1.readInt(br), - publicExponent: ASN1.readInt(br), - privateExponent: ASN1.readInt(br), - prime1: ASN1.readInt(br), - prime2: ASN1.readInt(br), - exponent1: ASN1.readInt(br), - exponent2: ASN1.readInt(br), - coefficient: ASN1.readInt(br) - }; -}; - -/** - * Read RSA public key from buffer. - * @param {Buffer} data - * @returns {Object} - */ - -ASN1.parseRSAPublic = function parseRSAPublic(data) { - return ASN1.readRSAPublic(new BufferReader(data, true)); -}; - -/** - * Read RSA private key from buffer. - * @param {Buffer} data - * @returns {Object} - */ - -ASN1.parseRSAPrivate = function parseRSAPrivate(data) { - return ASN1.readRSAPrivate(new BufferReader(data, true)); -}; - -/** - * Read certificate from buffer. - * @param {Buffer} data - * @returns {Object} - */ - -ASN1.parseCert = function parseCert(data) { - return ASN1.readCert(new BufferReader(data, true)); -}; - -/** - * Read TBS certificate from buffer. - * @param {Buffer} data - * @returns {Object} - */ - -ASN1.parseTBS = function parseTBS(data) { - return ASN1.readTBS(new BufferReader(data, true)); -}; diff --git a/lib/utils/asyncemitter.js b/lib/utils/asyncemitter.js index 3f1c3278..a2c0cffd 100644 --- a/lib/utils/asyncemitter.js +++ b/lib/utils/asyncemitter.js @@ -345,13 +345,13 @@ AsyncEmitter.prototype.fire = async function fire(type) { AsyncEmitter.prototype.tryFire = async function tryFire(type) { try { - await this.emit.apply(this, arguments); + await this.fire.apply(this, arguments); } catch (e) { if (type === 'error') return; try { - await this.emit('error', e); + await this.fire('error', e); } catch (e) { ; } diff --git a/lib/utils/gcs.js b/lib/utils/gcs.js index 5ee29414..b1d19d84 100644 --- a/lib/utils/gcs.js +++ b/lib/utils/gcs.js @@ -8,8 +8,8 @@ const assert = require('assert'); const {U64} = require('./int64'); -const digest = require('../crypto/digest'); -const siphash = require('../crypto/siphash'); +const hash256 = require('bcrypto/lib/hash256'); +const siphash = require('bcrypto/lib/siphash'); const DUMMY = Buffer.alloc(0); const EOF = new U64(-1); @@ -27,12 +27,12 @@ function GCSFilter() { } GCSFilter.prototype.hash = function hash(enc) { - const h = digest.hash256(this.data); + const h = hash256.digest(this.data); return enc === 'hex' ? h.toString('hex') : h; }; GCSFilter.prototype.header = function header(prev) { - return digest.root256(this.hash(), prev); + return hash256.root(this.hash(), prev); }; GCSFilter.prototype.match = function match(key, data) { diff --git a/lib/utils/index.js b/lib/utils/index.js index bac0d298..b246bb5e 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -10,7 +10,6 @@ * @module utils */ -exports.ASN1 = require('./asn1'); // exports.AsyncEmitter = require('./asyncemitter'); exports.AsyncObject = require('./asyncobject'); exports.base32 = require('./base32'); @@ -31,7 +30,6 @@ exports.LRU = require('./lru'); exports.MappedLock = require('./mappedlock'); exports.murmur3 = require('./murmur3'); exports.nfkd = require('./nfkd'); -exports.PEM = require('./pem'); exports.ProtoWriter = require('./protowriter'); exports.ProtoReader = require('./protoreader'); exports.RBT = require('./rbt'); diff --git a/lib/utils/pem.js b/lib/utils/pem.js deleted file mode 100644 index 2d68372e..00000000 --- a/lib/utils/pem.js +++ /dev/null @@ -1,148 +0,0 @@ -/*! - * pem.js - pem parsing for bcoin - * Copyright (c) 2016-2017, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcoin - */ - -'use strict'; - -const assert = require('assert'); - -/** - * @exports utils/pem - */ - -const PEM = exports; - -/** - * Parse PEM into separated chunks. - * @param {String} pem - * @returns {Object[]} - * @throws on parse error - */ - -PEM.parse = function parse(pem) { - const chunks = []; - let chunk = ''; - let tag; - - while (pem.length) { - let m; - - m = /^-----BEGIN ([^\-]+)-----/.exec(pem); - if (m) { - pem = pem.substring(m[0].length); - tag = m[1]; - continue; - } - - m = /^-----END ([^\-]+)-----/.exec(pem); - if (m) { - pem = pem.substring(m[0].length); - - assert(tag === m[1], 'Tag mismatch.'); - - const type = tag.split(' ')[0].toLowerCase(); - const data = Buffer.from(chunk, 'base64'); - - chunks.push({ - tag: tag, - type: type, - data: data - }); - - chunk = ''; - tag = null; - - continue; - } - - m = /^[a-zA-Z0-9\+=\/]+/.exec(pem); - if (m) { - pem = pem.substring(m[0].length); - chunk += m[0]; - continue; - } - - m = /^\s+/.exec(pem); - if (m) { - pem = pem.substring(m[0].length); - continue; - } - - throw new Error('PEM parse error.'); - } - - assert(chunks.length !== 0, 'PEM parse error.'); - assert(!tag, 'Un-ended tag.'); - assert(chunk.length === 0, 'Trailing data.'); - - return chunks; -}; - -/** - * Decode PEM into a manageable format. - * @param {String} pem - * @returns {Object} - * @throws on parse error - */ - -PEM.decode = function decode(pem) { - const chunks = PEM.parse(pem); - const body = chunks[0]; - const extra = chunks[1]; - - let params = null; - - if (extra) { - if (extra.tag.indexOf('PARAMETERS') !== -1) - params = extra.data; - } - - let alg = null; - - switch (body.type) { - case 'dsa': - alg = 'dsa'; - break; - case 'rsa': - alg = 'rsa'; - break; - case 'ec': - alg = 'ecdsa'; - break; - } - - return { - type: body.type, - alg: alg, - data: body.data, - params: params - }; -}; - -/** - * Encode DER to PEM. - * @param {Buffer} der - * @param {String} type - e.g. "ec". - * @param {String?} suffix - e.g. "public key". - * @returns {String} - */ - -PEM.encode = function encode(der, type, suffix) { - let pem = ''; - - if (suffix) - type += ' ' + suffix; - - type = type.toUpperCase(); - der = der.toString('base64'); - - for (let i = 0; i < der.length; i += 64) - pem += der.slice(i, i + 64) + '\n'; - - return '' - + `-----BEGIN ${type}-----\n` - + pem - + `-----END ${type}-----\n`; -}; diff --git a/lib/wallet/client.js b/lib/wallet/client.js index 374d3eb3..6e92c3bc 100644 --- a/lib/wallet/client.js +++ b/lib/wallet/client.js @@ -9,7 +9,7 @@ const {NodeClient} = require('bclient'); const TX = require('../primitives/tx'); -const digest = require('../crypto/digest'); +const digest = require('bcrypto/lib/digest'); const util = require('../utils/util'); class WalletClient extends NodeClient { diff --git a/lib/wallet/http.js b/lib/wallet/http.js index d7ce6e31..b23ef630 100644 --- a/lib/wallet/http.js +++ b/lib/wallet/http.js @@ -15,9 +15,9 @@ const base58 = require('../utils/base58'); const MTX = require('../primitives/mtx'); const Outpoint = require('../primitives/outpoint'); const Script = require('../script/script'); -const digest = require('../crypto/digest'); -const random = require('../crypto/random'); -const ccmp = require('../crypto/ccmp'); +const digest = require('bcrypto/lib/digest'); +const random = require('bcrypto/lib/random'); +const ccmp = require('bcrypto/lib/ccmp'); const Network = require('../protocol/network'); const Validator = require('../utils/validator'); const Address = require('../primitives/address'); diff --git a/lib/wallet/masterkey.js b/lib/wallet/masterkey.js index 368a3762..942ea686 100644 --- a/lib/wallet/masterkey.js +++ b/lib/wallet/masterkey.js @@ -10,11 +10,12 @@ const assert = require('assert'); const Network = require('../protocol/network'); const util = require('../utils/util'); const Lock = require('../utils/lock'); -const random = require('../crypto/random'); -const cleanse = require('../crypto/cleanse'); -const aes = require('../crypto/aes'); -const pbkdf2 = require('../crypto/pbkdf2'); -const scrypt = require('../crypto/scrypt'); +const random = require('bcrypto/lib/random'); +const cleanse = require('bcrypto/lib/cleanse'); +const aes = require('bcrypto/lib/aes'); +const sha256 = require('bcrypto/lib/sha256'); +const pbkdf2 = require('bcrypto/lib/pbkdf2'); +const scrypt = require('bcrypto/lib/scrypt'); const BufferReader = require('../utils/reader'); const StaticWriter = require('../utils/staticwriter'); const encoding = require('../utils/encoding'); @@ -265,7 +266,7 @@ MasterKey.prototype.derive = async function derive(passwd) { switch (this.alg) { case MasterKey.alg.PBKDF2: - return await pbkdf2.deriveAsync(passwd, salt, N, 32, 'sha256'); + return await pbkdf2.deriveAsync(sha256, passwd, salt, N, 32); case MasterKey.alg.SCRYPT: return await scrypt.deriveAsync(passwd, salt, N, r, p, 32); default: diff --git a/lib/wallet/plugin.js b/lib/wallet/plugin.js index 95364884..9c96ec96 100644 --- a/lib/wallet/plugin.js +++ b/lib/wallet/plugin.js @@ -53,7 +53,8 @@ plugin.init = function init(node) { port: config.uint('wallet-port'), spv: node.spv, verify: node.spv, - listen: false + listen: true, + plugin: true }); wdb.http.attach('/wallet', node.http); diff --git a/lib/wallet/rpc.js b/lib/wallet/rpc.js index 4a80ec0e..b606ce59 100644 --- a/lib/wallet/rpc.js +++ b/lib/wallet/rpc.js @@ -10,7 +10,7 @@ const assert = require('assert'); const bweb = require('bweb'); const fs = require('../utils/fs'); const util = require('../utils/util'); -const digest = require('../crypto/digest'); +const digest = require('bcrypto/lib/digest'); const Amount = require('../btc/amount'); const Script = require('../script/script'); const Address = require('../primitives/address'); diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 4d62da3c..fe6df76d 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -13,8 +13,8 @@ const Network = require('../protocol/network'); const util = require('../utils/util'); const encoding = require('../utils/encoding'); const Lock = require('../utils/lock'); -const digest = require('../crypto/digest'); -const cleanse = require('../crypto/cleanse'); +const digest = require('bcrypto/lib/digest'); +const cleanse = require('bcrypto/lib/cleanse'); const BufferReader = require('../utils/reader'); const StaticWriter = require('../utils/staticwriter'); const base58 = require('../utils/base58'); diff --git a/lib/wallet/walletdb.js b/lib/wallet/walletdb.js index 1847b407..248ad472 100644 --- a/lib/wallet/walletdb.js +++ b/lib/wallet/walletdb.js @@ -14,8 +14,8 @@ const util = require('../utils/util'); const Lock = require('../utils/lock'); const MappedLock = require('../utils/mappedlock'); const encoding = require('../utils/encoding'); -const ccmp = require('../crypto/ccmp'); -const aes = require('../crypto/aes'); +const ccmp = require('bcrypto/lib/ccmp'); +const aes = require('bcrypto/lib/aes'); const Network = require('../protocol/network'); const Path = require('./path'); const common = require('./common'); @@ -130,7 +130,7 @@ WalletDB.prototype._init = function _init() { */ WalletDB.prototype._open = async function _open() { - if (this.options.listen) + if (!this.options.plugin) await this.logger.open(); await this.db.open(); @@ -160,7 +160,8 @@ WalletDB.prototype._open = async function _open() { this.primary = wallet; this.rpc.wallet = wallet; - await this.http.open(); + if (this.options.listen) + await this.http.open(); }; /** @@ -171,7 +172,9 @@ WalletDB.prototype._open = async function _open() { WalletDB.prototype._close = async function _close() { await this.disconnect(); - await this.http.close(); + + if (this.options.listen) + await this.http.close(); for (const wallet of this.wallets.values()) { await wallet.destroy(); @@ -180,7 +183,7 @@ WalletDB.prototype._close = async function _close() { await this.db.close(); - if (this.options.listen) + if (!this.options.plugin) await this.logger.close(); }; @@ -2043,6 +2046,7 @@ function WalletOptions(options) { this.ssl = false; this.host = '127.0.0.1'; this.port = this.network.rpcPort + 2; + this.plugin = false; this.listen = false; if (options) @@ -2169,6 +2173,11 @@ WalletOptions.prototype.fromOptions = function fromOptions(options) { this.port = options.port; } + if (options.plugin != null) { + assert(typeof options.plugin === 'boolean'); + this.plugin = options.plugin; + } + if (options.listen != null) { assert(typeof options.listen === 'boolean'); this.listen = options.listen; diff --git a/lib/workers/jobs.js b/lib/workers/jobs.js index 5da2aec4..7ae94357 100644 --- a/lib/workers/jobs.js +++ b/lib/workers/jobs.js @@ -6,8 +6,8 @@ 'use strict'; -const secp256k1 = require('../crypto/secp256k1'); -const {derive} = require('../crypto/scrypt'); +const secp256k1 = require('bcrypto/lib/secp256k1'); +const {derive} = require('bcrypto/lib/scrypt'); const hashcash = require('../mining/mine'); const packets = require('./packets'); diff --git a/migrate/chaindb2to3.js b/migrate/chaindb2to3.js index 4248684b..a4d7871f 100644 --- a/migrate/chaindb2to3.js +++ b/migrate/chaindb2to3.js @@ -19,8 +19,8 @@ const assert = require('assert'); const encoding = require('../lib/utils/encoding'); const co = require('../lib/utils/co'); const util = require('../lib/utils/util'); -const digest = require('../lib/crypto/digest'); -const BN = require('../lib/crypto/bn'); +const digest = require('bcrypto/lib/digest'); +const BN = require('bcrypto/lib/bn'); const StaticWriter = require('../lib/utils/staticwriter'); const BufferReader = require('../lib/utils/reader'); const OldCoins = require('./coins/coins'); diff --git a/migrate/compress-old.js b/migrate/compress-old.js index bceac2f1..83598864 100644 --- a/migrate/compress-old.js +++ b/migrate/compress-old.js @@ -7,7 +7,7 @@ 'use strict'; const assert = require('assert'); -const secp256k1 = require('../lib/crypto/secp256k1'); +const secp256k1 = require('bcrypto/lib/secp256k1'); /* * Compression diff --git a/migrate/ensure-tip-index.js b/migrate/ensure-tip-index.js index 200322dc..6c6d0950 100644 --- a/migrate/ensure-tip-index.js +++ b/migrate/ensure-tip-index.js @@ -3,10 +3,10 @@ const assert = require('assert'); const encoding = require('../lib/utils/encoding'); const BufferReader = require('../lib/utils/reader'); -const digest = require('../lib/crypto/digest'); +const digest = require('bcrypto/lib/digest'); const util = require('../lib/utils/util'); const LDB = require('../lib/db/ldb'); -const BN = require('../lib/crypto/bn'); +const BN = require('bcrypto/lib/bn'); const DUMMY = Buffer.from([0]); let file = process.argv[2]; let batch; diff --git a/package.json b/package.json index 9b028d21..2ee819c6 100644 --- a/package.json +++ b/package.json @@ -23,18 +23,16 @@ "node": ">=7.6.0" }, "dependencies": { - "bn.js": "4.11.8", - "elliptic": "6.4.0", "n64": "0.0.18", "breq": "^0.0.1", "bclient": "^0.0.1", "bweb": "^0.0.1", - "bsock": "^0.0.1" + "bsock": "^0.0.1", + "bcrypto": "^0.0.1" }, "optionalDependencies": { "bcoin-native": "0.0.23", - "leveldown": "1.7.2", - "secp256k1": "3.3.0" + "leveldown": "1.7.2" }, "devDependencies": { "babel-core": "^6.25.0", diff --git a/scripts/fuzz.js b/scripts/fuzz.js index 87835e2c..facfa9a8 100644 --- a/scripts/fuzz.js +++ b/scripts/fuzz.js @@ -8,8 +8,8 @@ const Input = require('../lib/primitives/input'); const Output = require('../lib/primitives/output'); const Outpoint = require('../lib/primitives/outpoint'); const TX = require('../lib/primitives/tx'); -const random = require('../lib/crypto/random'); -const secp256k1 = require('../lib/crypto/secp256k1'); +const random = require('bcrypto/lib/random'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const flags = Script.flags; let consensus = null; diff --git a/test/aes-test.js b/test/aes-test.js deleted file mode 100644 index 32c547ef..00000000 --- a/test/aes-test.js +++ /dev/null @@ -1,49 +0,0 @@ -/* eslint-env mocha */ -/* eslint prefer-arrow-callback: "off" */ - -'use strict'; - -const assert = require('./util/assert'); -const aes = require('../lib/crypto/aes'); - -const key = Buffer.from( - '3a0c0bf669694ac7685e6806eeadee8e56c9b9bd22c3caa81c718ed4bbf809a1', - 'hex'); - -const iv = Buffer.from('6dd26d9045b73c377a9ed2ffeca72ffd', 'hex'); - -describe('AES', function() { - it('should encrypt and decrypt with 2 blocks', () => { - const data = Buffer.from( - 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', - 'hex'); - - const expected = Buffer.from('' - + '83de502a9c83112ca6383f2214a892a0cdad5ab2b3e192e' - + '9921ddb126b25262c41f1dcff4d67ccfb40e4116e5a4569c1', - 'hex'); - - const ciphertext = aes.encipher(data, key, iv); - assert.bufferEqual(ciphertext, expected); - - const plaintext = aes.decipher(ciphertext, key, iv); - assert.bufferEqual(plaintext, data); - }); - - it('should encrypt and decrypt with uneven blocks', () => { - const data = Buffer.from( - 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855010203', - 'hex'); - - const expected = Buffer.from('' - + '83de502a9c83112ca6383f2214a892a0cdad5ab2b3e192e9' - + '921ddb126b25262c5211801019a30c0c6f795296923e0af8', - 'hex'); - - const ciphertext = aes.encipher(data, key, iv); - assert.bufferEqual(ciphertext, expected); - - const plaintext = aes.decipher(ciphertext, key, iv); - assert.bufferEqual(plaintext, data); - }); -}); diff --git a/test/bip150-test.js b/test/bip150-test.js index b78c1587..7f745f62 100644 --- a/test/bip150-test.js +++ b/test/bip150-test.js @@ -4,7 +4,7 @@ 'use strict'; const assert = require('./util/assert'); -const secp256k1 = require('../lib/crypto/secp256k1'); +const secp256k1 = require('bcrypto/lib/secp256k1'); const BIP150 = require('../lib/net/bip150'); const BIP151 = require('../lib/net/bip151'); diff --git a/test/chachapoly-test.js b/test/chachapoly-test.js deleted file mode 100644 index 27beb23c..00000000 --- a/test/chachapoly-test.js +++ /dev/null @@ -1,235 +0,0 @@ -/* eslint-env mocha */ -/* eslint prefer-arrow-callback: "off" */ - -'use strict'; - -const assert = require('./util/assert'); -const ChaCha20 = require('../lib/crypto/chacha20'); -const Poly1305 = require('../lib/crypto/poly1305'); -const AEAD = require('../lib/crypto/aead'); - -function testChaCha(options) { - const key = Buffer.from(options.key, 'hex'); - const nonce = Buffer.from(options.nonce, 'hex'); - const plain = Buffer.from(options.plain, 'hex'); - const ciphertext = Buffer.from(options.ciphertext, 'hex'); - const counter = options.counter; - - const ctx1 = new ChaCha20(); - ctx1.init(key, nonce, counter); - const plainenc = Buffer.from(plain); - ctx1.encrypt(plainenc); - assert.bufferEqual(plainenc, ciphertext); - - const ctx2 = new ChaCha20(); - ctx2.init(key, nonce, counter); - ctx2.encrypt(ciphertext); - assert.bufferEqual(plain, ciphertext); -} - -function testAEAD(options) { - const plain = Buffer.from(options.plain, 'hex'); - const aad = Buffer.from(options.aad, 'hex'); - const key = Buffer.from(options.key, 'hex'); - const nonce = Buffer.from(options.nonce, 'hex'); - const pk = Buffer.from(options.pk, 'hex'); - const ciphertext = Buffer.from(options.ciphertext, 'hex'); - const tag = Buffer.from(options.tag, 'hex'); - - const ctx1 = new AEAD(); - ctx1.init(key, nonce); - assert.strictEqual(ctx1.chacha20.getCounter(), 1); - assert.bufferEqual(ctx1.polyKey, pk); - ctx1.aad(aad); - const plainenc = Buffer.from(plain); - ctx1.encrypt(plainenc); - assert.bufferEqual(plainenc, ciphertext); - assert.bufferEqual(ctx1.finish(), tag); - - const ctx2 = new AEAD(); - ctx2.init(key, nonce); - assert.strictEqual(ctx2.chacha20.getCounter(), 1); - assert.bufferEqual(ctx2.polyKey, pk); - ctx2.aad(aad); - ctx2.decrypt(ciphertext); - assert.bufferEqual(ciphertext, plain); - assert.bufferEqual(ctx2.finish(), tag); -} - -describe('ChaCha20 / Poly1305 / AEAD', function() { - it('should perform chacha20', () => { - testChaCha({ - key: '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', - nonce: '000000000000004a00000000', - plain: '' - + '4c616469657320616e642047656e746c656d656e206f6620746865206' - + '36c617373206f66202739393a204966204920636f756c64206f6666657220796' - + 'f75206f6e6c79206f6e652074697020666f7220746865206675747572652c207' - + '3756e73637265656e20776f756c642062652069742e', - ciphertext: '' - + '6e2e359a2568f98041ba0728dd0d6981e97e7aec1d4360c20a27afcc' - + 'fd9fae0bf91b65c5524733ab8f593dabcd62b3571639d624e65152ab' - + '8f530c359f0861d807ca0dbf500d6a6156a38e088a22b65e52bc514d' - + '16ccf806818ce91ab77937365af90bbf74a35be6b40b8eedf2785e42874d', - counter: 1 - }); - }); - - it('should perform chacha20', () => { - testChaCha({ - key: '0000000000000000000000000000000000000000000000000000000000000000', - nonce: '000000000000000000000000', - plain: '' - + '0000000000000000000000000000000000000000000000000000000000000000' - + '0000000000000000000000000000000000000000000000000000000000000000', - ciphertext: '' - + '76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b77' - + '0dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669' - + 'b2ee6586', - counter: 0 - }); - }); - - it('should perform chacha20', () => { - testChaCha({ - key: '0000000000000000000000000000000000000000000000000000000000000001', - nonce: '000000000000000000000002', - plain: '' - + '416e79207375626d697373696f6e20746f20746865204945544620696e' - + '74656e6465642062792074686520436f6e7472696275746f7220666f722' - + '07075626c69636174696f6e20617320616c6c206f722070617274206f' - + '6620616e204945544620496e7465726e65742d4472616674206f7220524' - + '64320616e6420616e792073746174656d656e74206d6164652077697468696' - + 'e2074686520636f6e74657874206f6620616e2049455446206163746976' - + '69747920697320636f6e7369646572656420616e20224945544620436f6' - + 'e747269627574696f6e222e20537563682073746174656d656e747320696e' - + '636c756465206f72616c2073746174656d656e747320696e204945544620' - + '73657373696f6e732c2061732077656c6c206173207772697474656e2061' - + '6e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d' - + '61646520617420616e792074696d65206f7220706c6163652c2077686963' - + '68206172652061646472657373656420746f', - ciphertext: '' - + 'a3fbf07df3fa2fde4f376ca23e82737041605d9f4f4f57bd8cff2c1d' - + '4b7955ec2a97948bd3722915c8f3d337f7d370050e9e96d647b7c39f' - + '56e031ca5eb6250d4042e02785ececfa4b4bb5e8ead0440e20b6e8db' - + '09d881a7c6132f420e52795042bdfa7773d8a9051447b3291ce1411c' - + '680465552aa6c405b7764d5e87bea85ad00f8449ed8f72d0d662ab05' - + '2691ca66424bc86d2df80ea41f43abf937d3259dc4b2d0dfb48a6c91' - + '39ddd7f76966e928e635553ba76c5c879d7b35d49eb2e62b0871cdac' - + '638939e25e8a1e0ef9d5280fa8ca328b351c3c765989cbcf3daa8b6c' - + 'cc3aaf9f3979c92b3720fc88dc95ed84a1be059c6499b9fda236e7e8' - + '18b04b0bc39c1e876b193bfe5569753f88128cc08aaa9b63d1a16f80' - + 'ef2554d7189c411f5869ca52c5b83fa36ff216b9c1d30062bebcfd' - + '2dc5bce0911934fda79a86f6e698ced759c3ff9b6477338f3da4f9' - + 'cd8514ea9982ccafb341b2384dd902f3d1ab7ac61dd29c6f21ba5b' - + '862f3730e37cfdc4fd806c22f221', - counter: 1 - }); - }); - - it('should perform chacha20', () => { - testChaCha({ - key: '1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0', - nonce: '000000000000000000000002', - plain: '' - + '2754776173206272696c6c69672c20616e642074686520736c6974687920746f76' - + '65730a446964206779726520616e642067696d626c6520696e207468' - + '6520776162653a0a416c6c206d696d73792077657265207468652062' - + '6f726f676f7665732c0a416e6420746865206d6f6d65207261746873' - + '206f757467726162652e', - ciphertext: '' - + '62e6347f95ed87a45ffae7426f27a1df5fb69110044c0d73118effa95b01e5cf16' - + '6d3df2d721caf9b21e5fb14c616871fd84c54f9d65b283196c7fe4f6' - + '0553ebf39c6402c42234e32a356b3e764312a61a5532055716ead696' - + '2568f87d3f3f7704c6a8d1bcd1bf4d50d6154b6da731b187b58dfd72' - + '8afa36757a797ac188d1', - counter: 42 - }); - }); - - it('should perform poly1305', () => { - const expected = Buffer.from('ddb9da7ddd5e52792730ed5cda5f90a4', 'hex'); - const key = Buffer.allocUnsafe(32); - const msg = Buffer.allocUnsafe(73); - - for (let i = 0; i < key.length; i++) - key[i] = i + 221; - - for (let i = 0; i < msg.length; i++) - msg[i] = i + 121; - - const mac = Poly1305.auth(msg, key); - assert(Poly1305.verify(mac, expected)); - assert.bufferEqual(mac, expected); - }); - - it('should perform poly1305', () => { - const key = Buffer.from('' - + '85d6be7857556d337f4452fe42d506a' - + '80103808afb0db2fd4abff6af4149f51b', - 'hex'); - - const msg = Buffer.from('Cryptographic Forum Research Group', 'ascii'); - const tag = Buffer.from('a8061dc1305136c6c22b8baf0c0127a9', 'hex'); - - const mac = Poly1305.auth(msg, key); - - assert(Poly1305.verify(mac, tag)); - - mac[0] = 0; - - assert(!Poly1305.verify(mac, tag)); - }); - - it('should create an AEAD and encrypt', () => { - testAEAD({ - plain: '' - + '4c616469657320616e642047656e746c656d656e206f662074686520636c6' - + '17373206f66202739393a204966204920636f756c64206f666665722' - + '0796f75206f6e6c79206f6e652074697020666f72207468652066757' - + '47572652c2073756e73637265656e20776f756c642062652069742e', - aad: '50515253c0c1c2c3c4c5c6c7', - key: '808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f', - nonce: '07000000' + '4041424344454647', - pk: '7bac2b252db447af09b67a55a4e955840ae1d6731075d9eb2a9375783ed553ff', - ciphertext: '' - + 'd31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee6' - + '2d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a' - + '5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad67' - + '5945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116', - tag: '1ae10b594f09e26a7e902ecbd0600691' - }); - }); - - it('should create an AEAD and encrypt', () => { - testAEAD({ - key: '1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0', - ciphertext: '' - + '64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8' - + 'cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03' - + 'b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d3' - + '3bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b35063836069' - + '07b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a' - + '4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b004' - + '7718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa7' - + '6991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e61' - + '7d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6' - + 'f2c29a6ad5cb4022b02709b', - nonce: '000000000102030405060708', - aad: 'f33388860000000000004e91', - tag: 'eead9d67890cbb22392336fea1851f38', - pk: 'bdf04aa95ce4de8995b14bb6a18fecaf26478f50c054f563dbc0a21e261572aa', - plain: '' - + '496e7465726e65742d4472616674732061726520647261667420646f63756' - + 'd656e74732076616c696420666f722061206d6178696d756d206f662' - + '0736978206d6f6e74687320616e64206d61792062652075706461746' - + '5642c207265706c616365642c206f72206f62736f6c6574656420627' - + '9206f7468657220646f63756d656e747320617420616e792074696d6' - + '52e20497420697320696e617070726f70726961746520746f2075736' - + '520496e7465726e65742d447261667473206173207265666572656e6' - + '365206d6174657269616c206f7220746f2063697465207468656d206' - + 'f74686572207468616e206173202fe2809c776f726b20696e2070726' - + 'f67726573732e2fe2809d' - }); - }); -}); diff --git a/test/consensus-test.js b/test/consensus-test.js index 9cd15b37..33882b42 100644 --- a/test/consensus-test.js +++ b/test/consensus-test.js @@ -5,7 +5,7 @@ const assert = require('./util/assert'); const consensus = require('../lib/protocol/consensus'); -const BN = require('../lib/crypto/bn'); +const BN = require('bcrypto/lib/bn'); describe('Consensus', function() { it('should calculate reward properly', () => { diff --git a/test/gcs-test.js b/test/gcs-test.js index 761c7f93..4d34e13d 100644 --- a/test/gcs-test.js +++ b/test/gcs-test.js @@ -5,7 +5,7 @@ const assert = require('./util/assert'); const GCSFilter = require('../lib/utils/gcs'); -const random = require('../lib/crypto/random'); +const random = require('bcrypto/lib/random'); const Outpoint = require('../lib/primitives/outpoint'); const Address = require('../lib/primitives/address'); const common = require('./util/common'); diff --git a/test/hd-test.js b/test/hd-test.js index 4a8698ed..ed5132b6 100644 --- a/test/hd-test.js +++ b/test/hd-test.js @@ -6,7 +6,8 @@ const assert = require('./util/assert'); const HD = require('../lib/hd'); const base58 = require('../lib/utils/base58'); -const pbkdf2 = require('../lib/crypto/pbkdf2'); +const pbkdf2 = require('bcrypto/lib/pbkdf2'); +const sha512 = require('bcrypto/lib/sha512'); const vectors = require('./data/hd.json'); const vector1 = vectors.vector1; const vector2 = vectors.vector2; @@ -21,8 +22,11 @@ function base58Equal(a, b) { describe('HD', function() { it('should create a pbkdf2 seed', () => { - const seed = pbkdf2.derive( - vectors.phrase, 'mnemonicfoo', 2048, 64, 'sha512'); + const seed = pbkdf2.derive(sha512, + Buffer.from(vectors.phrase), + Buffer.from('mnemonicfoo'), + 2048, + 64); assert.strictEqual(seed.toString('hex'), vectors.seed); }); diff --git a/test/hkdf-test.js b/test/hkdf-test.js deleted file mode 100644 index 8a43dcc6..00000000 --- a/test/hkdf-test.js +++ /dev/null @@ -1,84 +0,0 @@ -/* eslint-env mocha */ -/* eslint prefer-arrow-callback: "off" */ - -'use strict'; - -const assert = require('./util/assert'); -const hkdf = require('../lib/crypto/hkdf'); - -describe('HKDF', function() { - it('should do proper hkdf (1)', () => { - // https://tools.ietf.org/html/rfc5869 - const alg = 'sha256'; - const ikm = Buffer.from( - '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'); - const salt = Buffer.from('000102030405060708090a0b0c', 'hex'); - const info = Buffer.from('f0f1f2f3f4f5f6f7f8f9', 'hex'); - const len = 42; - - const prkE = Buffer.from( - '077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5', - 'hex'); - - const okmE = Buffer.from('' - + '3cb25f25faacd57a90434f64d0362f2a2d2d0a90' - + 'cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865', - 'hex'); - - const prk = hkdf.extract(ikm, salt, alg); - const okm = hkdf.expand(prk, info, len, alg); - - assert.bufferEqual(prk, prkE); - assert.bufferEqual(okm, okmE); - }); - - it('should do proper hkdf (2)', () => { - const alg = 'sha256'; - - const ikm = Buffer.from('' - + '000102030405060708090a0b0c0d0e0f' - + '101112131415161718191a1b1c1d1e1f' - + '202122232425262728292a2b2c2d2e2f' - + '303132333435363738393a3b3c3d3e3f' - + '404142434445464748494a4b4c4d4e4f', - 'hex'); - - const salt = Buffer.from('' - + '606162636465666768696a6b6c6d6e6f' - + '707172737475767778797a7b7c7d7e7f' - + '808182838485868788898a8b8c8d8e8f' - + '909192939495969798999a9b9c9d9e9f' - + 'a0a1a2a3a4a5a6a7a8a9aaabacadaeaf', - 'hex'); - - const info = Buffer.from('' - + 'b0b1b2b3b4b5b6b7b8b9babbbcbdbebf' - + 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf' - + 'd0d1d2d3d4d5d6d7d8d9dadbdcdddedf' - + 'e0e1e2e3e4e5e6e7e8e9eaebecedeeef' - + 'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff', - 'hex'); - - const len = 82; - - const prkE = Buffer.from('' - + '06a6b88c5853361a06104c9ceb35b45c' - + 'ef760014904671014a193f40c15fc244', - 'hex'); - - const okmE = Buffer.from('' - + 'b11e398dc80327a1c8e7f78c596a4934' - + '4f012eda2d4efad8a050cc4c19afa97c' - + '59045a99cac7827271cb41c65e590e09' - + 'da3275600c2f09b8367793a9aca3db71' - + 'cc30c58179ec3e87c14c01d5c1f3434f' - + '1d87', - 'hex'); - - const prk = hkdf.extract(ikm, salt, alg); - const okm = hkdf.expand(prk, info, len, alg); - - assert.bufferEqual(prk, prkE); - assert.bufferEqual(okm, okmE); - }); -}); diff --git a/test/mempool-test.js b/test/mempool-test.js index 63567337..0d8e8598 100644 --- a/test/mempool-test.js +++ b/test/mempool-test.js @@ -5,7 +5,7 @@ const assert = require('./util/assert'); const encoding = require('../lib/utils/encoding'); -const random = require('../lib/crypto/random'); +const random = require('bcrypto/lib/random'); const MempoolEntry = require('../lib/mempool/mempoolentry'); const Mempool = require('../lib/mempool/mempool'); const WorkerPool = require('../lib/workers/workerpool'); diff --git a/test/schnorr-test.js b/test/schnorr-test.js deleted file mode 100644 index 0934fd56..00000000 --- a/test/schnorr-test.js +++ /dev/null @@ -1,20 +0,0 @@ -/* eslint-env mocha */ -/* eslint prefer-arrow-callback: "off" */ - -'use strict'; - -const assert = require('./util/assert'); -const secp256k1 = require('../lib/crypto/secp256k1'); -const digest = require('../lib/crypto/digest'); -const schnorr = require('../lib/crypto/schnorr'); - -describe('Schnorr', function() { - it('should do proper schnorr', () => { - const key = secp256k1.generatePrivateKey(); - const pub = secp256k1.publicKeyCreate(key, true); - const msg = digest.hash256(Buffer.from('foo', 'ascii')); - const sig = schnorr.sign(msg, key); - assert.strictEqual(schnorr.verify(msg, sig, pub), true); - assert.bufferEqual(schnorr.recover(sig, msg), pub); - }); -}); diff --git a/test/scrypt-test.js b/test/scrypt-test.js deleted file mode 100644 index 93f13e1f..00000000 --- a/test/scrypt-test.js +++ /dev/null @@ -1,93 +0,0 @@ -/* eslint-env mocha */ -/* eslint prefer-arrow-callback: "off" */ - -'use strict'; - -const assert = require('./util/assert'); -const scrypt = require('../lib/crypto/scrypt'); - -describe('Scrypt', function() { - this.timeout(20000); - - it('should perform scrypt with N=16', () => { - const pass = Buffer.from(''); - const salt = Buffer.from(''); - const result = scrypt.derive(pass, salt, 16, 1, 1, 64); - assert.strictEqual(result.toString('hex'), '' - + '77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3f' - + 'ede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628' - + 'cf35e20c38d18906'); - }); - - it('should perform scrypt with N=1024', () => { - const pass = Buffer.from('password'); - const salt = Buffer.from('NaCl'); - const result = scrypt.derive(pass, salt, 1024, 8, 16, 64); - assert.strictEqual(result.toString('hex'), '' - + 'fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e773' - + '76634b3731622eaf30d92e22a3886ff109279d9830dac727afb9' - + '4a83ee6d8360cbdfa2cc0640'); - }); - - it('should perform scrypt with N=16384', () => { - const pass = Buffer.from('pleaseletmein'); - const salt = Buffer.from('SodiumChloride'); - const result = scrypt.derive(pass, salt, 16384, 8, 1, 64); - assert.strictEqual(result.toString('hex'), '' - + '7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b54' - + '3f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d' - + '651e40dfcf017b45575887'); - }); - - // Only enable if you want to wait a while. - // it('should perform scrypt with N=1048576', () => { - // let pass = Buffer.from('pleaseletmein'); - // let salt = Buffer.from('SodiumChloride'); - // let result = scrypt.derive(pass, salt, 1048576, 8, 1, 64); - // assert.strictEqual(result.toString('hex'), '' - // + '2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5' - // + 'ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049' - // + 'e8a952fbcbf45c6fa77a41a4'); - // }); - - it('should perform scrypt with N=16 (async)', async () => { - const pass = Buffer.from(''); - const salt = Buffer.from(''); - const result = await scrypt.deriveAsync(pass, salt, 16, 1, 1, 64); - assert.strictEqual(result.toString('hex'), '' - + '77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3f' - + 'ede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628' - + 'cf35e20c38d18906'); - }); - - it('should perform scrypt with N=1024 (async)', async () => { - const pass = Buffer.from('password'); - const salt = Buffer.from('NaCl'); - const result = await scrypt.deriveAsync(pass, salt, 1024, 8, 16, 64); - assert.strictEqual(result.toString('hex'), '' - + 'fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e773' - + '76634b3731622eaf30d92e22a3886ff109279d9830dac727afb9' - + '4a83ee6d8360cbdfa2cc0640'); - }); - - it('should perform scrypt with N=16384 (async)', async () => { - const pass = Buffer.from('pleaseletmein'); - const salt = Buffer.from('SodiumChloride'); - const result = await scrypt.deriveAsync(pass, salt, 16384, 8, 1, 64); - assert.strictEqual(result.toString('hex'), '' - + '7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b54' - + '3f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d' - + '651e40dfcf017b45575887'); - }); - - // Only enable if you want to wait a while. - // it('should perform scrypt with N=1048576 (async)', async () => { - // let pass = Buffer.from('pleaseletmein'); - // let salt = Buffer.from('SodiumChloride'); - // let result = await scrypt.deriveAsync(pass, salt, 1048576, 8, 1, 64); - // assert.strictEqual(result.toString('hex'), '' - // + '2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5' - // + 'ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049' - // + 'e8a952fbcbf45c6fa77a41a4'); - // }); -}); diff --git a/test/siphash-test.js b/test/siphash-test.js deleted file mode 100644 index 76aa8932..00000000 --- a/test/siphash-test.js +++ /dev/null @@ -1,30 +0,0 @@ -/* eslint-env mocha */ -/* eslint prefer-arrow-callback: "off" */ - -'use strict'; - -const assert = require('./util/assert'); -const siphash = require('../lib/crypto/siphash'); -const siphash256 = siphash.siphash256; - -describe('SipHash', function() { - it('should perform siphash with no data', () => { - const data = Buffer.alloc(0); - const key = Buffer.from('000102030405060708090a0b0c0d0e0f', 'hex'); - assert.deepStrictEqual(siphash256(data, key), [1919933255, -586281423]); - }); - - it('should perform siphash with data', () => { - const data = Buffer.from('0001020304050607', 'hex'); - const key = Buffer.from('000102030405060708090a0b0c0d0e0f', 'hex'); - assert.deepStrictEqual(siphash256(data, key), [-1812597383, -1701632926]); - }); - - it('should perform siphash with uint256', () => { - const data = Buffer.from( - '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', - 'hex'); - const key = Buffer.from('000102030405060708090a0b0c0d0e0f', 'hex'); - assert.deepStrictEqual(siphash256(data, key), [1898402095, 1928494286]); - }); -}); diff --git a/test/tx-test.js b/test/tx-test.js index 5de5b465..12d85b0c 100644 --- a/test/tx-test.js +++ b/test/tx-test.js @@ -6,7 +6,7 @@ const assert = require('./util/assert'); const util = require('../lib/utils/util'); const encoding = require('../lib/utils/encoding'); -const random = require('../lib/crypto/random'); +const random = require('bcrypto/lib/random'); const consensus = require('../lib/protocol/consensus'); const TX = require('../lib/primitives/tx'); const Output = require('../lib/primitives/output'); diff --git a/test/wallet-test.js b/test/wallet-test.js index 327027f3..cc042c9d 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -7,8 +7,8 @@ const assert = require('./util/assert'); const consensus = require('../lib/protocol/consensus'); const util = require('../lib/utils/util'); const encoding = require('../lib/utils/encoding'); -const digest = require('../lib/crypto/digest'); -const random = require('../lib/crypto/random'); +const digest = require('bcrypto/lib/digest'); +const random = require('bcrypto/lib/random'); const WalletDB = require('../lib/wallet/walletdb'); const WorkerPool = require('../lib/workers/workerpool'); const Address = require('../lib/primitives/address');