diff --git a/CHANGELOG.md b/CHANGELOG.md index aa4f02c9e..1937d96cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Bcoin release notes & changelog +## unreleased + +- Support for bech32m has been added. bcoin can now validate and send BTC to +addresses for witness programs with versions > 0. The address indexer has +also been updated to retrieve the new addresses. A bug was fixed where the +indexer may return data for a witness version 0 address even if a version 1 +address was queried, if the two addresses had the same data (hash). After +upgrading bcoin, a full rescan may be necessary to re-index these collisions +correctly. To accomplish this: + - Stop bcoin (`bcoin-cli rpc stop` or `ctrl-C`) + - Delete the existing addr indexer data (`rm -rf ~/.bcoin/index/addr`) + - Restart bcoin + - The address indexer will automatically begin re-indexing the chain. It may take up to 24 hours. + +- The logging module `blgr` has been updated. Log files will now be rolled over +at around 20 MB and timestamped. Only the last 10 log files will be kept on disk +and older log files will be purged. These values can be configured by passing +`--log-max-file-size` (in MB) and `--log-max-files`. + ## v2.1.2 - Fixed wallet RPC method `importprunedfunds`. diff --git a/bin/bcoin-cli b/bin/bcoin-cli index dd27fb9c6..05c4be054 100755 --- a/bin/bcoin-cli +++ b/bin/bcoin-cli @@ -64,7 +64,7 @@ class CLI { async getTX() { const hash = this.config.str(0, ''); - if (hash.length !== 64) { + if (!/^[0-9a-f]{64}$/i.test(hash)) { const txs = await this.client.getTXByAddress(hash); this.log(txs); return; diff --git a/lib/node/node.js b/lib/node/node.js index c35f1030b..34ca04c88 100644 --- a/lib/node/node.js +++ b/lib/node/node.js @@ -91,7 +91,9 @@ class Node extends EventEmitter { : null, level: config.str('log-level'), console: config.bool('log-console'), - shrink: config.bool('log-shrink') + shrink: config.bool('log-shrink'), + maxFileSize: config.mb('log-max-file-size'), + maxFiles: config.uint('log-max-files') }); this.logger = logger.context('node'); diff --git a/lib/primitives/address.js b/lib/primitives/address.js index a036d175d..b7fa0e631 100644 --- a/lib/primitives/address.js +++ b/lib/primitives/address.js @@ -11,6 +11,7 @@ const assert = require('bsert'); const bio = require('bufio'); const base58 = require('bcrypto/lib/encoding/base58'); const bech32 = require('bcrypto/lib/encoding/bech32'); +const bech32m = require('bcrypto/lib/encoding/bech32m'); const sha256 = require('bcrypto/lib/sha256'); const hash160 = require('bcrypto/lib/hash160'); const hash256 = require('bcrypto/lib/hash256'); @@ -131,13 +132,30 @@ class Address { return Address.typesByVal[this.type].toLowerCase(); } + /** + * Get prefix for indexers + * It's a single byte encoded as follows: + * 1 bit whether it's legacy or witness. + * 7 bits used for the data. + * @param {Network|String} network + * @returns {Number} + */ + + getPrefix(network) { + if (this.isProgram()) + return this.version; + + // Note: -1 | 0x80 = -1 + return 0x80 | this.getBase58Prefix(network); + } + /** * Get a network address prefix for the address. * @param {Network?} network * @returns {Number} */ - getPrefix(network) { + getBase58Prefix(network) { network = Network.get(network); const prefixes = network.addressPrefix; @@ -147,14 +165,6 @@ class Address { return prefixes.pubkeyhash; case Address.types.SCRIPTHASH: return prefixes.scripthash; - case Address.types.WITNESS: - if (this.hash.length === 20) - return prefixes.witnesspubkeyhash; - - if (this.hash.length === 32) - return prefixes.witnessscripthash; - - break; } return -1; @@ -184,7 +194,7 @@ class Address { toRaw(network) { const size = this.getSize(); const bw = bio.write(size); - const prefix = this.getPrefix(network); + const prefix = this.getBase58Prefix(network); assert(prefix !== -1, 'Not a valid address prefix.'); @@ -226,6 +236,9 @@ class Address { assert(version !== -1, 'Cannot convert non-program address to bech32.'); + assert(version === 0, + 'Cannot convert program version > 0 to bech32 address.'); + network = Network.get(network); const hrp = network.addressPrefix.bech32; @@ -233,6 +246,30 @@ class Address { return bech32.encode(hrp, version, hash); } + /** + * Compile the address object to a bech32m address. + * @param {{NetworkType|Network)?} network + * @returns {String} + * @throws Error on bad hash/prefix. + */ + + toBech32m(network) { + const version = this.version; + const hash = this.hash; + + assert(version !== -1, + 'Cannot convert non-program address to bech32m.'); + + assert(version !== 0, + 'Cannot convert version 0 program to bech32m address.'); + + network = Network.get(network); + + const hrp = network.addressPrefix.bech32; + + return bech32m.encode(hrp, version, hash); + } + /** * Inject properties from string. * @private @@ -253,7 +290,11 @@ class Address { // Otherwise, it's most likely bech32. try { - return this.fromBech32(addr, network); + try{ + return this.fromBech32(addr, network); + } catch (e) { + return this.fromBech32m(addr, network); + } } catch (e) { return this.fromBase58(addr, network); } @@ -277,8 +318,12 @@ class Address { */ toString(network) { - if (this.version !== -1) - return this.toBech32(network); + if (this.version !== -1) { + if (this.version === 0) + return this.toBech32(network); + + return this.toBech32m(network); + } return this.toBase58(network); } @@ -296,7 +341,7 @@ class Address { } /** - * Inject properties from serialized data. + * Decode base58. * @private * @param {Buffer} data * @throws Parse error @@ -306,29 +351,18 @@ class Address { const br = bio.read(data, true); const prefix = br.readU8(); - network = Network.fromAddress(prefix, network); + network = Network.fromBase58(prefix, network); const type = Address.getType(prefix, network); - let version = -1; - if (type === Address.types.WITNESS) { - if (data.length > 38) - throw new Error('Address is too long.'); - - version = br.readU8(); - - if (br.readU8() !== 0) - throw new Error('Address version padding is non-zero.'); - } else { - if (data.length !== 25) - throw new Error('Address is too long.'); - } + if (data.length !== 25) + throw new Error('Address is too long.'); const hash = br.readBytes(br.left() - 4); br.verifyChecksum(hash256.digest); - return this.fromHash(hash, type, version); + return this.fromHash(hash, type); } /** @@ -386,6 +420,12 @@ class Address { const [hrp, version, hash] = bech32.decode(data); + assert(version !== -1, + 'Cannot convert non-program address to bech32'); + + assert(version === 0, + 'Cannot convert program version > 0 to bech32'); + // make sure HRP is correct. Network.fromBech32(hrp, network); @@ -404,6 +444,45 @@ class Address { return new this().fromBech32(data, network); } + /** + * Inject properties from bech32m address. + * @private + * @param {String} data + * @param {Network?} network + * @throws Parse error + */ + + fromBech32m(data, network) { + const type = Address.types.WITNESS; + + assert(typeof data === 'string'); + + const [hrp, version, hash] = bech32m.decode(data); + + assert(version !== -1, + 'Cannot convert non-program address to bech32m'); + + assert(version > 0, + 'Cannot convert program version 0 to bech32m.'); + + // make sure HRP is correct. + Network.fromBech32m(hrp, network); + + return this.fromHash(hash, type, version); + } + + /** + * Create an address object from a bech32m address. + * @param {String} data + * @param {Network?} network + * @returns {Address} + * @throws Parse error. + */ + + static fromBech32m(data, network) { + return new this().fromBech32m(data, network); + } + /** * Inject properties from output script. * @private @@ -587,9 +666,9 @@ class Address { } else { assert(type === Address.types.WITNESS, 'Wrong version (non-witness).'); assert(version >= 0 && version <= 16, 'Bad program version.'); - if (version === 0 && type === Address.types.WITNESS) { + if (version === 0) { assert(hash.length === 20 || hash.length === 32, - 'Witness program hash is the wrong size.'); + 'Witness version 0 program hash is the wrong size.'); } assert(hash.length >= 2 && hash.length <= 40, 'Hash is the wrong size.'); } @@ -778,21 +857,6 @@ class Address { return this.version !== -1; } - /** - * Test whether the address is an unknown witness program. - * @returns {Boolean} - */ - - isUnknown() { - if (this.version === -1) - return false; - - if (this.version > 0) - return true; - - return this.hash.length !== 20 && this.hash.length !== 32; - } - /** * Get the hash of a base58 address or address-related object. * @param {String|Address|Hash} data @@ -807,8 +871,6 @@ class Address { let hash; if (Buffer.isBuffer(data)) { - if (data.length !== 20 && data.length !== 32) - throw new Error('Object is not an address.'); hash = data; } else if (data instanceof Address) { hash = data.hash; @@ -837,9 +899,6 @@ class Address { return Address.types.PUBKEYHASH; case prefixes.scripthash: return Address.types.SCRIPTHASH; - case prefixes.witnesspubkeyhash: - case prefixes.witnessscripthash: - return Address.types.WITNESS; default: throw new Error('Unknown address prefix.'); } diff --git a/lib/protocol/network.js b/lib/protocol/network.js index e3d9f0895..27d8f6061 100644 --- a/lib/protocol/network.js +++ b/lib/protocol/network.js @@ -308,8 +308,8 @@ class Network { * @returns {Network} */ - static fromAddress(prefix, network) { - return Network.by(prefix, cmpAddress, network, 'base58 address'); + static fromBase58(prefix, network) { + return Network.by(prefix, cmpBase58, network, 'base58 address'); } /** @@ -323,6 +323,17 @@ class Network { return Network.by(hrp, cmpBech32, network, 'bech32 address'); } + /** + * Get a network by its bech32m address prefix. + * @param {String} hrp + * @param {Network?} network + * @returns {Network} + */ + + static fromBech32m(hrp, network) { + return Network.by(hrp, cmpBech32, network, 'bech32m address'); + } + /** * Convert the network to a string. * @returns {String} @@ -417,14 +428,12 @@ function cmpPriv58(network, prefix) { return network.keyPrefix.xprivkey58 === prefix; } -function cmpAddress(network, prefix) { +function cmpBase58(network, prefix) { const prefixes = network.addressPrefix; switch (prefix) { case prefixes.pubkeyhash: case prefixes.scripthash: - case prefixes.witnesspubkeyhash: - case prefixes.witnessscripthash: return true; } diff --git a/lib/protocol/networks.js b/lib/protocol/networks.js index e7cfe9400..235627ccf 100644 --- a/lib/protocol/networks.js +++ b/lib/protocol/networks.js @@ -433,8 +433,6 @@ main.keyPrefix = { main.addressPrefix = { pubkeyhash: 0x00, scripthash: 0x05, - witnesspubkeyhash: 0x06, - witnessscripthash: 0x0a, bech32: 'bc' }; @@ -688,8 +686,6 @@ testnet.keyPrefix = { testnet.addressPrefix = { pubkeyhash: 0x6f, scripthash: 0xc4, - witnesspubkeyhash: 0x03, - witnessscripthash: 0x28, bech32: 'tb' }; @@ -850,8 +846,6 @@ regtest.keyPrefix = { regtest.addressPrefix = { pubkeyhash: 0x6f, scripthash: 0xc4, - witnesspubkeyhash: 0x03, - witnessscripthash: 0x28, bech32: 'bcrt' }; @@ -1020,8 +1014,6 @@ simnet.keyPrefix = { simnet.addressPrefix = { pubkeyhash: 0x3f, scripthash: 0x7b, - witnesspubkeyhash: 0x19, - witnessscripthash: 0x28, bech32: 'sb' }; diff --git a/node_modules/bcfg/lib/config.js b/node_modules/bcfg/lib/config.js index b78f94272..b9e15bc4f 100644 --- a/node_modules/bcfg/lib/config.js +++ b/node_modules/bcfg/lib/config.js @@ -166,6 +166,7 @@ class Config { _filter(name, this.args, child.args); _filter(name, this.query, child.query); _filter(name, this.hash, child.hash); + _filter(name, this.options, child.options); return child; } diff --git a/node_modules/bcfg/package.json b/node_modules/bcfg/package.json index e444407c4..e2e068d87 100644 --- a/node_modules/bcfg/package.json +++ b/node_modules/bcfg/package.json @@ -1,6 +1,6 @@ { "name": "bcfg", - "version": "0.1.6", + "version": "0.1.7", "description": "Config parser for bcoin", "keywords": [ "conf", @@ -30,7 +30,7 @@ "browser": { "./lib/fs": "./lib/fs-browser.js" }, - "_from": "git+https://github.com/bcoin-org/bcfg.git#semver:~0.1.6", - "_resolved": "git+https://github.com/bcoin-org/bcfg.git#1216c775832c2e138ae6451912a27ba496dc4386", - "_commit": "1216c775832c2e138ae6451912a27ba496dc4386" + "_from": "git+https://github.com/bcoin-org/bcfg.git#semver:~0.1.7", + "_resolved": "git+https://github.com/bcoin-org/bcfg.git#05122154b35baa82cd01dc9478ebee7346386ba1", + "_commit": "05122154b35baa82cd01dc9478ebee7346386ba1" } diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/aead.h b/node_modules/bcrypto/deps/torsion/include/torsion/aead.h index 5e877ac25..2d61d13a4 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/aead.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/aead.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_AEAD_H -#define _TORSION_AEAD_H +#ifndef TORSION_AEAD_H +#define TORSION_AEAD_H #ifdef __cplusplus extern "C" { @@ -30,13 +30,12 @@ extern "C" { #define chachapoly_final torsion_chachapoly_final /* - * Structs + * Types */ typedef struct chachapoly_s { chacha20_t chacha; poly1305_t poly; - int mode; uint64_t adlen; uint64_t ctlen; } chachapoly_t; @@ -89,4 +88,4 @@ chachapoly_final(chachapoly_t *aead, unsigned char *tag); } #endif -#endif /* _TORSION_AEAD_H */ +#endif /* TORSION_AEAD_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/cipher.h b/node_modules/bcrypto/deps/torsion/include/torsion/cipher.h index 42b011581..45570705d 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/cipher.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/cipher.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_CIPHER_H -#define _TORSION_CIPHER_H +#ifndef TORSION_CIPHER_H +#define TORSION_CIPHER_H #ifdef __cplusplus extern "C" { @@ -28,11 +28,6 @@ extern "C" { #define arc2_encrypt torsion_arc2_encrypt #define arc2_decrypt torsion_arc2_decrypt #define blowfish_init torsion_blowfish_init -#define blowfish_stream2word torsion_blowfish_stream2word -#define blowfish_expand0state torsion_blowfish_expand0state -#define blowfish_expandstate torsion_blowfish_expandstate -#define blowfish_enc torsion_blowfish_enc -#define blowfish_dec torsion_blowfish_dec #define blowfish_encrypt torsion_blowfish_encrypt #define blowfish_decrypt torsion_blowfish_decrypt #define camellia_init torsion_camellia_init @@ -115,6 +110,7 @@ extern "C" { #define cipher_stream_crypt torsion_cipher_stream_crypt #define cipher_stream_update_size torsion_cipher_stream_update_size #define cipher_stream_final torsion_cipher_stream_final +#define cipher_stream_final_size torsion_cipher_stream_final_size #define cipher_static_encrypt torsion_cipher_static_encrypt #define cipher_static_decrypt torsion_cipher_static_decrypt @@ -122,54 +118,15 @@ extern "C" { * Definitions */ -#define CIPHER_AES128 0 -#define CIPHER_AES192 1 -#define CIPHER_AES256 2 -#define CIPHER_ARC2 3 -#define CIPHER_ARC2_GUTMANN 4 -#define CIPHER_ARC2_40 5 -#define CIPHER_ARC2_64 6 -#define CIPHER_ARC2_128 7 -#define CIPHER_ARC2_128_GUTMANN 8 -#define CIPHER_BLOWFISH 9 -#define CIPHER_CAMELLIA128 10 -#define CIPHER_CAMELLIA192 11 -#define CIPHER_CAMELLIA256 12 -#define CIPHER_CAST5 13 -#define CIPHER_DES 14 -#define CIPHER_DES_EDE 15 -#define CIPHER_DES_EDE3 16 -#define CIPHER_IDEA 17 -#define CIPHER_SERPENT128 18 -#define CIPHER_SERPENT192 19 -#define CIPHER_SERPENT256 20 -#define CIPHER_TWOFISH128 21 -#define CIPHER_TWOFISH192 22 -#define CIPHER_TWOFISH256 23 -#define CIPHER_MAX 23 - -#define CIPHER_MODE_RAW 0 -#define CIPHER_MODE_ECB 1 -#define CIPHER_MODE_CBC 2 -#define CIPHER_MODE_CTS 3 -#define CIPHER_MODE_XTS 4 -#define CIPHER_MODE_CTR 5 -#define CIPHER_MODE_CFB 6 -#define CIPHER_MODE_OFB 7 -#define CIPHER_MODE_GCM 8 -#define CIPHER_MODE_CCM 9 -#define CIPHER_MODE_EAX 10 -#define CIPHER_MODE_MAX 10 - #define CIPHER_MAX_BLOCK_SIZE 16 #define CIPHER_MAX_TAG_SIZE 16 -#define _CIPHER_BLOCKS(n) \ +#define CIPHER_BLOCKS(n) \ (((n) + CIPHER_MAX_BLOCK_SIZE - 1) / CIPHER_MAX_BLOCK_SIZE) /* One extra block due to ctx->last. */ #define CIPHER_MAX_UPDATE_SIZE(n) \ - ((_CIPHER_BLOCKS(n) + 1) * CIPHER_MAX_BLOCK_SIZE) + ((CIPHER_BLOCKS(n) + 1) * CIPHER_MAX_BLOCK_SIZE) /* 2 * n - 1 bytes due to XTS mode. */ #define CIPHER_MAX_FINAL_SIZE (2 * CIPHER_MAX_BLOCK_SIZE - 1) @@ -178,7 +135,56 @@ extern "C" { #define CIPHER_MAX_DECRYPT_SIZE(n) CIPHER_MAX_UPDATE_SIZE(n) /* - * Structs + * Ciphers + */ + +typedef enum cipher_id { + CIPHER_AES128, + CIPHER_AES192, + CIPHER_AES256, + CIPHER_ARC2, + CIPHER_ARC2_GUTMANN, + CIPHER_ARC2_40, + CIPHER_ARC2_64, + CIPHER_ARC2_128, + CIPHER_ARC2_128_GUTMANN, + CIPHER_BLOWFISH, + CIPHER_CAMELLIA128, + CIPHER_CAMELLIA192, + CIPHER_CAMELLIA256, + CIPHER_CAST5, + CIPHER_DES, + CIPHER_DES_EDE, + CIPHER_DES_EDE3, + CIPHER_IDEA, + CIPHER_SERPENT128, + CIPHER_SERPENT192, + CIPHER_SERPENT256, + CIPHER_TWOFISH128, + CIPHER_TWOFISH192, + CIPHER_TWOFISH256 +} cipher_id_t; + +/* + * Modes + */ + +typedef enum mode_id { + CIPHER_MODE_RAW, + CIPHER_MODE_ECB, + CIPHER_MODE_CBC, + CIPHER_MODE_CTS, + CIPHER_MODE_XTS, + CIPHER_MODE_CTR, + CIPHER_MODE_CFB, + CIPHER_MODE_OFB, + CIPHER_MODE_GCM, + CIPHER_MODE_CCM, + CIPHER_MODE_EAX +} mode_id_t; + +/* + * Types */ typedef struct aes_s { @@ -236,7 +242,7 @@ typedef struct twofish_s { } twofish_t; typedef struct cipher_s { - int type; + cipher_id_t type; size_t size; union { aes_t aes; @@ -253,83 +259,68 @@ typedef struct cipher_s { } ctx; } cipher_t; -typedef struct cbc_s { - unsigned char prev[CIPHER_MAX_BLOCK_SIZE]; -} cbc_t; - -typedef struct xts_s { +typedef struct block_mode_s { unsigned char tweak[CIPHER_MAX_BLOCK_SIZE]; unsigned char prev[CIPHER_MAX_BLOCK_SIZE]; -} xts_t; +} block_mode_t; -typedef struct ctr_s { - uint8_t ctr[CIPHER_MAX_BLOCK_SIZE]; - unsigned char state[CIPHER_MAX_BLOCK_SIZE]; - size_t pos; -} ctr_t; +/* Avoid violating ISO C section 7.1.3. */ +#define stream_mode_t xstream_mode_t -typedef struct cfb_s { +typedef struct stream_mode_s { unsigned char state[CIPHER_MAX_BLOCK_SIZE]; - unsigned char prev[CIPHER_MAX_BLOCK_SIZE]; + unsigned char iv[CIPHER_MAX_BLOCK_SIZE]; size_t pos; -} cfb_t; +} stream_mode_t; -typedef struct ofb_s { - unsigned char state[CIPHER_MAX_BLOCK_SIZE]; - size_t pos; -} ofb_t; +typedef block_mode_t cbc_t; +typedef block_mode_t xts_t; +typedef stream_mode_t ctr_t; +typedef stream_mode_t cfb_t; +typedef stream_mode_t ofb_t; -struct __ghash_fe_s { +struct ghash_fe_s { uint64_t lo; uint64_t hi; }; -struct __ghash_s { - struct __ghash_fe_s state; - struct __ghash_fe_s table[16]; +struct ghash_s { + struct ghash_fe_s state; + struct ghash_fe_s table[16]; unsigned char block[16]; uint64_t adlen; uint64_t ctlen; - size_t size; + size_t pos; }; typedef struct gcm_s { - struct __ghash_s hash; - uint8_t ctr[16]; - unsigned char state[16]; + ctr_t ctr; + struct ghash_s hash; unsigned char mask[16]; - size_t pos; } gcm_t; -struct __cmac_s { +struct cmac_s { unsigned char mac[CIPHER_MAX_BLOCK_SIZE]; size_t pos; }; typedef struct ccm_s { - struct __cmac_s hash; - unsigned char state[16]; - uint8_t ctr[16]; - size_t pos; + ctr_t ctr; + struct cmac_s hash; } ccm_t; typedef struct eax_s { - struct __cmac_s hash1; - struct __cmac_s hash2; - unsigned char state[CIPHER_MAX_BLOCK_SIZE]; + ctr_t ctr; + struct cmac_s hash1; + struct cmac_s hash2; unsigned char mask[CIPHER_MAX_BLOCK_SIZE]; - uint8_t ctr[CIPHER_MAX_BLOCK_SIZE]; - size_t pos; } eax_t; -struct __cipher_mode_s { - int type; +struct cipher_mode_s { + mode_id_t type; union { - cbc_t cbc; - xts_t xts; - ctr_t ctr; - cfb_t cfb; - ofb_t ofb; + block_mode_t block; + stream_mode_t stream; gcm_t gcm; ccm_t ccm; eax_t eax; @@ -349,7 +340,7 @@ typedef struct cipher_stream_s { unsigned char last[CIPHER_MAX_BLOCK_SIZE]; unsigned char tag[CIPHER_MAX_TAG_SIZE]; cipher_t cipher; - struct __cipher_mode_s mode; + struct cipher_mode_s mode; } cipher_stream_t; /* @@ -396,25 +387,6 @@ blowfish_init(blowfish_t *ctx, const unsigned char *key, size_t key_len, const unsigned char *salt, size_t salt_len); -TORSION_EXTERN uint32_t -blowfish_stream2word(const unsigned char *data, size_t len, size_t *off); - -TORSION_EXTERN void -blowfish_expand0state(blowfish_t *ctx, - const unsigned char *key, - size_t key_len); - -TORSION_EXTERN void -blowfish_expandstate(blowfish_t *ctx, - const unsigned char *key, size_t key_len, - const unsigned char *data, size_t data_len); - -TORSION_EXTERN void -blowfish_enc(const blowfish_t *ctx, uint32_t *data, size_t len); - -TORSION_EXTERN void -blowfish_dec(const blowfish_t *ctx, uint32_t *data, size_t len); - TORSION_EXTERN void blowfish_encrypt(const blowfish_t *ctx, unsigned char *dst, @@ -580,13 +552,16 @@ pkcs7_unpad(unsigned char *dst, */ TORSION_EXTERN size_t -cipher_key_size(int type); +cipher_key_size(cipher_id_t type); TORSION_EXTERN size_t -cipher_block_size(int type); +cipher_block_size(cipher_id_t type); TORSION_EXTERN int -cipher_init(cipher_t *ctx, int type, const unsigned char *key, size_t key_len); +cipher_init(cipher_t *ctx, + cipher_id_t type, + const unsigned char *key, + size_t key_len); TORSION_EXTERN void cipher_encrypt(const cipher_t *ctx, @@ -796,7 +771,7 @@ eax_digest(eax_t *mode, const cipher_t *cipher, unsigned char *mac); TORSION_EXTERN int cipher_stream_init(cipher_stream_t *ctx, - int type, int mode, int encrypt, + cipher_id_t type, mode_id_t mode, int encrypt, const unsigned char *key, size_t key_len, const unsigned char *iv, size_t iv_len); @@ -842,6 +817,9 @@ cipher_stream_final(cipher_stream_t *ctx, unsigned char *output, size_t *output_len); +TORSION_EXTERN size_t +cipher_stream_final_size(const cipher_stream_t *ctx); + /* * Static Encryption/Decryption */ @@ -849,8 +827,8 @@ cipher_stream_final(cipher_stream_t *ctx, TORSION_EXTERN int cipher_static_encrypt(unsigned char *ct, size_t *ct_len, - int type, - int mode, + cipher_id_t type, + mode_id_t mode, const unsigned char *key, size_t key_len, const unsigned char *iv, @@ -861,8 +839,8 @@ cipher_static_encrypt(unsigned char *ct, TORSION_EXTERN int cipher_static_decrypt(unsigned char *pt, size_t *pt_len, - int type, - int mode, + cipher_id_t type, + mode_id_t mode, const unsigned char *key, size_t key_len, const unsigned char *iv, @@ -874,4 +852,4 @@ cipher_static_decrypt(unsigned char *pt, } #endif -#endif /* _TORSION_CIPHER_H */ +#endif /* TORSION_CIPHER_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/common.h b/node_modules/bcrypto/deps/torsion/include/torsion/common.h index eb8be9d31..dfeee3a68 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/common.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/common.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_COMMON_H -#define _TORSION_COMMON_H +#ifndef TORSION_COMMON_H +#define TORSION_COMMON_H #ifdef TORSION_BUILD # if defined(__EMSCRIPTEN__) @@ -13,11 +13,12 @@ # define TORSION_EXTERN EMSCRIPTEN_KEEPALIVE # elif defined(__wasm__) # define TORSION_EXTERN __attribute__((visibility("default"))) -# elif defined(_MSC_VER) || defined(__BORLANDC__) +# elif defined(_WIN32) # define TORSION_EXTERN __declspec(dllexport) # elif defined(__GNUC__) && __GNUC__ >= 4 # define TORSION_EXTERN __attribute__((visibility("default"))) -# elif defined(__SUNPRO_C) && __SUNPRO_C >= 0x550 +# elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x550) \ + || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x550) # define TORSION_EXTERN __global # endif #endif @@ -26,4 +27,4 @@ # define TORSION_EXTERN #endif -#endif /* _TORSION_COMMON_H */ +#endif /* TORSION_COMMON_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/drbg.h b/node_modules/bcrypto/deps/torsion/include/torsion/drbg.h index 802e86946..541949d74 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/drbg.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/drbg.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_DRBG_H -#define _TORSION_DRBG_H +#ifndef TORSION_DRBG_H +#define TORSION_DRBG_H #ifdef __cplusplus extern "C" { @@ -23,24 +23,24 @@ extern "C" { #define hmac_drbg_init torsion_hmac_drbg_init #define hmac_drbg_reseed torsion_hmac_drbg_reseed #define hmac_drbg_generate torsion_hmac_drbg_generate -#define hmac_drbg_rng __torsion_hmac_drbg_rng +#define hmac_drbg_rng torsion__hmac_drbg_rng #define hash_drbg_init torsion_hash_drbg_init #define hash_drbg_reseed torsion_hash_drbg_reseed #define hash_drbg_generate torsion_hash_drbg_generate -#define hash_drbg_rng __torsion_hash_drbg_rng +#define hash_drbg_rng torsion__hash_drbg_rng #define ctr_drbg_init torsion_ctr_drbg_init #define ctr_drbg_reseed torsion_ctr_drbg_reseed #define ctr_drbg_generate torsion_ctr_drbg_generate -#define ctr_drbg_rng __torsion_ctr_drbg_rng +#define ctr_drbg_rng torsion__ctr_drbg_rng /* - * Structs + * Types */ typedef struct hmac_drbg_s { - int type; + hash_id_t type; size_t size; hmac_t kmac; unsigned char K[HASH_MAX_OUTPUT_SIZE]; @@ -48,7 +48,7 @@ typedef struct hmac_drbg_s { } hmac_drbg_t; typedef struct hash_drbg_s { - int type; + hash_id_t type; hash_t hash; size_t size; size_t length; @@ -87,7 +87,7 @@ typedef hmac_drbg_t drbg_t; TORSION_EXTERN void hmac_drbg_init(hmac_drbg_t *drbg, - int type, + hash_id_t type, const unsigned char *seed, size_t seed_len); @@ -107,7 +107,7 @@ hmac_drbg_rng(void *out, size_t size, void *arg); TORSION_EXTERN void hash_drbg_init(hash_drbg_t *drbg, - int type, + hash_id_t type, const unsigned char *seed, size_t seed_len); @@ -160,4 +160,4 @@ ctr_drbg_rng(void *out, size_t size, void *arg); } #endif -#endif /* _TORSION_DRBG_H */ +#endif /* TORSION_DRBG_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/dsa.h b/node_modules/bcrypto/deps/torsion/include/torsion/dsa.h index 6e169b255..8950b7422 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/dsa.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/dsa.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_DSA_H -#define _TORSION_DSA_H +#ifndef TORSION_DSA_H +#define TORSION_DSA_H #ifdef __cplusplus extern "C" { @@ -45,7 +45,7 @@ extern "C" { #define dsa_derive torsion_dsa_derive /* - * Defs + * Definitions */ #define DSA_DEFAULT_BITS 2048 @@ -204,4 +204,4 @@ dsa_derive(unsigned char *out, size_t *out_len, } #endif -#endif /* _TORSION_DSA_H */ +#endif /* TORSION_DSA_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/ecc.h b/node_modules/bcrypto/deps/torsion/include/torsion/ecc.h index 0753836fb..2d1d93486 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/ecc.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/ecc.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_ECC_H -#define _TORSION_ECC_H +#ifndef TORSION_ECC_H +#define TORSION_ECC_H #ifdef __cplusplus extern "C" { @@ -81,40 +81,40 @@ extern "C" { #define ecdsa_recover torsion_ecdsa_recover #define ecdsa_derive torsion_ecdsa_derive -#define schnorr_legacy_support torsion_schnorr_legacy_support -#define schnorr_legacy_sig_size torsion_schnorr_legacy_sig_size -#define schnorr_legacy_sign torsion_schnorr_legacy_sign -#define schnorr_legacy_verify torsion_schnorr_legacy_verify -#define schnorr_legacy_verify_batch torsion_schnorr_legacy_verify_batch - -#define schnorr_privkey_size torsion_schnorr_privkey_size -#define schnorr_pubkey_size torsion_schnorr_pubkey_size -#define schnorr_sig_size torsion_schnorr_sig_size -#define schnorr_privkey_generate torsion_schnorr_privkey_generate -#define schnorr_privkey_verify torsion_schnorr_privkey_verify -#define schnorr_privkey_export torsion_schnorr_privkey_export -#define schnorr_privkey_import torsion_schnorr_privkey_import -#define schnorr_privkey_tweak_add torsion_schnorr_privkey_tweak_add -#define schnorr_privkey_tweak_mul torsion_schnorr_privkey_tweak_mul -#define schnorr_privkey_invert torsion_schnorr_privkey_invert -#define schnorr_pubkey_create torsion_schnorr_pubkey_create -#define schnorr_pubkey_from_uniform torsion_schnorr_pubkey_from_uniform -#define schnorr_pubkey_to_uniform torsion_schnorr_pubkey_to_uniform -#define schnorr_pubkey_from_hash torsion_schnorr_pubkey_from_hash -#define schnorr_pubkey_to_hash torsion_schnorr_pubkey_to_hash -#define schnorr_pubkey_verify torsion_schnorr_pubkey_verify -#define schnorr_pubkey_export torsion_schnorr_pubkey_export -#define schnorr_pubkey_import torsion_schnorr_pubkey_import -#define schnorr_pubkey_tweak_add torsion_schnorr_pubkey_tweak_add -#define schnorr_pubkey_tweak_add_check torsion_schnorr_pubkey_tweak_add_check -#define schnorr_pubkey_tweak_mul torsion_schnorr_pubkey_tweak_mul -#define schnorr_pubkey_tweak_mul_check torsion_schnorr_pubkey_tweak_mul_check -#define schnorr_pubkey_add torsion_schnorr_pubkey_add -#define schnorr_pubkey_combine torsion_schnorr_pubkey_combine -#define schnorr_sign torsion_schnorr_sign -#define schnorr_verify torsion_schnorr_verify -#define schnorr_verify_batch torsion_schnorr_verify_batch -#define schnorr_derive torsion_schnorr_derive +#define bipschnorr_support torsion_bipschnorr_support +#define bipschnorr_sig_size torsion_bipschnorr_sig_size +#define bipschnorr_sign torsion_bipschnorr_sign +#define bipschnorr_verify torsion_bipschnorr_verify +#define bipschnorr_verify_batch torsion_bipschnorr_verify_batch + +#define bip340_privkey_size torsion_bip340_privkey_size +#define bip340_pubkey_size torsion_bip340_pubkey_size +#define bip340_sig_size torsion_bip340_sig_size +#define bip340_privkey_generate torsion_bip340_privkey_generate +#define bip340_privkey_verify torsion_bip340_privkey_verify +#define bip340_privkey_export torsion_bip340_privkey_export +#define bip340_privkey_import torsion_bip340_privkey_import +#define bip340_privkey_tweak_add torsion_bip340_privkey_tweak_add +#define bip340_privkey_tweak_mul torsion_bip340_privkey_tweak_mul +#define bip340_privkey_invert torsion_bip340_privkey_invert +#define bip340_pubkey_create torsion_bip340_pubkey_create +#define bip340_pubkey_from_uniform torsion_bip340_pubkey_from_uniform +#define bip340_pubkey_to_uniform torsion_bip340_pubkey_to_uniform +#define bip340_pubkey_from_hash torsion_bip340_pubkey_from_hash +#define bip340_pubkey_to_hash torsion_bip340_pubkey_to_hash +#define bip340_pubkey_verify torsion_bip340_pubkey_verify +#define bip340_pubkey_export torsion_bip340_pubkey_export +#define bip340_pubkey_import torsion_bip340_pubkey_import +#define bip340_pubkey_tweak_add torsion_bip340_pubkey_tweak_add +#define bip340_pubkey_tweak_add_check torsion_bip340_pubkey_tweak_add_check +#define bip340_pubkey_tweak_mul torsion_bip340_pubkey_tweak_mul +#define bip340_pubkey_tweak_mul_check torsion_bip340_pubkey_tweak_mul_check +#define bip340_pubkey_add torsion_bip340_pubkey_add +#define bip340_pubkey_combine torsion_bip340_pubkey_combine +#define bip340_sign torsion_bip340_sign +#define bip340_verify torsion_bip340_verify +#define bip340_verify_batch torsion_bip340_verify_batch +#define bip340_derive torsion_bip340_derive #define ecdh_privkey_size torsion_ecdh_privkey_size #define ecdh_pubkey_size torsion_ecdh_pubkey_size @@ -207,11 +207,11 @@ extern "C" { #define ristretto_pubkey_negate torsion_ristretto_pubkey_negate #define ristretto_derive torsion_ristretto_derive -#define test_ecc_internal __torsion_test_ecc_internal +#define test_ecc_internal torsion__test_ecc_internal /* - * Defs + * Definitions */ #define WEI_MAX_FIELD_SIZE 66 @@ -228,14 +228,14 @@ extern "C" { #define ECDSA_MAX_SIG_SIZE (WEI_MAX_SCALAR_SIZE * 2) /* 132 */ #define ECDSA_MAX_DER_SIZE (9 + ECDSA_MAX_SIG_SIZE) /* 141 */ -#define SCHNORR_LEGACY_MAX_PRIV_SIZE ECDSA_MAX_PRIV_SIZE -#define SCHNORR_LEGACY_MAX_PUB_SIZE ECDSA_MAX_PUB_SIZE -#define SCHNORR_LEGACY_MAX_SIG_SIZE \ +#define BIPSCHNORR_MAX_PRIV_SIZE ECDSA_MAX_PRIV_SIZE +#define BIPSCHNORR_MAX_PUB_SIZE ECDSA_MAX_PUB_SIZE +#define BIPSCHNORR_MAX_SIG_SIZE \ (WEI_MAX_FIELD_SIZE + WEI_MAX_SCALAR_SIZE) /* 132 */ -#define SCHNORR_MAX_PRIV_SIZE WEI_MAX_SCALAR_SIZE /* 66 */ -#define SCHNORR_MAX_PUB_SIZE WEI_MAX_FIELD_SIZE /* 66 */ -#define SCHNORR_MAX_SIG_SIZE \ +#define BIP340_MAX_PRIV_SIZE WEI_MAX_SCALAR_SIZE /* 66 */ +#define BIP340_MAX_PUB_SIZE WEI_MAX_FIELD_SIZE /* 66 */ +#define BIP340_MAX_SIG_SIZE \ (WEI_MAX_FIELD_SIZE + WEI_MAX_SCALAR_SIZE) /* 132 */ #define ECDH_MAX_PRIV_SIZE MONT_MAX_SCALAR_SIZE /* 56 */ @@ -253,22 +253,25 @@ extern "C" { * Curves */ -#define WEI_CURVE_P192 0 -#define WEI_CURVE_P224 1 -#define WEI_CURVE_P256 2 -#define WEI_CURVE_P384 3 -#define WEI_CURVE_P521 4 -#define WEI_CURVE_SECP256K1 5 -#define WEI_CURVE_MAX 5 - -#define MONT_CURVE_X25519 0 -#define MONT_CURVE_X448 1 -#define MONT_CURVE_MAX 1 - -#define EDWARDS_CURVE_ED25519 0 -#define EDWARDS_CURVE_ED448 1 -#define EDWARDS_CURVE_ED1174 2 -#define EDWARDS_CURVE_MAX 2 +typedef enum wei_curve_id { + WEI_CURVE_P192, + WEI_CURVE_P224, + WEI_CURVE_P256, + WEI_CURVE_P384, + WEI_CURVE_P521, + WEI_CURVE_SECP256K1 +} wei_curve_id_t; + +typedef enum mont_curve_id { + MONT_CURVE_X25519, + MONT_CURVE_X448 +} mont_curve_id_t; + +typedef enum edwards_curve_id { + EDWARDS_CURVE_ED25519, + EDWARDS_CURVE_ED448, + EDWARDS_CURVE_ED1174 +} edwards_curve_id_t; /* * Types @@ -287,7 +290,7 @@ typedef void ecdsa_redefine_f(void *, size_t); */ TORSION_EXTERN wei_curve_t * -wei_curve_create(int type); +wei_curve_create(wei_curve_id_t type); TORSION_EXTERN void wei_curve_destroy(wei_curve_t *ec); @@ -318,7 +321,7 @@ wei_scratch_destroy(const wei_curve_t *ec, wei_scratch_t *scratch); */ TORSION_EXTERN mont_curve_t * -mont_curve_create(int type); +mont_curve_create(mont_curve_id_t type); TORSION_EXTERN void mont_curve_destroy(mont_curve_t *ec); @@ -340,7 +343,7 @@ mont_curve_field_bits(const mont_curve_t *ec); */ TORSION_EXTERN edwards_curve_t * -edwards_curve_create(int type); +edwards_curve_create(edwards_curve_id_t type); TORSION_EXTERN void edwards_curve_destroy(edwards_curve_t *ec); @@ -603,233 +606,233 @@ ecdsa_derive(const wei_curve_t *ec, int compact); /* - * Schnorr Legacy + * BIP-Schnorr */ TORSION_EXTERN int -schnorr_legacy_support(const wei_curve_t *ec); +bipschnorr_support(const wei_curve_t *ec); -#define schnorr_legacy_privkey_size ecdsa_privkey_size -#define schnorr_legacy_pubkey_size ecdsa_pubkey_size +#define bipschnorr_privkey_size ecdsa_privkey_size +#define bipschnorr_pubkey_size ecdsa_pubkey_size TORSION_EXTERN size_t -schnorr_legacy_sig_size(const wei_curve_t *ec); - -#define schnorr_legacy_privkey_generate ecdsa_privkey_generate -#define schnorr_legacy_privkey_verify ecdsa_privkey_verify -#define schnorr_legacy_privkey_export ecdsa_privkey_export -#define schnorr_legacy_privkey_import ecdsa_privkey_import -#define schnorr_legacy_privkey_tweak_add ecdsa_privkey_tweak_add -#define schnorr_legacy_privkey_tweak_mul ecdsa_privkey_tweak_mul -#define schnorr_legacy_privkey_negate ecdsa_privkey_negate -#define schnorr_legacy_privkey_invert ecdsa_privkey_invert -#define schnorr_legacy_pubkey_create ecdsa_pubkey_create -#define schnorr_legacy_pubkey_convert ecdsa_pubkey_convert -#define schnorr_legacy_pubkey_from_uniform ecdsa_pubkey_from_uniform -#define schnorr_legacy_pubkey_to_uniform ecdsa_pubkey_to_uniform -#define schnorr_legacy_pubkey_from_hash ecdsa_pubkey_from_hash -#define schnorr_legacy_pubkey_to_hash ecdsa_pubkey_to_hash -#define schnorr_legacy_pubkey_verify ecdsa_pubkey_verify -#define schnorr_legacy_pubkey_export ecdsa_pubkey_export -#define schnorr_legacy_pubkey_import ecdsa_pubkey_import -#define schnorr_legacy_pubkey_tweak_add ecdsa_pubkey_tweak_add -#define schnorr_legacy_pubkey_tweak_mul ecdsa_pubkey_tweak_mul -#define schnorr_legacy_pubkey_add ecdsa_pubkey_add -#define schnorr_legacy_pubkey_combine ecdsa_pubkey_combine -#define schnorr_legacy_pubkey_negate ecdsa_pubkey_negate - -TORSION_EXTERN int -schnorr_legacy_sign(const wei_curve_t *ec, - unsigned char *sig, - const unsigned char *msg, - size_t msg_len, - const unsigned char *priv); - -TORSION_EXTERN int -schnorr_legacy_verify(const wei_curve_t *ec, - const unsigned char *msg, - size_t msg_len, - const unsigned char *sig, - const unsigned char *pub, - size_t pub_len); - -TORSION_EXTERN int -schnorr_legacy_verify_batch(const wei_curve_t *ec, - const unsigned char *const *msgs, - const size_t *msg_lens, - const unsigned char *const *sigs, - const unsigned char *const *pubs, - const size_t *pub_lens, - size_t len, - wei_scratch_t *scratch); - -#define schnorr_legacy_derive ecdsa_derive +bipschnorr_sig_size(const wei_curve_t *ec); + +#define bipschnorr_privkey_generate ecdsa_privkey_generate +#define bipschnorr_privkey_verify ecdsa_privkey_verify +#define bipschnorr_privkey_export ecdsa_privkey_export +#define bipschnorr_privkey_import ecdsa_privkey_import +#define bipschnorr_privkey_tweak_add ecdsa_privkey_tweak_add +#define bipschnorr_privkey_tweak_mul ecdsa_privkey_tweak_mul +#define bipschnorr_privkey_negate ecdsa_privkey_negate +#define bipschnorr_privkey_invert ecdsa_privkey_invert +#define bipschnorr_pubkey_create ecdsa_pubkey_create +#define bipschnorr_pubkey_convert ecdsa_pubkey_convert +#define bipschnorr_pubkey_from_uniform ecdsa_pubkey_from_uniform +#define bipschnorr_pubkey_to_uniform ecdsa_pubkey_to_uniform +#define bipschnorr_pubkey_from_hash ecdsa_pubkey_from_hash +#define bipschnorr_pubkey_to_hash ecdsa_pubkey_to_hash +#define bipschnorr_pubkey_verify ecdsa_pubkey_verify +#define bipschnorr_pubkey_export ecdsa_pubkey_export +#define bipschnorr_pubkey_import ecdsa_pubkey_import +#define bipschnorr_pubkey_tweak_add ecdsa_pubkey_tweak_add +#define bipschnorr_pubkey_tweak_mul ecdsa_pubkey_tweak_mul +#define bipschnorr_pubkey_add ecdsa_pubkey_add +#define bipschnorr_pubkey_combine ecdsa_pubkey_combine +#define bipschnorr_pubkey_negate ecdsa_pubkey_negate + +TORSION_EXTERN int +bipschnorr_sign(const wei_curve_t *ec, + unsigned char *sig, + const unsigned char *msg, + size_t msg_len, + const unsigned char *priv); + +TORSION_EXTERN int +bipschnorr_verify(const wei_curve_t *ec, + const unsigned char *msg, + size_t msg_len, + const unsigned char *sig, + const unsigned char *pub, + size_t pub_len); + +TORSION_EXTERN int +bipschnorr_verify_batch(const wei_curve_t *ec, + const unsigned char *const *msgs, + const size_t *msg_lens, + const unsigned char *const *sigs, + const unsigned char *const *pubs, + const size_t *pub_lens, + size_t len, + wei_scratch_t *scratch); + +#define bipschnorr_derive ecdsa_derive /* - * Schnorr + * BIP340 */ TORSION_EXTERN size_t -schnorr_privkey_size(const wei_curve_t *ec); +bip340_privkey_size(const wei_curve_t *ec); TORSION_EXTERN size_t -schnorr_pubkey_size(const wei_curve_t *ec); +bip340_pubkey_size(const wei_curve_t *ec); TORSION_EXTERN size_t -schnorr_sig_size(const wei_curve_t *ec); +bip340_sig_size(const wei_curve_t *ec); TORSION_EXTERN void -schnorr_privkey_generate(const wei_curve_t *ec, - unsigned char *out, - const unsigned char *entropy); +bip340_privkey_generate(const wei_curve_t *ec, + unsigned char *out, + const unsigned char *entropy); TORSION_EXTERN int -schnorr_privkey_verify(const wei_curve_t *ec, const unsigned char *priv); +bip340_privkey_verify(const wei_curve_t *ec, const unsigned char *priv); TORSION_EXTERN int -schnorr_privkey_export(const wei_curve_t *ec, - unsigned char *d_raw, - unsigned char *x_raw, - unsigned char *y_raw, - const unsigned char *priv); +bip340_privkey_export(const wei_curve_t *ec, + unsigned char *d_raw, + unsigned char *x_raw, + unsigned char *y_raw, + const unsigned char *priv); TORSION_EXTERN int -schnorr_privkey_import(const wei_curve_t *ec, - unsigned char *out, - const unsigned char *bytes, - size_t len); +bip340_privkey_import(const wei_curve_t *ec, + unsigned char *out, + const unsigned char *bytes, + size_t len); TORSION_EXTERN int -schnorr_privkey_tweak_add(const wei_curve_t *ec, - unsigned char *out, - const unsigned char *priv, - const unsigned char *tweak); +bip340_privkey_tweak_add(const wei_curve_t *ec, + unsigned char *out, + const unsigned char *priv, + const unsigned char *tweak); TORSION_EXTERN int -schnorr_privkey_tweak_mul(const wei_curve_t *ec, - unsigned char *out, - const unsigned char *priv, - const unsigned char *tweak); +bip340_privkey_tweak_mul(const wei_curve_t *ec, + unsigned char *out, + const unsigned char *priv, + const unsigned char *tweak); TORSION_EXTERN int -schnorr_privkey_invert(const wei_curve_t *ec, - unsigned char *out, - const unsigned char *priv); +bip340_privkey_invert(const wei_curve_t *ec, + unsigned char *out, + const unsigned char *priv); TORSION_EXTERN int -schnorr_pubkey_create(const wei_curve_t *ec, - unsigned char *pub, - const unsigned char *priv); +bip340_pubkey_create(const wei_curve_t *ec, + unsigned char *pub, + const unsigned char *priv); TORSION_EXTERN void -schnorr_pubkey_from_uniform(const wei_curve_t *ec, - unsigned char *out, - const unsigned char *bytes); +bip340_pubkey_from_uniform(const wei_curve_t *ec, + unsigned char *out, + const unsigned char *bytes); TORSION_EXTERN int -schnorr_pubkey_to_uniform(const wei_curve_t *ec, - unsigned char *out, - const unsigned char *pub, - unsigned int hint); +bip340_pubkey_to_uniform(const wei_curve_t *ec, + unsigned char *out, + const unsigned char *pub, + unsigned int hint); TORSION_EXTERN int -schnorr_pubkey_from_hash(const wei_curve_t *ec, - unsigned char *out, - const unsigned char *bytes); +bip340_pubkey_from_hash(const wei_curve_t *ec, + unsigned char *out, + const unsigned char *bytes); TORSION_EXTERN int -schnorr_pubkey_to_hash(const wei_curve_t *ec, - unsigned char *out, - const unsigned char *pub, - unsigned int subgroup, - const unsigned char *entropy); +bip340_pubkey_to_hash(const wei_curve_t *ec, + unsigned char *out, + const unsigned char *pub, + unsigned int subgroup, + const unsigned char *entropy); TORSION_EXTERN int -schnorr_pubkey_verify(const wei_curve_t *ec, const unsigned char *pub); +bip340_pubkey_verify(const wei_curve_t *ec, const unsigned char *pub); TORSION_EXTERN int -schnorr_pubkey_export(const wei_curve_t *ec, - unsigned char *x_raw, - unsigned char *y_raw, - const unsigned char *pub); +bip340_pubkey_export(const wei_curve_t *ec, + unsigned char *x_raw, + unsigned char *y_raw, + const unsigned char *pub); TORSION_EXTERN int -schnorr_pubkey_import(const wei_curve_t *ec, - unsigned char *out, - const unsigned char *x_raw, - size_t x_len, - const unsigned char *y_raw, - size_t y_len); +bip340_pubkey_import(const wei_curve_t *ec, + unsigned char *out, + const unsigned char *x_raw, + size_t x_len, + const unsigned char *y_raw, + size_t y_len); TORSION_EXTERN int -schnorr_pubkey_tweak_add(const wei_curve_t *ec, - unsigned char *out, - int *negated, - const unsigned char *pub, - const unsigned char *tweak); +bip340_pubkey_tweak_add(const wei_curve_t *ec, + unsigned char *out, + int *negated, + const unsigned char *pub, + const unsigned char *tweak); TORSION_EXTERN int -schnorr_pubkey_tweak_add_check(const wei_curve_t *ec, - const unsigned char *pub, - const unsigned char *tweak, - const unsigned char *expect, - int negated); +bip340_pubkey_tweak_add_check(const wei_curve_t *ec, + const unsigned char *pub, + const unsigned char *tweak, + const unsigned char *expect, + int negated); TORSION_EXTERN int -schnorr_pubkey_tweak_mul(const wei_curve_t *ec, - unsigned char *out, - int *negated, - const unsigned char *pub, - const unsigned char *tweak); +bip340_pubkey_tweak_mul(const wei_curve_t *ec, + unsigned char *out, + int *negated, + const unsigned char *pub, + const unsigned char *tweak); TORSION_EXTERN int -schnorr_pubkey_tweak_mul_check(const wei_curve_t *ec, - const unsigned char *pub, - const unsigned char *tweak, - const unsigned char *expect, - int negated); +bip340_pubkey_tweak_mul_check(const wei_curve_t *ec, + const unsigned char *pub, + const unsigned char *tweak, + const unsigned char *expect, + int negated); TORSION_EXTERN int -schnorr_pubkey_add(const wei_curve_t *ec, - unsigned char *out, - const unsigned char *pub1, - const unsigned char *pub2); +bip340_pubkey_add(const wei_curve_t *ec, + unsigned char *out, + const unsigned char *pub1, + const unsigned char *pub2); TORSION_EXTERN int -schnorr_pubkey_combine(const wei_curve_t *ec, - unsigned char *out, - const unsigned char *const *pubs, - size_t len); +bip340_pubkey_combine(const wei_curve_t *ec, + unsigned char *out, + const unsigned char *const *pubs, + size_t len); TORSION_EXTERN int -schnorr_sign(const wei_curve_t *ec, - unsigned char *sig, - const unsigned char *msg, - size_t msg_len, - const unsigned char *priv, - const unsigned char *aux); +bip340_sign(const wei_curve_t *ec, + unsigned char *sig, + const unsigned char *msg, + size_t msg_len, + const unsigned char *priv, + const unsigned char *aux); TORSION_EXTERN int -schnorr_verify(const wei_curve_t *ec, - const unsigned char *msg, - size_t msg_len, - const unsigned char *sig, - const unsigned char *pub); +bip340_verify(const wei_curve_t *ec, + const unsigned char *msg, + size_t msg_len, + const unsigned char *sig, + const unsigned char *pub); TORSION_EXTERN int -schnorr_verify_batch(const wei_curve_t *ec, - const unsigned char *const *msgs, - const size_t *msg_lens, - const unsigned char *const *sigs, - const unsigned char *const *pubs, - size_t len, - wei_scratch_t *scratch); +bip340_verify_batch(const wei_curve_t *ec, + const unsigned char *const *msgs, + const size_t *msg_lens, + const unsigned char *const *sigs, + const unsigned char *const *pubs, + size_t len, + wei_scratch_t *scratch); TORSION_EXTERN int -schnorr_derive(const wei_curve_t *ec, - unsigned char *secret, - const unsigned char *pub, - const unsigned char *priv); +bip340_derive(const wei_curve_t *ec, + unsigned char *secret, + const unsigned char *pub, + const unsigned char *priv); /* * ECDH @@ -1334,4 +1337,4 @@ test_ecc_internal(struct hmac_drbg_s *rng); } #endif -#endif /* _TORSION_ECC_H */ +#endif /* TORSION_ECC_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/encoding.h b/node_modules/bcrypto/deps/torsion/include/torsion/encoding.h index b03c620fc..681775ec8 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/encoding.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/encoding.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_ENCODING_H -#define _TORSION_ENCODING_H +#ifndef TORSION_ENCODING_H +#define TORSION_ENCODING_H #ifdef __cplusplus extern "C" { @@ -254,16 +254,18 @@ TORSION_EXTERN int bech32_serialize(char *str, const char *hrp, const uint8_t *data, - size_t data_len); + size_t data_len, + uint32_t checksum); TORSION_EXTERN int bech32_deserialize(char *hrp, uint8_t *data, size_t *data_len, - const char *str); + const char *str, + uint32_t checksum); TORSION_EXTERN int -bech32_is(const char *str); +bech32_is(const char *str, uint32_t checksum); TORSION_EXTERN int bech32_convert_bits(uint8_t *dst, @@ -279,17 +281,19 @@ bech32_encode(char *addr, const char *hrp, unsigned int version, const uint8_t *hash, - size_t hash_len); + size_t hash_len, + uint32_t checksum); TORSION_EXTERN int bech32_decode(char *hrp, unsigned int *version, uint8_t *hash, size_t *hash_len, - const char *addr); + const char *addr, + uint32_t checksum); TORSION_EXTERN int -bech32_test(const char *addr); +bech32_test(const char *addr, uint32_t checksum); /* * Cash32 @@ -358,4 +362,4 @@ cash32_test(const char *addr, const char *expect); } #endif -#endif /* _TORSION_ENCODING_H */ +#endif /* TORSION_ENCODING_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/hash.h b/node_modules/bcrypto/deps/torsion/include/torsion/hash.h index fbe64187c..1dd7be7b0 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/hash.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/hash.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_HASH_H -#define _TORSION_HASH_H +#ifndef TORSION_HASH_H +#define TORSION_HASH_H #ifdef __cplusplus extern "C" { @@ -135,48 +135,54 @@ extern "C" { #define hmac_final torsion_hmac_final /* - * Defs + * Definitions */ #define HASH_MAX_OUTPUT_SIZE 64 #define HASH_MAX_BLOCK_SIZE 168 -#define HASH_BLAKE2B_160 0 -#define HASH_BLAKE2B_256 1 -#define HASH_BLAKE2B_384 2 -#define HASH_BLAKE2B_512 3 -#define HASH_BLAKE2S_128 4 -#define HASH_BLAKE2S_160 5 -#define HASH_BLAKE2S_224 6 -#define HASH_BLAKE2S_256 7 -#define HASH_GOST94 8 -#define HASH_HASH160 9 -#define HASH_HASH256 10 -#define HASH_KECCAK224 11 -#define HASH_KECCAK256 12 -#define HASH_KECCAK384 13 -#define HASH_KECCAK512 14 -#define HASH_MD2 15 -#define HASH_MD4 16 -#define HASH_MD5 17 -#define HASH_MD5SHA1 18 -#define HASH_RIPEMD160 19 -#define HASH_SHA1 20 -#define HASH_SHA224 21 -#define HASH_SHA256 22 -#define HASH_SHA384 23 -#define HASH_SHA512 24 -#define HASH_SHA3_224 25 -#define HASH_SHA3_256 26 -#define HASH_SHA3_384 27 -#define HASH_SHA3_512 28 -#define HASH_SHAKE128 29 -#define HASH_SHAKE256 30 -#define HASH_WHIRLPOOL 31 -#define HASH_MAX 31 +/* + * Hashes + */ + +typedef enum hash_id { + HASH_NONE, + HASH_BLAKE2B_160, + HASH_BLAKE2B_256, + HASH_BLAKE2B_384, + HASH_BLAKE2B_512, + HASH_BLAKE2S_128, + HASH_BLAKE2S_160, + HASH_BLAKE2S_224, + HASH_BLAKE2S_256, + HASH_GOST94, + HASH_HASH160, + HASH_HASH256, + HASH_KECCAK224, + HASH_KECCAK256, + HASH_KECCAK384, + HASH_KECCAK512, + HASH_MD2, + HASH_MD4, + HASH_MD5, + HASH_MD5SHA1, + HASH_RIPEMD160, + HASH_SHA1, + HASH_SHA224, + HASH_SHA256, + HASH_SHA384, + HASH_SHA512, + HASH_SHA3_224, + HASH_SHA3_256, + HASH_SHA3_384, + HASH_SHA3_512, + HASH_SHAKE128, + HASH_SHAKE256, + HASH_WHIRLPOOL +} hash_id_t; /* - * Structs + * Types */ typedef struct blake2b_s { @@ -199,7 +205,7 @@ typedef struct gost94_s { uint8_t state[32]; uint8_t sigma[32]; unsigned char block[32]; - uint64_t size; + uint64_t size[4]; } gost94_t; typedef struct keccak_s { @@ -249,13 +255,13 @@ typedef struct sha256_s { typedef struct sha512_s { uint64_t state[8]; unsigned char block[128]; - uint64_t size; + uint64_t size[2]; } sha512_t; typedef struct whirlpool_s { uint64_t state[8]; unsigned char block[64]; - uint64_t size; + uint64_t size[4]; } whirlpool_t; typedef md5_t md4_t; @@ -266,7 +272,7 @@ typedef sha256_t hash256_t; typedef keccak_t sha3_t; typedef struct hash_s { - int type; + hash_id_t type; union { blake2b_t blake2b; blake2s_t blake2s; @@ -284,7 +290,7 @@ typedef struct hash_s { } hash_t; typedef struct hmac_s { - int type; + hash_id_t type; hash_t inner; hash_t outer; } hmac_t; @@ -309,7 +315,7 @@ blake2b_final(blake2b_t *ctx, unsigned char *out); * BLAKE2b-{160,256,384,512} */ -#define __TORSION_DEFINE_BLAKE2(name, bits) \ +#define TORSION__DEFINE_BLAKE2(name, bits) \ TORSION_EXTERN void \ torsion_##name##bits##_init(name##_t *ctx, \ const unsigned char *key, size_t keylen); \ @@ -321,10 +327,10 @@ torsion_##name##bits##_update(name##_t *ctx, \ TORSION_EXTERN void \ torsion_##name##bits##_final(name##_t *ctx, unsigned char *out); -__TORSION_DEFINE_BLAKE2(blake2b, 160) -__TORSION_DEFINE_BLAKE2(blake2b, 256) -__TORSION_DEFINE_BLAKE2(blake2b, 384) -__TORSION_DEFINE_BLAKE2(blake2b, 512) +TORSION__DEFINE_BLAKE2(blake2b, 160) +TORSION__DEFINE_BLAKE2(blake2b, 256) +TORSION__DEFINE_BLAKE2(blake2b, 384) +TORSION__DEFINE_BLAKE2(blake2b, 512) /* * BLAKE2s @@ -346,10 +352,10 @@ blake2s_final(blake2s_t *ctx, unsigned char *out); * BLAKE2s-{128,160,224,256} */ -__TORSION_DEFINE_BLAKE2(blake2s, 128) -__TORSION_DEFINE_BLAKE2(blake2s, 160) -__TORSION_DEFINE_BLAKE2(blake2s, 224) -__TORSION_DEFINE_BLAKE2(blake2s, 256) +TORSION__DEFINE_BLAKE2(blake2s, 128) +TORSION__DEFINE_BLAKE2(blake2s, 160) +TORSION__DEFINE_BLAKE2(blake2s, 224) +TORSION__DEFINE_BLAKE2(blake2s, 256) /* * GOST94 @@ -407,7 +413,7 @@ keccak_final(keccak_t *ctx, unsigned char *out, unsigned int pad, size_t len); * Keccak{224,256,384,512} */ -#define __TORSION_DEFINE_KECCAK(name) \ +#define TORSION__DEFINE_KECCAK(name) \ TORSION_EXTERN void \ torsion_##name##_init(sha3_t *ctx); \ \ @@ -417,10 +423,10 @@ torsion_##name##_update(sha3_t *ctx, const void *data, size_t len); \ TORSION_EXTERN void \ torsion_##name##_final(sha3_t *ctx, unsigned char *out); -__TORSION_DEFINE_KECCAK(keccak224) -__TORSION_DEFINE_KECCAK(keccak256) -__TORSION_DEFINE_KECCAK(keccak384) -__TORSION_DEFINE_KECCAK(keccak512) +TORSION__DEFINE_KECCAK(keccak224) +TORSION__DEFINE_KECCAK(keccak256) +TORSION__DEFINE_KECCAK(keccak384) +TORSION__DEFINE_KECCAK(keccak512) /* * MD2 @@ -556,16 +562,16 @@ sha512_final(sha512_t *ctx, unsigned char *out); * SHA3-{224,256,384,512} */ -__TORSION_DEFINE_KECCAK(sha3_224) -__TORSION_DEFINE_KECCAK(sha3_256) -__TORSION_DEFINE_KECCAK(sha3_384) -__TORSION_DEFINE_KECCAK(sha3_512) +TORSION__DEFINE_KECCAK(sha3_224) +TORSION__DEFINE_KECCAK(sha3_256) +TORSION__DEFINE_KECCAK(sha3_384) +TORSION__DEFINE_KECCAK(sha3_512) /* * SHAKE{128,256} */ -#define __TORSION_DEFINE_SHAKE(name) \ +#define TORSION__DEFINE_SHAKE(name) \ TORSION_EXTERN void \ torsion_##name##_init(sha3_t *ctx); \ \ @@ -575,8 +581,8 @@ torsion_##name##_update(sha3_t *ctx, const void *data, size_t len); \ TORSION_EXTERN void \ torsion_##name##_final(sha3_t *ctx, unsigned char *out, size_t len); -__TORSION_DEFINE_SHAKE(shake224) -__TORSION_DEFINE_SHAKE(shake256) +TORSION__DEFINE_SHAKE(shake128) +TORSION__DEFINE_SHAKE(shake256) /* * Whirlpool @@ -596,7 +602,7 @@ whirlpool_final(whirlpool_t *ctx, unsigned char *out); */ TORSION_EXTERN void -hash_init(hash_t *hash, int type); +hash_init(hash_t *hash, hash_id_t type); TORSION_EXTERN void hash_update(hash_t *hash, const void *data, size_t len); @@ -605,20 +611,20 @@ TORSION_EXTERN void hash_final(hash_t *hash, unsigned char *out, size_t len); TORSION_EXTERN int -hash_has_backend(int type); +hash_has_backend(hash_id_t type); TORSION_EXTERN size_t -hash_output_size(int type); +hash_output_size(hash_id_t type); TORSION_EXTERN size_t -hash_block_size(int type); +hash_block_size(hash_id_t type); /* * HMAC */ TORSION_EXTERN void -hmac_init(hmac_t *hmac, int type, const unsigned char *key, size_t len); +hmac_init(hmac_t *hmac, hash_id_t type, const unsigned char *key, size_t len); TORSION_EXTERN void hmac_update(hmac_t *hmac, const void *data, size_t len); @@ -630,4 +636,4 @@ hmac_final(hmac_t *hmac, unsigned char *out); } #endif -#endif /* _TORSION_HASH_H */ +#endif /* TORSION_HASH_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/ies.h b/node_modules/bcrypto/deps/torsion/include/torsion/ies.h index 6462658cd..da8fd8e29 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/ies.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/ies.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/bcrypto */ -#ifndef _TORSION_IES_H -#define _TORSION_IES_H +#ifndef TORSION_IES_H +#define TORSION_IES_H #ifdef __cplusplus extern "C" { @@ -54,4 +54,4 @@ secretbox_derive(unsigned char *key, const unsigned char *secret); } #endif -#endif /* _TORSION_IES_H */ +#endif /* TORSION_IES_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/kdf.h b/node_modules/bcrypto/deps/torsion/include/torsion/kdf.h index 6d0fcac48..fb68fded9 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/kdf.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/kdf.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_KDF_H -#define _TORSION_KDF_H +#ifndef TORSION_KDF_H +#define TORSION_KDF_H #ifdef __cplusplus extern "C" { @@ -14,6 +14,7 @@ extern "C" { #include #include #include "common.h" +#include "hash.h" /* * Symbol Aliases @@ -87,7 +88,7 @@ bcrypt_verify(const unsigned char *pass, size_t pass_len, const char *record); TORSION_EXTERN int eb2k_derive(unsigned char *key, unsigned char *iv, - int type, + hash_id_t type, const unsigned char *passwd, size_t passwd_len, const unsigned char *salt, @@ -100,13 +101,13 @@ eb2k_derive(unsigned char *key, */ TORSION_EXTERN int -hkdf_extract(unsigned char *out, int type, +hkdf_extract(unsigned char *out, hash_id_t type, const unsigned char *ikm, size_t ikm_len, const unsigned char *salt, size_t salt_len); TORSION_EXTERN int hkdf_expand(unsigned char *out, - int type, + hash_id_t type, const unsigned char *prk, const unsigned char *info, size_t info_len, @@ -118,7 +119,7 @@ hkdf_expand(unsigned char *out, TORSION_EXTERN int pbkdf2_derive(unsigned char *out, - int type, + hash_id_t type, const unsigned char *pass, size_t pass_len, const unsigned char *salt, @@ -132,14 +133,14 @@ pbkdf2_derive(unsigned char *out, TORSION_EXTERN int pgpdf_derive_simple(unsigned char *out, - int type, + hash_id_t type, const unsigned char *pass, size_t pass_len, size_t len); TORSION_EXTERN int pgpdf_derive_salted(unsigned char *out, - int type, + hash_id_t type, const unsigned char *pass, size_t pass_len, const unsigned char *salt, @@ -148,7 +149,7 @@ pgpdf_derive_salted(unsigned char *out, TORSION_EXTERN int pgpdf_derive_iterated(unsigned char *out, - int type, + hash_id_t type, const unsigned char *pass, size_t pass_len, const unsigned char *salt, @@ -175,4 +176,4 @@ scrypt_derive(unsigned char *out, } #endif -#endif /* _TORSION_KDF_H */ +#endif /* TORSION_KDF_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/mac.h b/node_modules/bcrypto/deps/torsion/include/torsion/mac.h index f49395804..f4ae1bf21 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/mac.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/mac.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_MAC_H -#define _TORSION_MAC_H +#ifndef TORSION_MAC_H +#define TORSION_MAC_H #ifdef __cplusplus extern "C" { @@ -21,6 +21,7 @@ extern "C" { #define poly1305_init torsion_poly1305_init #define poly1305_update torsion_poly1305_update +#define poly1305_pad torsion_poly1305_pad #define poly1305_final torsion_poly1305_final #define siphash_sum torsion_siphash_sum #define siphash_mod torsion_siphash_mod @@ -28,24 +29,28 @@ extern "C" { #define siphash256_sum torsion_siphash256_sum /* - * Structs + * Types */ +struct poly1305_32_s { + uint32_t r[5]; + uint32_t h[5]; + uint32_t pad[4]; +}; + +struct poly1305_64_s { + uint64_t r[3]; + uint64_t h[3]; + uint64_t pad[2]; +}; + typedef struct poly1305_s { union { - struct poly1305_32_s { - uint32_t r[5]; - uint32_t h[5]; - uint32_t pad[4]; - } u32; - struct poly1305_64_s { - uint64_t r[3]; - uint64_t h[3]; - uint64_t pad[2]; - } u64; + struct poly1305_32_s u32; + struct poly1305_64_s u64; } state; unsigned char block[16]; - size_t size; + size_t pos; } poly1305_t; /* @@ -58,6 +63,9 @@ poly1305_init(poly1305_t *ctx, const unsigned char *key); TORSION_EXTERN void poly1305_update(poly1305_t *ctx, const unsigned char *data, size_t len); +TORSION_EXTERN void +poly1305_pad(poly1305_t *ctx); + TORSION_EXTERN void poly1305_final(poly1305_t *ctx, unsigned char *mac); @@ -84,4 +92,4 @@ siphash256_sum(uint64_t num, const unsigned char *key); } #endif -#endif /* _TORSION_MAC_H */ +#endif /* TORSION_MAC_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/rand.h b/node_modules/bcrypto/deps/torsion/include/torsion/rand.h index 047db9636..edbb097c8 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/rand.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/rand.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_RAND_H -#define _TORSION_RAND_H +#ifndef TORSION_RAND_H +#define TORSION_RAND_H #ifdef __cplusplus extern "C" { @@ -19,16 +19,16 @@ extern "C" { * Symbol Aliases */ -#define torsion_threadsafety __torsion_threadsafety -#define torsion_randomaddr __torsion_randomaddr +#define torsion_threadsafety torsion__threadsafety +#define torsion_randomaddr torsion__randomaddr /* - * Defs + * Definitions */ -#define TORSION_THREAD_SAFETY_NONE 0 -#define TORSION_THREAD_SAFETY_TLS 1 -#define TORSION_THREAD_SAFETY_MUTEX 2 +#define TORSION_THREADSAFETY_NONE 0 +#define TORSION_THREADSAFETY_TLS 1 +#define TORSION_THREADSAFETY_MUTEX 2 /* * Random @@ -60,4 +60,4 @@ torsion_randomaddr(void); } #endif -#endif /* _TORSION_RAND_H */ +#endif /* TORSION_RAND_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/rsa.h b/node_modules/bcrypto/deps/torsion/include/torsion/rsa.h index 2024d18ea..4a8a777ee 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/rsa.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/rsa.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_RSA_H -#define _TORSION_RSA_H +#ifndef TORSION_RSA_H +#define TORSION_RSA_H #ifdef __cplusplus extern "C" { @@ -14,6 +14,7 @@ extern "C" { #include #include #include "common.h" +#include "hash.h" /* * Symbol Aliases @@ -43,7 +44,7 @@ extern "C" { #define rsa_unveil torsion_rsa_unveil /* - * Defs + * Definitions */ #define RSA_DEFAULT_MOD_BITS 2048 @@ -149,7 +150,7 @@ rsa_pubkey_export(unsigned char *out, TORSION_EXTERN int rsa_sign(unsigned char *out, size_t *out_len, - int type, + hash_id_t type, const unsigned char *msg, size_t msg_len, const unsigned char *key, @@ -157,7 +158,7 @@ rsa_sign(unsigned char *out, const unsigned char *entropy); TORSION_EXTERN int -rsa_verify(int type, +rsa_verify(hash_id_t type, const unsigned char *msg, size_t msg_len, const unsigned char *sig, @@ -186,7 +187,7 @@ rsa_decrypt(unsigned char *out, TORSION_EXTERN int rsa_sign_pss(unsigned char *out, size_t *out_len, - int type, + hash_id_t type, const unsigned char *msg, size_t msg_len, const unsigned char *key, @@ -195,7 +196,7 @@ rsa_sign_pss(unsigned char *out, const unsigned char *entropy); TORSION_EXTERN int -rsa_verify_pss(int type, +rsa_verify_pss(hash_id_t type, const unsigned char *msg, size_t msg_len, const unsigned char *sig, @@ -207,7 +208,7 @@ rsa_verify_pss(int type, TORSION_EXTERN int rsa_encrypt_oaep(unsigned char *out, size_t *out_len, - int type, + hash_id_t type, const unsigned char *msg, size_t msg_len, const unsigned char *key, @@ -219,7 +220,7 @@ rsa_encrypt_oaep(unsigned char *out, TORSION_EXTERN int rsa_decrypt_oaep(unsigned char *out, size_t *out_len, - int type, + hash_id_t type, const unsigned char *msg, size_t msg_len, const unsigned char *key, @@ -251,4 +252,4 @@ rsa_unveil(unsigned char *out, } #endif -#endif /* _TORSION_RSA_H */ +#endif /* TORSION_RSA_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/stream.h b/node_modules/bcrypto/deps/torsion/include/torsion/stream.h index 94b30908a..8046ec3b1 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/stream.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/stream.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_STREAM_H -#define _TORSION_STREAM_H +#ifndef TORSION_STREAM_H +#define TORSION_STREAM_H #ifdef __cplusplus extern "C" { @@ -23,15 +23,13 @@ extern "C" { #define arc4_crypt torsion_arc4_crypt #define chacha20_init torsion_chacha20_init #define chacha20_crypt torsion_chacha20_crypt -#define chacha20_pad torsion_chacha20_pad #define chacha20_derive torsion_chacha20_derive #define salsa20_init torsion_salsa20_init #define salsa20_crypt torsion_salsa20_crypt -#define salsa20_pad torsion_salsa20_pad #define salsa20_derive torsion_salsa20_derive /* - * Structs + * Types */ typedef struct arc4_s { @@ -79,8 +77,8 @@ chacha20_init(chacha20_t *ctx, TORSION_EXTERN void chacha20_crypt(chacha20_t *ctx, - unsigned char *out, - const unsigned char *data, + unsigned char *dst, + const unsigned char *src, size_t len); TORSION_EXTERN void @@ -103,8 +101,8 @@ salsa20_init(salsa20_t *ctx, TORSION_EXTERN void salsa20_crypt(salsa20_t *ctx, - unsigned char *out, - const unsigned char *data, + unsigned char *dst, + const unsigned char *src, size_t len); TORSION_EXTERN void @@ -117,4 +115,4 @@ salsa20_derive(unsigned char *out, } #endif -#endif /* _TORSION_STREAM_H */ +#endif /* TORSION_STREAM_H */ diff --git a/node_modules/bcrypto/deps/torsion/include/torsion/util.h b/node_modules/bcrypto/deps/torsion/include/torsion/util.h index fe7612b24..586a84e4c 100644 --- a/node_modules/bcrypto/deps/torsion/include/torsion/util.h +++ b/node_modules/bcrypto/deps/torsion/include/torsion/util.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_UTIL_H -#define _TORSION_UTIL_H +#ifndef TORSION_UTIL_H +#define TORSION_UTIL_H #ifdef __cplusplus extern "C" { @@ -27,14 +27,24 @@ extern "C" { */ TORSION_EXTERN void -torsion_cleanse(void *ptr, size_t len); +torsion_memzero(void *ptr, size_t len); /* * Memequal */ TORSION_EXTERN int -torsion_memequal(const void *s1, const void *s2, size_t n); +torsion_memequal(const void *x, const void *y, size_t n); + +/* + * Memxor + */ + +TORSION_EXTERN void +torsion_memxor(void *z, const void *x, size_t n); + +TORSION_EXTERN void +torsion_memxor3(void *z, const void *x, const void *y, size_t n); /* * Murmur3 @@ -51,4 +61,4 @@ murmur3_tweak(const unsigned char *data, } #endif -#endif /* _TORSION_UTIL_H */ +#endif /* TORSION_UTIL_H */ diff --git a/node_modules/bcrypto/deps/torsion/src/aead.c b/node_modules/bcrypto/deps/torsion/src/aead.c index 028fea49b..cf456e446 100644 --- a/node_modules/bcrypto/deps/torsion/src/aead.c +++ b/node_modules/bcrypto/deps/torsion/src/aead.c @@ -14,12 +14,6 @@ #include "bio.h" #include "internal.h" -/* - * Constants - */ - -static const unsigned char zero64[64] = {0}; - /* * ChaCha20-Poly1305 * @@ -33,6 +27,7 @@ chachapoly_init(chachapoly_t *aead, const unsigned char *key, const unsigned char *iv, size_t iv_len) { + static const unsigned char zero64[64] = {0}; unsigned char polykey[64]; chacha20_init(&aead->chacha, key, 32, iv, iv_len, 0); @@ -40,28 +35,16 @@ chachapoly_init(chachapoly_t *aead, poly1305_init(&aead->poly, polykey); - aead->mode = 0; aead->adlen = 0; aead->ctlen = 0; - torsion_cleanse(polykey, sizeof(polykey)); + torsion_memzero(polykey, sizeof(polykey)); } void chachapoly_aad(chachapoly_t *aead, const unsigned char *aad, size_t len) { - CHECK(aead->mode == 0); - - poly1305_update(&aead->poly, aad, len); - aead->adlen += len; -} - -static void -chachapoly_pad16(chachapoly_t *aead, uint64_t size) { - uint64_t pos = size & 15; - - if (pos > 0) - poly1305_update(&aead->poly, zero64, 16 - pos); + poly1305_update(&aead->poly, aad, len); } void @@ -69,17 +52,13 @@ chachapoly_encrypt(chachapoly_t *aead, unsigned char *dst, const unsigned char *src, size_t len) { - if (aead->mode == 0) { - chachapoly_pad16(aead, aead->adlen); - aead->mode = 1; - } + if (aead->ctlen == 0) + poly1305_pad(&aead->poly); - CHECK(aead->mode == 1); + aead->ctlen += len; chacha20_crypt(&aead->chacha, dst, src, len); poly1305_update(&aead->poly, dst, len); - - aead->ctlen += len; } void @@ -87,12 +66,8 @@ chachapoly_decrypt(chachapoly_t *aead, unsigned char *dst, const unsigned char *src, size_t len) { - if (aead->mode == 0) { - chachapoly_pad16(aead, aead->adlen); - aead->mode = 2; - } - - CHECK(aead->mode == 2); + if (aead->ctlen == 0) + poly1305_pad(&aead->poly); aead->ctlen += len; @@ -102,12 +77,8 @@ chachapoly_decrypt(chachapoly_t *aead, void chachapoly_auth(chachapoly_t *aead, const unsigned char *data, size_t len) { - if (aead->mode == 0) { - chachapoly_pad16(aead, aead->adlen); - aead->mode = 3; - } - - CHECK(aead->mode == 3); + if (aead->ctlen == 0) + poly1305_pad(&aead->poly); aead->ctlen += len; @@ -121,13 +92,7 @@ chachapoly_final(chachapoly_t *aead, unsigned char *tag) { write64le(len + 0, aead->adlen); write64le(len + 8, aead->ctlen); - if (aead->mode == 0) - chachapoly_pad16(aead, aead->adlen); - - chachapoly_pad16(aead, aead->ctlen); - + poly1305_pad(&aead->poly); poly1305_update(&aead->poly, len, 16); poly1305_final(&aead->poly, tag); - - aead->mode = -1; } diff --git a/node_modules/bcrypto/deps/torsion/src/asn1.h b/node_modules/bcrypto/deps/torsion/src/asn1.h index b9ba63023..4066f6dfb 100644 --- a/node_modules/bcrypto/deps/torsion/src/asn1.h +++ b/node_modules/bcrypto/deps/torsion/src/asn1.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_ASN1_H -#define _TORSION_ASN1_H +#ifndef TORSION_ASN1_H +#define TORSION_ASN1_H #include #include "mpi.h" @@ -14,22 +14,22 @@ * Alias */ -#define asn1_read_size __torsion_asn1_read_size -#define asn1_read_seq __torsion_asn1_read_seq -#define asn1_read_int __torsion_asn1_read_int -#define asn1_read_mpz __torsion_asn1_read_mpz -#define asn1_read_version __torsion_asn1_read_version -#define asn1_read_dumb __torsion_asn1_read_dumb -#define asn1_size_size __torsion_asn1_size_size -#define asn1_size_int __torsion_asn1_size_int -#define asn1_size_mpz __torsion_asn1_size_mpz -#define asn1_size_version __torsion_asn1_size_version -#define asn1_write_size __torsion_asn1_write_size -#define asn1_write_seq __torsion_asn1_write_seq -#define asn1_write_int __torsion_asn1_write_int -#define asn1_write_mpz __torsion_asn1_write_mpz -#define asn1_write_version __torsion_asn1_write_version -#define asn1_write_dumb __torsion_asn1_write_dumb +#define asn1_read_size torsion__asn1_read_size +#define asn1_read_seq torsion__asn1_read_seq +#define asn1_read_int torsion__asn1_read_int +#define asn1_read_mpz torsion__asn1_read_mpz +#define asn1_read_version torsion__asn1_read_version +#define asn1_read_dumb torsion__asn1_read_dumb +#define asn1_size_size torsion__asn1_size_size +#define asn1_size_int torsion__asn1_size_int +#define asn1_size_mpz torsion__asn1_size_mpz +#define asn1_size_version torsion__asn1_size_version +#define asn1_write_size torsion__asn1_write_size +#define asn1_write_seq torsion__asn1_write_seq +#define asn1_write_int torsion__asn1_write_int +#define asn1_write_mpz torsion__asn1_write_mpz +#define asn1_write_version torsion__asn1_write_version +#define asn1_write_dumb torsion__asn1_write_dumb /* * ASN1 @@ -88,4 +88,4 @@ asn1_write_version(unsigned char *data, size_t pos, unsigned int version); size_t asn1_write_dumb(unsigned char *data, size_t pos, const mpz_t n); -#endif /* _TORSION_ASN1_H */ +#endif /* TORSION_ASN1_H */ diff --git a/node_modules/bcrypto/deps/torsion/src/bf.h b/node_modules/bcrypto/deps/torsion/src/bf.h new file mode 100644 index 000000000..d847a9f52 --- /dev/null +++ b/node_modules/bcrypto/deps/torsion/src/bf.h @@ -0,0 +1,39 @@ +/*! + * bf.h - extra blowfish functions for libtorsion + * Copyright (c) 2020, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/libtorsion + */ + +#ifndef TORSION_BF_H +#define TORSION_BF_H + +#include +#include +#include + +#define blowfish_stream2word torsion__blowfish_stream2word +#define blowfish_expand0state torsion__blowfish_expand0state +#define blowfish_expandstate torsion__blowfish_expandstate +#define blowfish_enc torsion__blowfish_enc +#define blowfish_dec torsion__blowfish_dec + +uint32_t +blowfish_stream2word(const unsigned char *data, size_t len, size_t *off); + +void +blowfish_expand0state(blowfish_t *ctx, + const unsigned char *key, + size_t key_len); + +void +blowfish_expandstate(blowfish_t *ctx, + const unsigned char *key, size_t key_len, + const unsigned char *data, size_t data_len); + +void +blowfish_enc(const blowfish_t *ctx, uint32_t *data, size_t len); + +void +blowfish_dec(const blowfish_t *ctx, uint32_t *data, size_t len); + +#endif /* TORSION_BF_H */ diff --git a/node_modules/bcrypto/deps/torsion/src/bio.h b/node_modules/bcrypto/deps/torsion/src/bio.h index 672f7ebf4..b39ca0c5d 100644 --- a/node_modules/bcrypto/deps/torsion/src/bio.h +++ b/node_modules/bcrypto/deps/torsion/src/bio.h @@ -14,8 +14,8 @@ * the read/write. */ -#ifndef _TORSION_BIO_H -#define _TORSION_BIO_H +#ifndef TORSION_BIO_H +#define TORSION_BIO_H #include #include @@ -28,96 +28,84 @@ */ static TORSION_INLINE uint16_t -read16le(const void *src) { +read16le(const uint8_t *src) { if (!TORSION_BIGENDIAN) { uint16_t w; memcpy(&w, src, sizeof(w)); return w; } else { - const uint8_t *p = (const uint8_t *)src; - - return ((uint16_t)p[1] << 8) - | ((uint16_t)p[0] << 0); + return ((uint16_t)src[1] << 8) + | ((uint16_t)src[0] << 0); } } static TORSION_INLINE void -write16le(void *dst, uint16_t w) { +write16le(uint8_t *dst, uint16_t w) { if (!TORSION_BIGENDIAN) { memcpy(dst, &w, sizeof(w)); } else { - uint8_t *p = (uint8_t *)dst; - - p[1] = w >> 8; - p[0] = w >> 0; + dst[1] = w >> 8; + dst[0] = w >> 0; } } static TORSION_INLINE uint32_t -read32le(const void *src) { +read32le(const uint8_t *src) { if (!TORSION_BIGENDIAN) { uint32_t w; memcpy(&w, src, sizeof(w)); return w; } else { - const uint8_t *p = (const uint8_t *)src; - - return ((uint32_t)p[3] << 24) - | ((uint32_t)p[2] << 16) - | ((uint32_t)p[1] << 8) - | ((uint32_t)p[0] << 0); + return ((uint32_t)src[3] << 24) + | ((uint32_t)src[2] << 16) + | ((uint32_t)src[1] << 8) + | ((uint32_t)src[0] << 0); } } static TORSION_INLINE void -write32le(void *dst, uint32_t w) { +write32le(uint8_t *dst, uint32_t w) { if (!TORSION_BIGENDIAN) { memcpy(dst, &w, sizeof(w)); } else { - uint8_t *p = (uint8_t *)dst; - - p[3] = w >> 24; - p[2] = w >> 16; - p[1] = w >> 8; - p[0] = w >> 0; + dst[3] = w >> 24; + dst[2] = w >> 16; + dst[1] = w >> 8; + dst[0] = w >> 0; } } static TORSION_INLINE uint64_t -read64le(const void *src) { +read64le(const uint8_t *src) { if (!TORSION_BIGENDIAN) { uint64_t w; memcpy(&w, src, sizeof(w)); return w; } else { - const uint8_t *p = (const uint8_t *)src; - - return ((uint64_t)p[7] << 56) - | ((uint64_t)p[6] << 48) - | ((uint64_t)p[5] << 40) - | ((uint64_t)p[4] << 32) - | ((uint64_t)p[3] << 24) - | ((uint64_t)p[2] << 16) - | ((uint64_t)p[1] << 8) - | ((uint64_t)p[0] << 0); + return ((uint64_t)src[7] << 56) + | ((uint64_t)src[6] << 48) + | ((uint64_t)src[5] << 40) + | ((uint64_t)src[4] << 32) + | ((uint64_t)src[3] << 24) + | ((uint64_t)src[2] << 16) + | ((uint64_t)src[1] << 8) + | ((uint64_t)src[0] << 0); } } static TORSION_INLINE void -write64le(void *dst, uint64_t w) { +write64le(uint8_t *dst, uint64_t w) { if (!TORSION_BIGENDIAN) { memcpy(dst, &w, sizeof(w)); } else { - uint8_t *p = (uint8_t *)dst; - - p[7] = w >> 56; - p[6] = w >> 48; - p[5] = w >> 40; - p[4] = w >> 32; - p[3] = w >> 24; - p[2] = w >> 16; - p[1] = w >> 8; - p[0] = w >> 0; + dst[7] = w >> 56; + dst[6] = w >> 48; + dst[5] = w >> 40; + dst[4] = w >> 32; + dst[3] = w >> 24; + dst[2] = w >> 16; + dst[1] = w >> 8; + dst[0] = w >> 0; } } @@ -126,96 +114,84 @@ write64le(void *dst, uint64_t w) { */ static TORSION_INLINE uint16_t -read16be(const void *src) { +read16be(const uint8_t *src) { if (TORSION_BIGENDIAN) { uint16_t w; memcpy(&w, src, sizeof(w)); return w; } else { - const uint8_t *p = (const uint8_t *)src; - - return ((uint16_t)p[0] << 8) - | ((uint16_t)p[1] << 0); + return ((uint16_t)src[0] << 8) + | ((uint16_t)src[1] << 0); } } static TORSION_INLINE void -write16be(void *dst, uint16_t w) { +write16be(uint8_t *dst, uint16_t w) { if (TORSION_BIGENDIAN) { memcpy(dst, &w, sizeof(w)); } else { - uint8_t *p = (uint8_t *)dst; - - p[0] = w >> 8; - p[1] = w >> 0; + dst[0] = w >> 8; + dst[1] = w >> 0; } } static TORSION_INLINE uint32_t -read32be(const void *src) { +read32be(const uint8_t *src) { if (TORSION_BIGENDIAN) { uint32_t w; memcpy(&w, src, sizeof(w)); return w; } else { - const uint8_t *p = (const uint8_t *)src; - - return ((uint32_t)p[0] << 24) - | ((uint32_t)p[1] << 16) - | ((uint32_t)p[2] << 8) - | ((uint32_t)p[3] << 0); + return ((uint32_t)src[0] << 24) + | ((uint32_t)src[1] << 16) + | ((uint32_t)src[2] << 8) + | ((uint32_t)src[3] << 0); } } static TORSION_INLINE void -write32be(void *dst, uint32_t w) { +write32be(uint8_t *dst, uint32_t w) { if (TORSION_BIGENDIAN) { memcpy(dst, &w, sizeof(w)); } else { - uint8_t *p = (uint8_t *)dst; - - p[0] = w >> 24; - p[1] = w >> 16; - p[2] = w >> 8; - p[3] = w >> 0; + dst[0] = w >> 24; + dst[1] = w >> 16; + dst[2] = w >> 8; + dst[3] = w >> 0; } } static TORSION_INLINE uint64_t -read64be(const void *src) { +read64be(const uint8_t *src) { if (TORSION_BIGENDIAN) { uint64_t w; memcpy(&w, src, sizeof(w)); return w; } else { - const uint8_t *p = (const uint8_t *)src; - - return ((uint64_t)p[0] << 56) - | ((uint64_t)p[1] << 48) - | ((uint64_t)p[2] << 40) - | ((uint64_t)p[3] << 32) - | ((uint64_t)p[4] << 24) - | ((uint64_t)p[5] << 16) - | ((uint64_t)p[6] << 8) - | ((uint64_t)p[7] << 0); + return ((uint64_t)src[0] << 56) + | ((uint64_t)src[1] << 48) + | ((uint64_t)src[2] << 40) + | ((uint64_t)src[3] << 32) + | ((uint64_t)src[4] << 24) + | ((uint64_t)src[5] << 16) + | ((uint64_t)src[6] << 8) + | ((uint64_t)src[7] << 0); } } static TORSION_INLINE void -write64be(void *dst, uint64_t w) { +write64be(uint8_t *dst, uint64_t w) { if (TORSION_BIGENDIAN) { memcpy(dst, &w, sizeof(w)); } else { - uint8_t *p = (uint8_t *)dst; - - p[0] = w >> 56; - p[1] = w >> 48; - p[2] = w >> 40; - p[3] = w >> 32; - p[4] = w >> 24; - p[5] = w >> 16; - p[6] = w >> 8; - p[7] = w >> 0; + dst[0] = w >> 56; + dst[1] = w >> 48; + dst[2] = w >> 40; + dst[3] = w >> 32; + dst[4] = w >> 24; + dst[5] = w >> 16; + dst[6] = w >> 8; + dst[7] = w >> 0; } } @@ -260,4 +236,54 @@ torsion_bswap64(uint64_t x) { } #endif -#endif /* _TORSION_BIO_H */ +/* + * Incrementation + */ + +static TORSION_INLINE void +increment_le(uint8_t *x, size_t n) { + unsigned int c = 1; + size_t i; + + for (i = 0; i < n; i++) { + c += (unsigned int)x[i]; + x[i] = c; + c >>= 8; + } +} + +static TORSION_INLINE void +increment_le_var(uint8_t *x, size_t n) { + uint8_t c = 1; + size_t i; + + for (i = 0; i < n && c != 0; i++) { + x[i] += c; + c = (x[i] < c); + } +} + +static TORSION_INLINE void +increment_be(uint8_t *x, size_t n) { + unsigned int c = 1; + size_t i; + + for (i = n - 1; i != (size_t)-1; i--) { + c += (unsigned int)x[i]; + x[i] = c; + c >>= 8; + } +} + +static TORSION_INLINE void +increment_be_var(uint8_t *x, size_t n) { + uint8_t c = 1; + size_t i; + + for (i = n - 1; i != (size_t)-1 && c != 0; i--) { + x[i] += c; + c = (x[i] < c); + } +} + +#endif /* TORSION_BIO_H */ diff --git a/node_modules/bcrypto/deps/torsion/src/cipher.c b/node_modules/bcrypto/deps/torsion/src/cipher.c index 19dc9530d..659f392b5 100644 --- a/node_modules/bcrypto/deps/torsion/src/cipher.c +++ b/node_modules/bcrypto/deps/torsion/src/cipher.c @@ -33,14 +33,13 @@ #include #include #include +#include "bf.h" #include "bio.h" /* * Constants */ -static const unsigned char zero64[64] = {0}; - /* Shifted by four. */ static const uint32_t poly_table[9] = { 0x00001b, /* 8 */ @@ -660,176 +659,174 @@ aes_init(aes_t *ctx, unsigned int bits, const unsigned char *key) { void aes_init_encrypt(aes_t *ctx, unsigned int bits, const unsigned char *key) { uint32_t *K = ctx->enckey; - uint32_t tmp; - int p = 0; + uint32_t word; int i = 0; - CHECK(bits == 128 || bits == 192 || bits == 256); - /* Defensive memset. */ memset(ctx, 0, sizeof(*ctx)); - K[0] = read32be(key + 0); - K[1] = read32be(key + 4); - K[2] = read32be(key + 8); - K[3] = read32be(key + 12); + switch (bits) { + case 128: { + ctx->rounds = 10; - if (bits == 128) { - ctx->rounds = 10; + K[0] = read32be(key + 0); + K[1] = read32be(key + 4); + K[2] = read32be(key + 8); + K[3] = read32be(key + 12); - for (;;) { - tmp = K[p + 3]; + for (;;) { + word = K[3]; - K[p + 4] = K[p] - ^ (TE2[(tmp >> 16) & 0xff] & 0xff000000) - ^ (TE3[(tmp >> 8) & 0xff] & 0x00ff0000) - ^ (TE0[(tmp >> 0) & 0xff] & 0x0000ff00) - ^ (TE1[(tmp >> 24) & 0xff] & 0x000000ff) - ^ RCON[i]; + K[4] = K[0] + ^ (TE2[(word >> 16) & 0xff] & 0xff000000) + ^ (TE3[(word >> 8) & 0xff] & 0x00ff0000) + ^ (TE0[(word >> 0) & 0xff] & 0x0000ff00) + ^ (TE1[(word >> 24) & 0xff] & 0x000000ff) + ^ RCON[i]; - K[p + 5] = K[p + 1] ^ K[p + 4]; - K[p + 6] = K[p + 2] ^ K[p + 5]; - K[p + 7] = K[p + 3] ^ K[p + 6]; + K[5] = K[1] ^ K[4]; + K[6] = K[2] ^ K[5]; + K[7] = K[3] ^ K[6]; - i += 1; + if (++i == 10) + break; - if (i == 10) - break; + K += 4; + } - p += 4; + break; } - return; - } + case 192: { + ctx->rounds = 12; - K[p + 4] = read32be(key + 16); - K[p + 5] = read32be(key + 20); + K[0] = read32be(key + 0); + K[1] = read32be(key + 4); + K[2] = read32be(key + 8); + K[3] = read32be(key + 12); + K[4] = read32be(key + 16); + K[5] = read32be(key + 20); - if (bits == 192) { - ctx->rounds = 12; + for (;;) { + word = K[5]; - for (;;) { - tmp = K[p + 5]; + K[6] = K[0] + ^ (TE2[(word >> 16) & 0xff] & 0xff000000) + ^ (TE3[(word >> 8) & 0xff] & 0x00ff0000) + ^ (TE0[(word >> 0) & 0xff] & 0x0000ff00) + ^ (TE1[(word >> 24) & 0xff] & 0x000000ff) + ^ RCON[i]; - K[p + 6] = K[p] - ^ (TE2[(tmp >> 16) & 0xff] & 0xff000000) - ^ (TE3[(tmp >> 8) & 0xff] & 0x00ff0000) - ^ (TE0[(tmp >> 0) & 0xff] & 0x0000ff00) - ^ (TE1[(tmp >> 24) & 0xff] & 0x000000ff) - ^ RCON[i]; + K[7] = K[1] ^ K[6]; + K[8] = K[2] ^ K[7]; + K[9] = K[3] ^ K[8]; - K[p + 7] = K[p + 1] ^ K[p + 6]; - K[p + 8] = K[p + 2] ^ K[p + 7]; - K[p + 9] = K[p + 3] ^ K[p + 8]; + if (++i == 8) + break; - i += 1; + K[10] = K[4] ^ K[ 9]; + K[11] = K[5] ^ K[10]; - if (i == 8) - break; + K += 6; + } - K[p + 10] = K[p + 4] ^ K[p + 9]; - K[p + 11] = K[p + 5] ^ K[p + 10]; - p += 6; + break; } - return; - } - - K[p + 6] = read32be(key + 24); - K[p + 7] = read32be(key + 28); - - if (bits == 256) { - ctx->rounds = 14; - - for (;;) { - tmp = K[p + 7]; - - K[p + 8] = K[p] - ^ (TE2[(tmp >> 16) & 0xff] & 0xff000000) - ^ (TE3[(tmp >> 8) & 0xff] & 0x00ff0000) - ^ (TE0[(tmp >> 0) & 0xff] & 0x0000ff00) - ^ (TE1[(tmp >> 24) & 0xff] & 0x000000ff) - ^ RCON[i]; - - K[p + 9] = K[p + 1] ^ K[p + 8]; - K[p + 10] = K[p + 2] ^ K[p + 9]; - K[p + 11] = K[p + 3] ^ K[p + 10]; - - i += 1; + case 256: { + ctx->rounds = 14; + + K[0] = read32be(key + 0); + K[1] = read32be(key + 4); + K[2] = read32be(key + 8); + K[3] = read32be(key + 12); + K[4] = read32be(key + 16); + K[5] = read32be(key + 20); + K[6] = read32be(key + 24); + K[7] = read32be(key + 28); + + for (;;) { + word = K[7]; + + K[8] = K[0] + ^ (TE2[(word >> 16) & 0xff] & 0xff000000) + ^ (TE3[(word >> 8) & 0xff] & 0x00ff0000) + ^ (TE0[(word >> 0) & 0xff] & 0x0000ff00) + ^ (TE1[(word >> 24) & 0xff] & 0x000000ff) + ^ RCON[i]; + + K[ 9] = K[1] ^ K[ 8]; + K[10] = K[2] ^ K[ 9]; + K[11] = K[3] ^ K[10]; + + if (++i == 7) + break; - if (i == 7) - break; + word = K[11]; - tmp = K[p + 11]; + K[12] = K[4] + ^ (TE2[(word >> 24) & 0xff] & 0xff000000) + ^ (TE3[(word >> 16) & 0xff] & 0x00ff0000) + ^ (TE0[(word >> 8) & 0xff] & 0x0000ff00) + ^ (TE1[(word >> 0) & 0xff] & 0x000000ff); - K[p + 12] = K[p + 4] - ^ (TE2[(tmp >> 24) & 0xff] & 0xff000000) - ^ (TE3[(tmp >> 16) & 0xff] & 0x00ff0000) - ^ (TE0[(tmp >> 8) & 0xff] & 0x0000ff00) - ^ (TE1[(tmp >> 0) & 0xff] & 0x000000ff); + K[13] = K[5] ^ K[12]; + K[14] = K[6] ^ K[13]; + K[15] = K[7] ^ K[14]; - K[p + 13] = K[p + 5] ^ K[p + 12]; - K[p + 14] = K[p + 6] ^ K[p + 13]; - K[p + 15] = K[p + 7] ^ K[p + 14]; + K += 8; + } - p += 8; + break; } - return; + default: { + torsion_abort(); /* LCOV_EXCL_LINE */ + break; + } } - - torsion_abort(); /* LCOV_EXCL_LINE */ } void aes_init_decrypt(aes_t *ctx) { uint32_t *K = ctx->deckey; - uint32_t tmp; - int p = 0; - int i, j; + uint32_t x, y; + int i, j, k; memcpy(K, ctx->enckey, sizeof(ctx->enckey)); for (i = 0, j = 4 * ctx->rounds; i < j; i += 4, j -= 4) { - tmp = K[i + 0]; - K[i + 0] = K[j + 0]; - K[j + 0] = tmp; - - tmp = K[i + 1]; - K[i + 1] = K[j + 1]; - K[j + 1] = tmp; - - tmp = K[i + 2]; - K[i + 2] = K[j + 2]; - K[j + 2] = tmp; + for (k = 0; k < 4; k++) { + x = K[i + k]; + y = K[j + k]; - tmp = K[i + 3]; - K[i + 3] = K[j + 3]; - K[j + 3] = tmp; + K[i + k] = y; + K[j + k] = x; + } } for (i = 1; i < ctx->rounds; i++) { - p += 4; - - K[p + 0] = TD0[TE1[(K[p + 0] >> 24) & 0xff] & 0xff] - ^ TD1[TE1[(K[p + 0] >> 16) & 0xff] & 0xff] - ^ TD2[TE1[(K[p + 0] >> 8) & 0xff] & 0xff] - ^ TD3[TE1[(K[p + 0] >> 0) & 0xff] & 0xff]; - - K[p + 1] = TD0[TE1[(K[p + 1] >> 24) & 0xff] & 0xff] - ^ TD1[TE1[(K[p + 1] >> 16) & 0xff] & 0xff] - ^ TD2[TE1[(K[p + 1] >> 8) & 0xff] & 0xff] - ^ TD3[TE1[(K[p + 1] >> 0) & 0xff] & 0xff]; - - K[p + 2] = TD0[TE1[(K[p + 2] >> 24) & 0xff] & 0xff] - ^ TD1[TE1[(K[p + 2] >> 16) & 0xff] & 0xff] - ^ TD2[TE1[(K[p + 2] >> 8) & 0xff] & 0xff] - ^ TD3[TE1[(K[p + 2] >> 0) & 0xff] & 0xff]; - - K[p + 3] = TD0[TE1[(K[p + 3] >> 24) & 0xff] & 0xff] - ^ TD1[TE1[(K[p + 3] >> 16) & 0xff] & 0xff] - ^ TD2[TE1[(K[p + 3] >> 8) & 0xff] & 0xff] - ^ TD3[TE1[(K[p + 3] >> 0) & 0xff] & 0xff]; + K += 4; + + K[0] = TD0[TE1[(K[0] >> 24) & 0xff] & 0xff] + ^ TD1[TE1[(K[0] >> 16) & 0xff] & 0xff] + ^ TD2[TE1[(K[0] >> 8) & 0xff] & 0xff] + ^ TD3[TE1[(K[0] >> 0) & 0xff] & 0xff]; + + K[1] = TD0[TE1[(K[1] >> 24) & 0xff] & 0xff] + ^ TD1[TE1[(K[1] >> 16) & 0xff] & 0xff] + ^ TD2[TE1[(K[1] >> 8) & 0xff] & 0xff] + ^ TD3[TE1[(K[1] >> 0) & 0xff] & 0xff]; + + K[2] = TD0[TE1[(K[2] >> 24) & 0xff] & 0xff] + ^ TD1[TE1[(K[2] >> 16) & 0xff] & 0xff] + ^ TD2[TE1[(K[2] >> 8) & 0xff] & 0xff] + ^ TD3[TE1[(K[2] >> 0) & 0xff] & 0xff]; + + K[3] = TD0[TE1[(K[3] >> 24) & 0xff] & 0xff] + ^ TD1[TE1[(K[3] >> 16) & 0xff] & 0xff] + ^ TD2[TE1[(K[3] >> 8) & 0xff] & 0xff] + ^ TD3[TE1[(K[3] >> 0) & 0xff] & 0xff]; } } @@ -842,87 +839,85 @@ aes_encrypt(const aes_t *ctx, unsigned char *dst, const unsigned char *src) { uint32_t s3 = read32be(src + 12) ^ K[3]; uint32_t t0, t1, t2, t3; int r = ctx->rounds >> 1; - int p = 0; for (;;) { t0 = TE0[(s0 >> 24) & 0xff] ^ TE1[(s1 >> 16) & 0xff] ^ TE2[(s2 >> 8) & 0xff] ^ TE3[(s3 >> 0) & 0xff] - ^ K[p + 4]; + ^ K[4]; t1 = TE0[(s1 >> 24) & 0xff] ^ TE1[(s2 >> 16) & 0xff] ^ TE2[(s3 >> 8) & 0xff] ^ TE3[(s0 >> 0) & 0xff] - ^ K[p + 5]; + ^ K[5]; t2 = TE0[(s2 >> 24) & 0xff] ^ TE1[(s3 >> 16) & 0xff] ^ TE2[(s0 >> 8) & 0xff] ^ TE3[(s1 >> 0) & 0xff] - ^ K[p + 6]; + ^ K[6]; t3 = TE0[(s3 >> 24) & 0xff] ^ TE1[(s0 >> 16) & 0xff] ^ TE2[(s1 >> 8) & 0xff] ^ TE3[(s2 >> 0) & 0xff] - ^ K[p + 7]; + ^ K[7]; - p += 8; - r -= 1; + K += 8; - if (r == 0) + if (--r == 0) break; s0 = TE0[(t0 >> 24) & 0xff] ^ TE1[(t1 >> 16) & 0xff] ^ TE2[(t2 >> 8) & 0xff] ^ TE3[(t3 >> 0) & 0xff] - ^ K[p + 0]; + ^ K[0]; s1 = TE0[(t1 >> 24) & 0xff] ^ TE1[(t2 >> 16) & 0xff] ^ TE2[(t3 >> 8) & 0xff] ^ TE3[(t0 >> 0) & 0xff] - ^ K[p + 1]; + ^ K[1]; s2 = TE0[(t2 >> 24) & 0xff] ^ TE1[(t3 >> 16) & 0xff] ^ TE2[(t0 >> 8) & 0xff] ^ TE3[(t1 >> 0) & 0xff] - ^ K[p + 2]; + ^ K[2]; s3 = TE0[(t3 >> 24) & 0xff] ^ TE1[(t0 >> 16) & 0xff] ^ TE2[(t1 >> 8) & 0xff] ^ TE3[(t2 >> 0) & 0xff] - ^ K[p + 3]; + ^ K[3]; } s0 = (TE2[(t0 >> 24) & 0xff] & 0xff000000) ^ (TE3[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (TE0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (TE1[(t3 >> 0) & 0xff] & 0x000000ff) - ^ K[p + 0]; + ^ K[0]; s1 = (TE2[(t1 >> 24) & 0xff] & 0xff000000) ^ (TE3[(t2 >> 16) & 0xff] & 0x00ff0000) ^ (TE0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (TE1[(t0 >> 0) & 0xff] & 0x000000ff) - ^ K[p + 1]; + ^ K[1]; s2 = (TE2[(t2 >> 24) & 0xff] & 0xff000000) ^ (TE3[(t3 >> 16) & 0xff] & 0x00ff0000) ^ (TE0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (TE1[(t1 >> 0) & 0xff] & 0x000000ff) - ^ K[p + 2]; + ^ K[2]; s3 = (TE2[(t3 >> 24) & 0xff] & 0xff000000) ^ (TE3[(t0 >> 16) & 0xff] & 0x00ff0000) ^ (TE0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (TE1[(t2 >> 0) & 0xff] & 0x000000ff) - ^ K[p + 3]; + ^ K[3]; write32be(dst + 0, s0); write32be(dst + 4, s1); @@ -939,87 +934,85 @@ aes_decrypt(const aes_t *ctx, unsigned char *dst, const unsigned char *src) { uint32_t s3 = read32be(src + 12) ^ K[3]; uint32_t t0, t1, t2, t3; int r = ctx->rounds >> 1; - int p = 0; for (;;) { t0 = TD0[(s0 >> 24) & 0xff] ^ TD1[(s3 >> 16) & 0xff] ^ TD2[(s2 >> 8) & 0xff] ^ TD3[(s1 >> 0) & 0xff] - ^ K[p + 4]; + ^ K[4]; t1 = TD0[(s1 >> 24) & 0xff] ^ TD1[(s0 >> 16) & 0xff] ^ TD2[(s3 >> 8) & 0xff] ^ TD3[(s2 >> 0) & 0xff] - ^ K[p + 5]; + ^ K[5]; t2 = TD0[(s2 >> 24) & 0xff] ^ TD1[(s1 >> 16) & 0xff] ^ TD2[(s0 >> 8) & 0xff] ^ TD3[(s3 >> 0) & 0xff] - ^ K[p + 6]; + ^ K[6]; t3 = TD0[(s3 >> 24) & 0xff] ^ TD1[(s2 >> 16) & 0xff] ^ TD2[(s1 >> 8) & 0xff] ^ TD3[(s0 >> 0) & 0xff] - ^ K[p + 7]; + ^ K[7]; - p += 8; - r -= 1; + K += 8; - if (r == 0) + if (--r == 0) break; s0 = TD0[(t0 >> 24) & 0xff] ^ TD1[(t3 >> 16) & 0xff] ^ TD2[(t2 >> 8) & 0xff] ^ TD3[(t1 >> 0) & 0xff] - ^ K[p + 0]; + ^ K[0]; s1 = TD0[(t1 >> 24) & 0xff] ^ TD1[(t0 >> 16) & 0xff] ^ TD2[(t3 >> 8) & 0xff] ^ TD3[(t2 >> 0) & 0xff] - ^ K[p + 1]; + ^ K[1]; s2 = TD0[(t2 >> 24) & 0xff] ^ TD1[(t1 >> 16) & 0xff] ^ TD2[(t0 >> 8) & 0xff] ^ TD3[(t3 >> 0) & 0xff] - ^ K[p + 2]; + ^ K[2]; s3 = TD0[(t3 >> 24) & 0xff] ^ TD1[(t2 >> 16) & 0xff] ^ TD2[(t1 >> 8) & 0xff] ^ TD3[(t0 >> 0) & 0xff] - ^ K[p + 3]; + ^ K[3]; } s0 = (TD4[(t0 >> 24) & 0xff] << 24) ^ (TD4[(t3 >> 16) & 0xff] << 16) ^ (TD4[(t2 >> 8) & 0xff] << 8) ^ (TD4[(t1 >> 0) & 0xff] << 0) - ^ K[p + 0]; + ^ K[0]; s1 = (TD4[(t1 >> 24) & 0xff] << 24) ^ (TD4[(t0 >> 16) & 0xff] << 16) ^ (TD4[(t3 >> 8) & 0xff] << 8) ^ (TD4[(t2 >> 0) & 0xff] << 0) - ^ K[p + 1]; + ^ K[1]; s2 = (TD4[(t2 >> 24) & 0xff] << 24) ^ (TD4[(t1 >> 16) & 0xff] << 16) ^ (TD4[(t0 >> 8) & 0xff] << 8) ^ (TD4[(t3 >> 0) & 0xff] << 0) - ^ K[p + 2]; + ^ K[2]; s3 = (TD4[(t3 >> 24) & 0xff] << 24) ^ (TD4[(t2 >> 16) & 0xff] << 16) ^ (TD4[(t1 >> 8) & 0xff] << 8) ^ (TD4[(t0 >> 0) & 0xff] << 0) - ^ K[p + 3]; + ^ K[3]; write32be(dst + 0, s0); write32be(dst + 4, s1); @@ -1859,13 +1852,13 @@ blowfish_decrypt(const blowfish_t *ctx, * https://github.com/aead/camellia/blob/master/camellia.go */ -#define SIGMA camellia_SIGMA +#define sigma camellia_SIGMA #define S1 camellia_S1 #define S2 camellia_S2 #define S3 camellia_S3 #define S4 camellia_S4 -static const uint32_t SIGMA[12] = { +static const uint32_t sigma[12] = { 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be, 0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd @@ -2188,16 +2181,16 @@ camellia128_init(camellia_t *ctx, const unsigned char *key) { k[2] = s2; k[3] = s3; - F(s0, s1, s2, s3, SIGMA[0], SIGMA[1]); - F(s2, s3, s0, s1, SIGMA[2], SIGMA[3]); + F(s0, s1, s2, s3, sigma[0], sigma[1]); + F(s2, s3, s0, s1, sigma[2], sigma[3]); s0 ^= k[0]; s1 ^= k[1]; s2 ^= k[2]; s3 ^= k[3]; - F(s0, s1, s2, s3, SIGMA[4], SIGMA[5]); - F(s2, s3, s0, s1, SIGMA[6], SIGMA[7]); + F(s0, s1, s2, s3, sigma[4], sigma[5]); + F(s2, s3, s0, s1, sigma[6], sigma[7]); k[4] = s0; k[5] = s1; @@ -2447,16 +2440,16 @@ camellia256_init(camellia_t *ctx, const unsigned char *key, size_t key_len) { s2 = k[10] ^ k[2]; s3 = k[11] ^ k[3]; - F(s0, s1, s2, s3, SIGMA[0], SIGMA[1]); - F(s2, s3, s0, s1, SIGMA[2], SIGMA[3]); + F(s0, s1, s2, s3, sigma[0], sigma[1]); + F(s2, s3, s0, s1, sigma[2], sigma[3]); s0 ^= k[0]; s1 ^= k[1]; s2 ^= k[2]; s3 ^= k[3]; - F(s0, s1, s2, s3, SIGMA[4], SIGMA[5]); - F(s2, s3, s0, s1, SIGMA[6], SIGMA[7]); + F(s0, s1, s2, s3, sigma[4], sigma[5]); + F(s2, s3, s0, s1, sigma[6], sigma[7]); k[12] = s0; k[13] = s1; @@ -2468,8 +2461,8 @@ camellia256_init(camellia_t *ctx, const unsigned char *key, size_t key_len) { s2 ^= k[10]; s3 ^= k[11]; - F(s0, s1, s2, s3, SIGMA[8], SIGMA[9]); - F(s2, s3, s0, s1, SIGMA[10], SIGMA[11]); + F(s0, s1, s2, s3, sigma[8], sigma[9]); + F(s2, s3, s0, s1, sigma[10], sigma[11]); k[4] = s0; k[5] = s1; @@ -2789,7 +2782,7 @@ camellia_decrypt(const camellia_t *ctx, camellia256_decrypt(ctx, dst, src); } -#undef SIGMA +#undef sigma #undef S1 #undef S2 #undef S3 @@ -3348,58 +3341,58 @@ static const struct { } schedule[4] = { { { - {4, 0, 0xd, 0xf, 0xc, 0xe, 0x8}, - {5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa}, - {6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9}, - {7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb} + { 0x04, 0x00, 0x0d, 0x0f, 0x0c, 0x0e, 0x08 }, + { 0x05, 0x02, 0x10, 0x12, 0x11, 0x13, 0x0a }, + { 0x06, 0x03, 0x17, 0x16, 0x15, 0x14, 0x09 }, + { 0x07, 0x01, 0x1a, 0x19, 0x1b, 0x18, 0x0b } }, { - {16 + 8, 16 + 9, 16 + 7, 16 + 6, 16 + 2}, - {16 + 0xa, 16 + 0xb, 16 + 5, 16 + 4, 16 + 6}, - {16 + 0xc, 16 + 0xd, 16 + 3, 16 + 2, 16 + 9}, - {16 + 0xe, 16 + 0xf, 16 + 1, 16 + 0, 16 + 0xc} + { 0x18, 0x19, 0x17, 0x16, 0x12 }, + { 0x1a, 0x1b, 0x15, 0x14, 0x16 }, + { 0x1c, 0x1d, 0x13, 0x12, 0x19 }, + { 0x1e, 0x1f, 0x11, 0x10, 0x1c } } }, { { - {0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0}, - {1, 4, 0, 2, 1, 3, 16 + 2}, - {2, 5, 7, 6, 5, 4, 16 + 1}, - {3, 7, 0xa, 9, 0xb, 8, 16 + 3} + { 0x00, 0x06, 0x15, 0x17, 0x14, 0x16, 0x10 }, + { 0x01, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12 }, + { 0x02, 0x05, 0x07, 0x06, 0x05, 0x04, 0x11 }, + { 0x03, 0x07, 0x0a, 0x09, 0x0b, 0x08, 0x13 } }, { - {3, 2, 0xc, 0xd, 8}, - {1, 0, 0xe, 0xf, 0xd}, - {7, 6, 8, 9, 3}, - {5, 4, 0xa, 0xb, 7} + { 0x03, 0x02, 0x0c, 0x0d, 0x08 }, + { 0x01, 0x00, 0x0e, 0x0f, 0x0d }, + { 0x07, 0x06, 0x08, 0x09, 0x03 }, + { 0x05, 0x04, 0x0a, 0x0b, 0x07 } } }, { { - {4, 0, 0xd, 0xf, 0xc, 0xe, 8}, - {5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa}, - {6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9}, - {7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb} + { 0x04, 0x00, 0x0d, 0x0f, 0x0c, 0x0e, 0x08 }, + { 0x05, 0x02, 0x10, 0x12, 0x11, 0x13, 0x0a }, + { 0x06, 0x03, 0x17, 0x16, 0x15, 0x14, 0x09 }, + { 0x07, 0x01, 0x1a, 0x19, 0x1b, 0x18, 0x0b } }, { - {16 + 3, 16 + 2, 16 + 0xc, 16 + 0xd, 16 + 9}, - {16 + 1, 16 + 0, 16 + 0xe, 16 + 0xf, 16 + 0xc}, - {16 + 7, 16 + 6, 16 + 8, 16 + 9, 16 + 2}, - {16 + 5, 16 + 4, 16 + 0xa, 16 + 0xb, 16 + 6} + { 0x13, 0x12, 0x1c, 0x1d, 0x19 }, + { 0x11, 0x10, 0x1e, 0x1f, 0x1c }, + { 0x17, 0x16, 0x18, 0x19, 0x12 }, + { 0x15, 0x14, 0x1a, 0x1b, 0x16 } } }, { { - {0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0}, - {1, 4, 0, 2, 1, 3, 16 + 2}, - {2, 5, 7, 6, 5, 4, 16 + 1}, - {3, 7, 0xa, 9, 0xb, 8, 16 + 3} + { 0x00, 0x06, 0x15, 0x17, 0x14, 0x16, 0x10 }, + { 0x01, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12 }, + { 0x02, 0x05, 0x07, 0x06, 0x05, 0x04, 0x11 }, + { 0x03, 0x07, 0x0a, 0x09, 0x0b, 0x08, 0x13 } }, { - {8, 9, 7, 6, 3}, - {0xa, 0xb, 5, 4, 7}, - {0xc, 0xd, 3, 2, 8}, - {0xe, 0xf, 1, 0, 0xd} + { 0x08, 0x09, 0x07, 0x06, 0x03 }, + { 0x0a, 0x0b, 0x05, 0x04, 0x07 }, + { 0x0c, 0x0d, 0x03, 0x02, 0x08 }, + { 0x0e, 0x0f, 0x01, 0x00, 0x0d } } } }; @@ -3408,8 +3401,9 @@ static const uint8_t X[4] = {6, 7, 4, 5}; static TORSION_INLINE uint32_t f1(uint32_t d, uint32_t m, uint32_t r) { + uint32_t c = -(uint32_t)(r != 0); uint32_t t = m + d; - uint32_t I = (t << r) | (t >> (32 - r));; + uint32_t I = (t << r) | (t >> ((32 - r) & c)); return (((S[0][(I >> 24) & 0xff] ^ S[1][(I >> 16) & 0xff]) @@ -3419,8 +3413,9 @@ f1(uint32_t d, uint32_t m, uint32_t r) { static TORSION_INLINE uint32_t f2(uint32_t d, uint32_t m, uint32_t r) { + uint32_t c = -(uint32_t)(r != 0); uint32_t t = m ^ d; - uint32_t I = (t << r) | (t >> (32 - r)); + uint32_t I = (t << r) | (t >> ((32 - r) & c)); return (((S[0][(I >> 24) & 0xff] - S[1][(I >> 16) & 0xff]) @@ -3430,8 +3425,9 @@ f2(uint32_t d, uint32_t m, uint32_t r) { static TORSION_INLINE uint32_t f3(uint32_t d, uint32_t m, uint32_t r) { + uint32_t c = -(uint32_t)(r != 0); uint32_t t = m - d; - uint32_t I = (t << r) | (t >> (32 - r)); + uint32_t I = (t << r) | (t >> ((32 - r) & c)); return (((S[0][(I >> 24) & 0xff] + S[1][(I >> 16) & 0xff]) @@ -3490,8 +3486,8 @@ cast5_init(cast5_t *ctx, const unsigned char *key) { } } -#define R(ctx, l, r, f, i) do { \ - uint32_t t = l; \ +#define R(f, i) do { \ + t = l; \ l = r; \ r = t ^ f(r, ctx->masking[i], ctx->rotate[i]); \ } while (0) @@ -3502,26 +3498,24 @@ cast5_encrypt(const cast5_t *ctx, const unsigned char *src) { uint32_t l = read32be(src + 0); uint32_t r = read32be(src + 4); + uint32_t t; - R(ctx, l, r, f1, 0); - R(ctx, l, r, f2, 1); - R(ctx, l, r, f3, 2); - R(ctx, l, r, f1, 3); - - R(ctx, l, r, f2, 4); - R(ctx, l, r, f3, 5); - R(ctx, l, r, f1, 6); - R(ctx, l, r, f2, 7); - - R(ctx, l, r, f3, 8); - R(ctx, l, r, f1, 9); - R(ctx, l, r, f2, 10); - R(ctx, l, r, f3, 11); - - R(ctx, l, r, f1, 12); - R(ctx, l, r, f2, 13); - R(ctx, l, r, f3, 14); - R(ctx, l, r, f1, 15); + R(f1, 0); + R(f2, 1); + R(f3, 2); + R(f1, 3); + R(f2, 4); + R(f3, 5); + R(f1, 6); + R(f2, 7); + R(f3, 8); + R(f1, 9); + R(f2, 10); + R(f3, 11); + R(f1, 12); + R(f2, 13); + R(f3, 14); + R(f1, 15); write32be(dst + 0, r); write32be(dst + 4, l); @@ -3533,26 +3527,24 @@ cast5_decrypt(const cast5_t *ctx, const unsigned char *src) { uint32_t l = read32be(src + 0); uint32_t r = read32be(src + 4); + uint32_t t; - R(ctx, l, r, f1, 15); - R(ctx, l, r, f3, 14); - R(ctx, l, r, f2, 13); - R(ctx, l, r, f1, 12); - - R(ctx, l, r, f3, 11); - R(ctx, l, r, f2, 10); - R(ctx, l, r, f1, 9); - R(ctx, l, r, f3, 8); - - R(ctx, l, r, f2, 7); - R(ctx, l, r, f1, 6); - R(ctx, l, r, f3, 5); - R(ctx, l, r, f2, 4); - - R(ctx, l, r, f1, 3); - R(ctx, l, r, f3, 2); - R(ctx, l, r, f2, 1); - R(ctx, l, r, f1, 0); + R(f1, 15); + R(f3, 14); + R(f2, 13); + R(f1, 12); + R(f3, 11); + R(f2, 10); + R(f1, 9); + R(f3, 8); + R(f2, 7); + R(f1, 6); + R(f3, 5); + R(f2, 4); + R(f1, 3); + R(f3, 2); + R(f2, 1); + R(f1, 0); write32be(dst + 0, r); write32be(dst + 4, l); @@ -3576,12 +3568,10 @@ cast5_decrypt(const cast5_t *ctx, */ static const uint8_t des_pc2_table[48] = { - /* inL => outL */ 0x0e, 0x0b, 0x11, 0x04, 0x1b, 0x17, 0x19, 0x00, 0x0d, 0x16, 0x07, 0x12, 0x05, 0x09, 0x10, 0x18, 0x02, 0x14, 0x0c, 0x15, 0x01, 0x08, 0x0f, 0x1a, - /* inR => outR */ 0x0f, 0x04, 0x19, 0x13, 0x09, 0x01, 0x1a, 0x10, 0x05, 0x0b, 0x17, 0x08, 0x0c, 0x07, 0x11, 0x00, 0x16, 0x03, 0x0a, 0x0e, 0x06, 0x14, 0x1b, 0x18 @@ -3804,14 +3794,14 @@ des_pc2(uint32_t *xl, uint32_t *xr) { uint32_t r = *xr; uint32_t u = 0; uint32_t v = 0; - int i = 0; + int i; - for (; i < 24; i++) { + for (i = 0; i < 24; i++) { u <<= 1; u |= (l >> des_pc2_table[i]) & 1; } - for (; i < 48; i++) { + for (i = 24; i < 48; i++) { v <<= 1; v |= (r >> des_pc2_table[i]) & 1; } @@ -3878,9 +3868,9 @@ des_permute(uint32_t s) { static void des_encipher(const des_t *ctx, uint32_t *xl, uint32_t *xr) { + uint32_t kl, kr, b1, b2, s, f, t; uint32_t l = *xl; uint32_t r = *xr; - uint32_t kl, kr, b1, b2, s, f, t; int i; /* Initial Permutation */ @@ -3914,9 +3904,9 @@ des_encipher(const des_t *ctx, uint32_t *xl, uint32_t *xr) { static void des_decipher(const des_t *ctx, uint32_t *xl, uint32_t *xr) { + uint32_t kl, kr, b1, b2, s, f, t; uint32_t l = *xr; uint32_t r = *xl; - uint32_t kl, kr, b1, b2, s, f, t; int i; /* Initial Permutation */ @@ -3952,6 +3942,7 @@ void des_init(des_t *ctx, const unsigned char *key) { uint32_t kl = read32be(key + 0); uint32_t kr = read32be(key + 4); + uint32_t k0, k1; int i, shift; /* Defensive memset. */ @@ -3965,11 +3956,13 @@ des_init(des_t *ctx, const unsigned char *key) { kl = des_r28shl(kl, shift); kr = des_r28shl(kr, shift); - ctx->keys[i + 0] = kl; - ctx->keys[i + 1] = kr; + k0 = kl; + k1 = kr; + + des_pc2(&k0, &k1); - des_pc2(&ctx->keys[i + 0], - &ctx->keys[i + 1]); + ctx->keys[i + 0] = k0; + ctx->keys[i + 1] = k1; } } @@ -4060,60 +4053,129 @@ des_ede3_decrypt(const des_ede3_t *ctx, * https://github.com/dgryski/go-idea/blob/master/idea.go */ -#define inv16 idea_invm16 -#define mul16 idea_mul16 +#undef HAVE_STRENGTH_REDUCTION -static uint16_t -inv16(uint16_t x) { - uint16_t y, q, t0, t1; +#if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER) +# if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ >= 8 +# define HAVE_STRENGTH_REDUCTION +# endif +#endif - if (x <= 1) - return x; +/* Constant-time IDEA. + * + * The code below assumes the compiler is strength + * reducing our modulo by 65537. This is achieved + * with something like: + * + * x - (mulhi(x, c) >> 16) + * + * Where `mulhi` does a wide multiplication and + * returns the high word, with following values + * of `c`: + * + * 0xffff0001 (32 bit) + * 0xffff0000ffff0001 (64 bit) + * + * Note: GCC & ICC strength-reduce the division + * at every optimization level (except for -Os), + * whereas clang requires -O1 or higher. Unsure + * what MSVC does here. + * + * The inverse mod 65537 can then be computed in + * constant-time by abusing a well-known property + * of Fermat's little theorem: + * + * x^65535 mod 65537 = x^-1 mod 65537 + * + * An exponent of 65535 (0xffff) makes things + * nice and simple. Normally left-to-right + * exponentiation (z = x^y mod n) follows an + * algorithm of: + * + * z = 1 + * for i = ceil(log2(y+1)) - 1 downto 0 + * z = z * z mod n + * if floor(y / 2^i) mod 2 == 1 + * z = z * x mod n + * + * This can be simplified in three ways: + * + * 1. The branch is not necessary as all bits + * in the exponent are set. + * + * 2. A 64-bit integer is wide enough to + * handle two multiplications of 17 bit + * integers, requiring only one modulo + * operation per iteration. i.e. + * + * z = z * z * x mod n + * + * 3. The first round simply assigns `z` + * to `x`, allowing us to initialize `z` + * as `x` and skip the first iteration. + * + * The result is the very simple loop you see + * below. Note that zero is handled properly as: + * + * 65536^-1 mod 65537 = 65536 + */ - t1 = UINT32_C(0x10001) / (uint32_t)x; - y = UINT32_C(0x10001) % (uint32_t)x; +#if defined(HAVE_STRENGTH_REDUCTION) - if (y == 1) - return 1 - t1; +static uint16_t +idea_mul(uint16_t x, uint16_t y) { + uint64_t u = x; + uint64_t v = y; - t0 = 1; + u |= 0x10000 & -((u - 1) >> 63); + v |= 0x10000 & -((v - 1) >> 63); - while (y != 1) { - q = x / y; - x = x % y; - t0 += q * t1; + return (u * v) % 0x10001; +} - if (x == 1) - return t0; +static uint16_t +idea_inv(uint16_t x) { + uint64_t z = x; + int i; - q = y / x; - y = y % x; - t1 += q * t0; - } + for (i = 0; i < 15; i++) + z = (z * z * x) % 0x10001; - return 1 - t1; + return z; } +#else /* !HAVE_STRENGTH_REDUCTION */ + static uint16_t -mul16(uint16_t x, uint16_t y) { - uint32_t t32; +idea_mul(uint16_t x, uint16_t y) { + uint32_t u = x; + uint32_t v = y; + uint32_t w = u * v; + uint32_t hi = w >> 16; + uint32_t lo = w & 0xffff; + uint32_t z = lo - hi + (lo < hi); - if (y == 0) - return 1 - x; + z |= (1 - u) & -((v - 1) >> 31); + z |= (1 - v) & -((u - 1) >> 31); - if (x == 0) - return 1 - y; + return z; +} - t32 = (uint32_t)x * (uint32_t)y; - x = t32; - y = t32 >> 16; +static uint16_t +idea_inv(uint16_t x) { + uint16_t z = x; + int i; - if (x < y) - return x - y + 1; + for (i = 0; i < 15; i++) { + z = idea_mul(z, z); + z = idea_mul(z, x); + } - return x - y; + return z; } +#endif /* !HAVE_STRENGTH_REDUCTION */ + void idea_init(idea_t *ctx, const unsigned char *key) { idea_init_encrypt(ctx, key); @@ -4123,9 +4185,8 @@ idea_init(idea_t *ctx, const unsigned char *key) { void idea_init_encrypt(idea_t *ctx, const unsigned char *key) { uint16_t *K = ctx->enckey; - int p = 0; - int j = 0; int i = 0; + int j = 0; /* Defensive memset. */ memset(ctx, 0, sizeof(*ctx)); @@ -4136,10 +4197,10 @@ idea_init_encrypt(idea_t *ctx, const unsigned char *key) { for (; j < 52; j++) { i += 1; - K[p + (i + 7)] = (K[p + ((i + 0) & 7)] << 9) - | (K[p + ((i + 1) & 7)] >> 7); + K[i + 7] = (K[(i + 0) & 7] << 9) + | (K[(i + 1) & 7] >> 7); - p += i & 8; + K += i & 8; i &= 7; } } @@ -4147,50 +4208,48 @@ idea_init_encrypt(idea_t *ctx, const unsigned char *key) { void idea_init_decrypt(idea_t *ctx) { uint16_t *K = ctx->enckey; - uint16_t *D = ctx->deckey; + uint16_t *D = ctx->deckey + 52; uint16_t t1, t2, t3; - int di = 52 - 1; - int ki = 0; int i; - t1 = inv16(K[ki++]); - t2 = -K[ki++]; - t3 = -K[ki++]; + t1 = idea_inv(*K++); + t2 = -*K++; + t3 = -*K++; - D[di--] = inv16(K[ki++]); - D[di--] = t3; - D[di--] = t2; - D[di--] = t1; + *--D = idea_inv(*K++); + *--D = t3; + *--D = t2; + *--D = t1; for (i = 0; i < 8 - 1; i++) { - t1 = K[ki++]; + t1 = *K++; - D[di--] = K[ki++]; - D[di--] = t1; + *--D = *K++; + *--D = t1; - t1 = inv16(K[ki++]); - t2 = -K[ki++]; - t3 = -K[ki++]; + t1 = idea_inv(*K++); + t2 = -*K++; + t3 = -*K++; - D[di--] = inv16(K[ki++]); - D[di--] = t2; - D[di--] = t3; - D[di--] = t1; + *--D = idea_inv(*K++); + *--D = t2; + *--D = t3; + *--D = t1; } - t1 = K[ki++]; + t1 = *K++; - D[di--] = K[ki++]; - D[di--] = t1; + *--D = *K++; + *--D = t1; - t1 = inv16(K[ki++]); - t2 = -K[ki++]; - t3 = -K[ki++]; + t1 = idea_inv(*K++); + t2 = -*K++; + t3 = -*K++; - D[di--] = inv16(K[ki++]); - D[di--] = t3; - D[di--] = t2; - D[di--] = t1; + *--D = idea_inv(*K++); + *--D = t3; + *--D = t2; + *--D = t1; } static void @@ -4201,23 +4260,22 @@ idea_crypt(unsigned char *dst, const unsigned char *src, const uint16_t *K) { uint16_t x4 = read16be(src + 6); uint16_t s2 = 0; uint16_t s3 = 0; - int p = 0; int i; for (i = 8 - 1; i >= 0; i--) { - x1 = mul16(x1, K[p++]); - x2 += K[p++]; - x3 += K[p++]; - x4 = mul16(x4, K[p++]); + x1 = idea_mul(x1, *K++); + x2 += *K++; + x3 += *K++; + x4 = idea_mul(x4, *K++); s3 = x3; x3 ^= x1; - x3 = mul16(x3, K[p++]); + x3 = idea_mul(x3, *K++); s2 = x2; x2 ^= x4; x2 += x3; - x2 = mul16(x2, K[p++]); + x2 = idea_mul(x2, *K++); x3 += x2; x1 ^= x2; @@ -4226,10 +4284,10 @@ idea_crypt(unsigned char *dst, const unsigned char *src, const uint16_t *K) { x3 ^= s2; } - x1 = mul16(x1, K[p++]); - x3 += K[p++]; - x2 += K[p++]; - x4 = mul16(x4, K[p++]); + x1 = idea_mul(x1, *K++); + x3 += *K++; + x2 += *K++; + x4 = idea_mul(x4, *K++); write16be(dst + 0, x1); write16be(dst + 2, x3); @@ -4247,9 +4305,6 @@ idea_decrypt(const idea_t *ctx, unsigned char *dst, const unsigned char *src) { idea_crypt(dst, src, ctx->deckey); } -#undef inv16 -#undef mul16 - /* * Serpent * @@ -4277,6 +4332,7 @@ idea_decrypt(const idea_t *ctx, unsigned char *dst, const unsigned char *src) { #define sb6inv serpent_sb6inv #define sb7 serpent_sb7 #define sb7inv serpent_sb7inv +#define xor4 serpent_xor4 static TORSION_INLINE void linear(uint32_t *v0, uint32_t *v1, uint32_t *v2, uint32_t *v3) { @@ -4613,6 +4669,15 @@ sb7inv(uint32_t *r0, uint32_t *r1, uint32_t *r2, uint32_t *r3) { *r2 = (t0 ^ *r1) ^ (*r0 ^ (v0 & *r3)); } +static TORSION_INLINE void +xor4(uint32_t *r0, uint32_t *r1, uint32_t *r2, uint32_t *r3, + const uint32_t *sk, int i0, int i1, int i2, int i3) { + *r0 ^= sk[i0]; + *r1 ^= sk[i1]; + *r2 ^= sk[i2]; + *r3 ^= sk[i3]; +} + void serpent_init(serpent_t *ctx, unsigned int bits, const unsigned char *key) { static const uint32_t phi = 0x9e3779b9; @@ -4644,7 +4709,7 @@ serpent_init(serpent_t *ctx, unsigned int bits, const unsigned char *key) { } for (i = 8; i < 132; i++) { - x = s[i - 8] ^ s[i - 5] ^ s[i - 3] ^ s[i - 1] ^ phi ^ (uint32_t)(i); + x = s[i - 8] ^ s[i - 5] ^ s[i - 3] ^ s[i - 1] ^ phi ^ (uint32_t)i; s[i] = (x << 11) | (x >> 21); } @@ -4697,109 +4762,107 @@ serpent_encrypt(const serpent_t *ctx, uint32_t r2 = read32le(src + 8); uint32_t r3 = read32le(src + 12); - r0 ^= sk[0], r1 ^= sk[1], r2 ^= sk[2], r3 ^= sk[3]; + xor4(&r0, &r1, &r2, &r3, sk, 0, 1, 2, 3); + sb0(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[4], r1 ^= sk[5], r2 ^= sk[6], r3 ^= sk[7]; + xor4(&r0, &r1, &r2, &r3, sk, 4, 5, 6, 7); sb1(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[8], r1 ^= sk[9], r2 ^= sk[10], r3 ^= sk[11]; + xor4(&r0, &r1, &r2, &r3, sk, 8, 9, 10, 11); sb2(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[12], r1 ^= sk[13], r2 ^= sk[14], r3 ^= sk[15]; + xor4(&r0, &r1, &r2, &r3, sk, 12, 13, 14, 15); sb3(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[16], r1 ^= sk[17], r2 ^= sk[18], r3 ^= sk[19]; + xor4(&r0, &r1, &r2, &r3, sk, 16, 17, 18, 19); sb4(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[20], r1 ^= sk[21], r2 ^= sk[22], r3 ^= sk[23]; + xor4(&r0, &r1, &r2, &r3, sk, 20, 21, 22, 23); sb5(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[24], r1 ^= sk[25], r2 ^= sk[26], r3 ^= sk[27]; + xor4(&r0, &r1, &r2, &r3, sk, 24, 25, 26, 27); sb6(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[28], r1 ^= sk[29], r2 ^= sk[30], r3 ^= sk[31]; + xor4(&r0, &r1, &r2, &r3, sk, 28, 29, 30, 31); sb7(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[32], r1 ^= sk[33], r2 ^= sk[34], r3 ^= sk[35]; + xor4(&r0, &r1, &r2, &r3, sk, 32, 33, 34, 35); sb0(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[36], r1 ^= sk[37], r2 ^= sk[38], r3 ^= sk[39]; + xor4(&r0, &r1, &r2, &r3, sk, 36, 37, 38, 39); sb1(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[40], r1 ^= sk[41], r2 ^= sk[42], r3 ^= sk[43]; + xor4(&r0, &r1, &r2, &r3, sk, 40, 41, 42, 43); sb2(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[44], r1 ^= sk[45], r2 ^= sk[46], r3 ^= sk[47]; + xor4(&r0, &r1, &r2, &r3, sk, 44, 45, 46, 47); sb3(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[48], r1 ^= sk[49], r2 ^= sk[50], r3 ^= sk[51]; + xor4(&r0, &r1, &r2, &r3, sk, 48, 49, 50, 51); sb4(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[52], r1 ^= sk[53], r2 ^= sk[54], r3 ^= sk[55]; + xor4(&r0, &r1, &r2, &r3, sk, 52, 53, 54, 55); sb5(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[56], r1 ^= sk[57], r2 ^= sk[58], r3 ^= sk[59]; + xor4(&r0, &r1, &r2, &r3, sk, 56, 57, 58, 59); sb6(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[60], r1 ^= sk[61], r2 ^= sk[62], r3 ^= sk[63]; + xor4(&r0, &r1, &r2, &r3, sk, 60, 61, 62, 63); sb7(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[64], r1 ^= sk[65], r2 ^= sk[66], r3 ^= sk[67]; + xor4(&r0, &r1, &r2, &r3, sk, 64, 65, 66, 67); sb0(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[68], r1 ^= sk[69], r2 ^= sk[70], r3 ^= sk[71]; + xor4(&r0, &r1, &r2, &r3, sk, 68, 69, 70, 71); sb1(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[72], r1 ^= sk[73], r2 ^= sk[74], r3 ^= sk[75]; + xor4(&r0, &r1, &r2, &r3, sk, 72, 73, 74, 75); sb2(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[76], r1 ^= sk[77], r2 ^= sk[78], r3 ^= sk[79]; + xor4(&r0, &r1, &r2, &r3, sk, 76, 77, 78, 79); sb3(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[80], r1 ^= sk[81], r2 ^= sk[82], r3 ^= sk[83]; + xor4(&r0, &r1, &r2, &r3, sk, 80, 81, 82, 83); sb4(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[84], r1 ^= sk[85], r2 ^= sk[86], r3 ^= sk[87]; + xor4(&r0, &r1, &r2, &r3, sk, 84, 85, 86, 87); sb5(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[88], r1 ^= sk[89], r2 ^= sk[90], r3 ^= sk[91]; + xor4(&r0, &r1, &r2, &r3, sk, 88, 89, 90, 91); sb6(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[92], r1 ^= sk[93], r2 ^= sk[94], r3 ^= sk[95]; + xor4(&r0, &r1, &r2, &r3, sk, 92, 93, 94, 95); sb7(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[96], r1 ^= sk[97], r2 ^= sk[98], r3 ^= sk[99]; + xor4(&r0, &r1, &r2, &r3, sk, 96, 97, 98, 99); sb0(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[100], r1 ^= sk[101], r2 ^= sk[102], r3 ^= sk[103]; + xor4(&r0, &r1, &r2, &r3, sk, 100, 101, 102, 103); sb1(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[104], r1 ^= sk[105], r2 ^= sk[106], r3 ^= sk[107]; + xor4(&r0, &r1, &r2, &r3, sk, 104, 105, 106, 107); sb2(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[108], r1 ^= sk[109], r2 ^= sk[110], r3 ^= sk[111]; + xor4(&r0, &r1, &r2, &r3, sk, 108, 109, 110, 111); sb3(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[112], r1 ^= sk[113], r2 ^= sk[114], r3 ^= sk[115]; + xor4(&r0, &r1, &r2, &r3, sk, 112, 113, 114, 115); sb4(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[116], r1 ^= sk[117], r2 ^= sk[118], r3 ^= sk[119]; + xor4(&r0, &r1, &r2, &r3, sk, 116, 117, 118, 119); sb5(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[120], r1 ^= sk[121], r2 ^= sk[122], r3 ^= sk[123]; + xor4(&r0, &r1, &r2, &r3, sk, 120, 121, 122, 123); sb6(&r0, &r1, &r2, &r3); linear(&r0, &r1, &r2, &r3); - r0 ^= sk[124], r1 ^= sk[125], r2 ^= sk[126], r3 ^= sk[127]; + xor4(&r0, &r1, &r2, &r3, sk, 124, 125, 126, 127); sb7(&r0, &r1, &r2, &r3); - r0 ^= sk[128]; - r1 ^= sk[129]; - r2 ^= sk[130]; - r3 ^= sk[131]; + xor4(&r0, &r1, &r2, &r3, sk, 128, 129, 130, 131); write32le(dst + 0, r0); write32le(dst + 4, r1); @@ -4817,113 +4880,107 @@ serpent_decrypt(const serpent_t *ctx, uint32_t r2 = read32le(src + 8); uint32_t r3 = read32le(src + 12); - r0 ^= sk[128]; - r1 ^= sk[129]; - r2 ^= sk[130]; - r3 ^= sk[131]; + xor4(&r0, &r1, &r2, &r3, sk, 128, 129, 130, 131); sb7inv(&r0, &r1, &r2, &r3); - r0 ^= sk[124], r1 ^= sk[125], r2 ^= sk[126], r3 ^= sk[127]; + xor4(&r0, &r1, &r2, &r3, sk, 124, 125, 126, 127); linearinv(&r0, &r1, &r2, &r3); sb6inv(&r0, &r1, &r2, &r3); - r0 ^= sk[120], r1 ^= sk[121], r2 ^= sk[122], r3 ^= sk[123]; + xor4(&r0, &r1, &r2, &r3, sk, 120, 121, 122, 123); linearinv(&r0, &r1, &r2, &r3); sb5inv(&r0, &r1, &r2, &r3); - r0 ^= sk[116], r1 ^= sk[117], r2 ^= sk[118], r3 ^= sk[119]; + xor4(&r0, &r1, &r2, &r3, sk, 116, 117, 118, 119); linearinv(&r0, &r1, &r2, &r3); sb4inv(&r0, &r1, &r2, &r3); - r0 ^= sk[112], r1 ^= sk[113], r2 ^= sk[114], r3 ^= sk[115]; + xor4(&r0, &r1, &r2, &r3, sk, 112, 113, 114, 115); linearinv(&r0, &r1, &r2, &r3); sb3inv(&r0, &r1, &r2, &r3); - r0 ^= sk[108], r1 ^= sk[109], r2 ^= sk[110], r3 ^= sk[111]; + xor4(&r0, &r1, &r2, &r3, sk, 108, 109, 110, 111); linearinv(&r0, &r1, &r2, &r3); sb2inv(&r0, &r1, &r2, &r3); - r0 ^= sk[104], r1 ^= sk[105], r2 ^= sk[106], r3 ^= sk[107]; + xor4(&r0, &r1, &r2, &r3, sk, 104, 105, 106, 107); linearinv(&r0, &r1, &r2, &r3); sb1inv(&r0, &r1, &r2, &r3); - r0 ^= sk[100], r1 ^= sk[101], r2 ^= sk[102], r3 ^= sk[103]; + xor4(&r0, &r1, &r2, &r3, sk, 100, 101, 102, 103); linearinv(&r0, &r1, &r2, &r3); sb0inv(&r0, &r1, &r2, &r3); - r0 ^= sk[96], r1 ^= sk[97], r2 ^= sk[98], r3 ^= sk[99]; + xor4(&r0, &r1, &r2, &r3, sk, 96, 97, 98, 99); linearinv(&r0, &r1, &r2, &r3); sb7inv(&r0, &r1, &r2, &r3); - r0 ^= sk[92], r1 ^= sk[93], r2 ^= sk[94], r3 ^= sk[95]; + xor4(&r0, &r1, &r2, &r3, sk, 92, 93, 94, 95); linearinv(&r0, &r1, &r2, &r3); sb6inv(&r0, &r1, &r2, &r3); - r0 ^= sk[88], r1 ^= sk[89], r2 ^= sk[90], r3 ^= sk[91]; + xor4(&r0, &r1, &r2, &r3, sk, 88, 89, 90, 91); linearinv(&r0, &r1, &r2, &r3); sb5inv(&r0, &r1, &r2, &r3); - r0 ^= sk[84], r1 ^= sk[85], r2 ^= sk[86], r3 ^= sk[87]; + xor4(&r0, &r1, &r2, &r3, sk, 84, 85, 86, 87); linearinv(&r0, &r1, &r2, &r3); sb4inv(&r0, &r1, &r2, &r3); - r0 ^= sk[80], r1 ^= sk[81], r2 ^= sk[82], r3 ^= sk[83]; + xor4(&r0, &r1, &r2, &r3, sk, 80, 81, 82, 83); linearinv(&r0, &r1, &r2, &r3); sb3inv(&r0, &r1, &r2, &r3); - r0 ^= sk[76], r1 ^= sk[77], r2 ^= sk[78], r3 ^= sk[79]; + xor4(&r0, &r1, &r2, &r3, sk, 76, 77, 78, 79); linearinv(&r0, &r1, &r2, &r3); sb2inv(&r0, &r1, &r2, &r3); - r0 ^= sk[72], r1 ^= sk[73], r2 ^= sk[74], r3 ^= sk[75]; + xor4(&r0, &r1, &r2, &r3, sk, 72, 73, 74, 75); linearinv(&r0, &r1, &r2, &r3); sb1inv(&r0, &r1, &r2, &r3); - r0 ^= sk[68], r1 ^= sk[69], r2 ^= sk[70], r3 ^= sk[71]; + xor4(&r0, &r1, &r2, &r3, sk, 68, 69, 70, 71); linearinv(&r0, &r1, &r2, &r3); sb0inv(&r0, &r1, &r2, &r3); - r0 ^= sk[64], r1 ^= sk[65], r2 ^= sk[66], r3 ^= sk[67]; + xor4(&r0, &r1, &r2, &r3, sk, 64, 65, 66, 67); linearinv(&r0, &r1, &r2, &r3); sb7inv(&r0, &r1, &r2, &r3); - r0 ^= sk[60], r1 ^= sk[61], r2 ^= sk[62], r3 ^= sk[63]; + xor4(&r0, &r1, &r2, &r3, sk, 60, 61, 62, 63); linearinv(&r0, &r1, &r2, &r3); sb6inv(&r0, &r1, &r2, &r3); - r0 ^= sk[56], r1 ^= sk[57], r2 ^= sk[58], r3 ^= sk[59]; + xor4(&r0, &r1, &r2, &r3, sk, 56, 57, 58, 59); linearinv(&r0, &r1, &r2, &r3); sb5inv(&r0, &r1, &r2, &r3); - r0 ^= sk[52], r1 ^= sk[53], r2 ^= sk[54], r3 ^= sk[55]; + xor4(&r0, &r1, &r2, &r3, sk, 52, 53, 54, 55); linearinv(&r0, &r1, &r2, &r3); sb4inv(&r0, &r1, &r2, &r3); - r0 ^= sk[48], r1 ^= sk[49], r2 ^= sk[50], r3 ^= sk[51]; + xor4(&r0, &r1, &r2, &r3, sk, 48, 49, 50, 51); linearinv(&r0, &r1, &r2, &r3); sb3inv(&r0, &r1, &r2, &r3); - r0 ^= sk[44], r1 ^= sk[45], r2 ^= sk[46], r3 ^= sk[47]; + xor4(&r0, &r1, &r2, &r3, sk, 44, 45, 46, 47); linearinv(&r0, &r1, &r2, &r3); sb2inv(&r0, &r1, &r2, &r3); - r0 ^= sk[40], r1 ^= sk[41], r2 ^= sk[42], r3 ^= sk[43]; + xor4(&r0, &r1, &r2, &r3, sk, 40, 41, 42, 43); linearinv(&r0, &r1, &r2, &r3); sb1inv(&r0, &r1, &r2, &r3); - r0 ^= sk[36], r1 ^= sk[37], r2 ^= sk[38], r3 ^= sk[39]; + xor4(&r0, &r1, &r2, &r3, sk, 36, 37, 38, 39); linearinv(&r0, &r1, &r2, &r3); sb0inv(&r0, &r1, &r2, &r3); - r0 ^= sk[32], r1 ^= sk[33], r2 ^= sk[34], r3 ^= sk[35]; + xor4(&r0, &r1, &r2, &r3, sk, 32, 33, 34, 35); linearinv(&r0, &r1, &r2, &r3); sb7inv(&r0, &r1, &r2, &r3); - r0 ^= sk[28], r1 ^= sk[29], r2 ^= sk[30], r3 ^= sk[31]; + xor4(&r0, &r1, &r2, &r3, sk, 28, 29, 30, 31); linearinv(&r0, &r1, &r2, &r3); sb6inv(&r0, &r1, &r2, &r3); - r0 ^= sk[24], r1 ^= sk[25], r2 ^= sk[26], r3 ^= sk[27]; + xor4(&r0, &r1, &r2, &r3, sk, 24, 25, 26, 27); linearinv(&r0, &r1, &r2, &r3); sb5inv(&r0, &r1, &r2, &r3); - r0 ^= sk[20], r1 ^= sk[21], r2 ^= sk[22], r3 ^= sk[23]; + xor4(&r0, &r1, &r2, &r3, sk, 20, 21, 22, 23); linearinv(&r0, &r1, &r2, &r3); sb4inv(&r0, &r1, &r2, &r3); - r0 ^= sk[16], r1 ^= sk[17], r2 ^= sk[18], r3 ^= sk[19]; + xor4(&r0, &r1, &r2, &r3, sk, 16, 17, 18, 19); linearinv(&r0, &r1, &r2, &r3); sb3inv(&r0, &r1, &r2, &r3); - r0 ^= sk[12], r1 ^= sk[13], r2 ^= sk[14], r3 ^= sk[15]; + xor4(&r0, &r1, &r2, &r3, sk, 12, 13, 14, 15); linearinv(&r0, &r1, &r2, &r3); sb2inv(&r0, &r1, &r2, &r3); - r0 ^= sk[8], r1 ^= sk[9], r2 ^= sk[10], r3 ^= sk[11]; + xor4(&r0, &r1, &r2, &r3, sk, 8, 9, 10, 11); linearinv(&r0, &r1, &r2, &r3); sb1inv(&r0, &r1, &r2, &r3); - r0 ^= sk[4], r1 ^= sk[5], r2 ^= sk[6], r3 ^= sk[7]; + xor4(&r0, &r1, &r2, &r3, sk, 4, 5, 6, 7); linearinv(&r0, &r1, &r2, &r3); sb0inv(&r0, &r1, &r2, &r3); - r0 ^= sk[0]; - r1 ^= sk[1]; - r2 ^= sk[2]; - r3 ^= sk[3]; + xor4(&r0, &r1, &r2, &r3, sk, 0, 1, 2, 3); write32le(dst + 0, r0); write32le(dst + 4, r1); @@ -4949,6 +5006,7 @@ serpent_decrypt(const serpent_t *ctx, #undef sb6inv #undef sb7 #undef sb7inv +#undef xor4 /* * Twofish @@ -5434,7 +5492,7 @@ pkcs7_unpad(unsigned char *dst, */ size_t -cipher_key_size(int type) { +cipher_key_size(cipher_id_t type) { switch (type) { case CIPHER_AES128: return 16; @@ -5490,7 +5548,7 @@ cipher_key_size(int type) { } size_t -cipher_block_size(int type) { +cipher_block_size(cipher_id_t type) { switch (type) { case CIPHER_AES128: return 16; @@ -5546,7 +5604,10 @@ cipher_block_size(int type) { } int -cipher_init(cipher_t *ctx, int type, const unsigned char *key, size_t key_len) { +cipher_init(cipher_t *ctx, + cipher_id_t type, + const unsigned char *key, + size_t key_len) { ctx->type = type; ctx->size = cipher_block_size(type); @@ -5997,37 +6058,39 @@ cbc_decrypt(cbc_t *mode, const cipher_t *cipher, unsigned char *dst, const unsigned char *src, size_t len) { size_t i; - CHECK((len & (cipher->size - 1)) == 0); - if (dst == src) { - unsigned char prev[CIPHER_MAX_BLOCK_SIZE]; + unsigned char tmp[CIPHER_MAX_BLOCK_SIZE]; - while (len > 0) { - memcpy(prev, mode->prev, cipher->size); - memcpy(mode->prev, src, cipher->size); - - cipher_decrypt(cipher, dst, src); - - for (i = 0; i < cipher->size; i++) - dst[i] ^= prev[i]; + CHECK((len & (cipher->size - 1)) == 0); - dst += cipher->size; - src += cipher->size; - len -= cipher->size; - } - } else { while (len > 0) { - cipher_decrypt(cipher, dst, src); + cipher_decrypt(cipher, tmp, src); for (i = 0; i < cipher->size; i++) - dst[i] ^= mode->prev[i]; + tmp[i] ^= mode->prev[i]; memcpy(mode->prev, src, cipher->size); + memcpy(dst, tmp, cipher->size); dst += cipher->size; src += cipher->size; len -= cipher->size; } + + torsion_memzero(tmp, cipher->size); + } else if (len > 0) { + ecb_decrypt(cipher, dst, src, len); + + for (i = 0; i < cipher->size; i++) + dst[i] ^= mode->prev[i]; + + dst += cipher->size; + len -= cipher->size; + + for (i = 0; i < len; i++) + dst[i] ^= src[i]; + + memcpy(mode->prev, src + len, cipher->size); } } @@ -6080,7 +6143,7 @@ cbc_unsteal(cbc_t *mode, for (i = 0; i < cipher->size; i++) last[i] ^= tmp[i]; - torsion_cleanse(tmp, cipher->size); + torsion_memzero(tmp, cipher->size); } /* @@ -6103,29 +6166,26 @@ xts_setup(xts_t *mode, const cipher_t *cipher, cipher_encrypt(&c, mode->tweak, mode->tweak); - torsion_cleanse(&c, sizeof(c)); + torsion_memzero(&c, sizeof(c)); return 1; } static void xts_shift(uint8_t *dst, const uint8_t *src, size_t size) { + /* Little-endian doubling. */ uint32_t poly = poly_table[size >> 4]; - uint8_t cy = 0; - uint8_t c; + uint8_t c = src[size - 1] >> 7; size_t i; - for (i = 0; i < size; i++) { - c = src[i] >> 7; + for (i = size - 1; i >= 1; i--) + dst[i] = (src[i] << 1) | (src[i - 1] >> 7); - dst[i] = (src[i] << 1) | cy; + dst[0] = src[0] << 1; - cy = c; - } - - dst[2] ^= (uint8_t)(poly >> 16) & -cy; - dst[1] ^= (uint8_t)(poly >> 8) & -cy; - dst[0] ^= (uint8_t)(poly >> 0) & -cy; + dst[2] ^= (uint8_t)(poly >> 16) & -c; + dst[1] ^= (uint8_t)(poly >> 8) & -c; + dst[0] ^= (uint8_t)(poly >> 0) & -c; } void @@ -6260,39 +6320,91 @@ xts_unsteal(xts_t *mode, last[i] ^= mode->prev[i]; } +/* + * Stream (Abstract) + */ + +/* Avoid violating ISO C section 7.1.3. */ +#define stream_f xstream_f +#define stream_update xstream_update + +typedef void stream_f(stream_mode_t *mode, const cipher_t *cipher); +typedef void xor_f(stream_mode_t *mode, size_t pos, unsigned char *dst, + const unsigned char *src, size_t len); + +static TORSION_INLINE void +stream_update(stream_mode_t *mode, + const cipher_t *cipher, + stream_f *stream, + xor_f *permute, + unsigned char *dst, + const unsigned char *src, + size_t len) { + size_t size = cipher->size; + size_t pos = mode->pos; + size_t want = size - pos; + + if (len >= want) { + if (pos > 0) { + permute(mode, pos, dst, src, want); + + dst += want; + src += want; + len -= want; + pos = 0; + } + + while (len >= size) { + stream(mode, cipher); + + permute(mode, 0, dst, src, size); + + dst += size; + src += size; + len -= size; + } + } + + if (len > 0) { + if (pos == 0) + stream(mode, cipher); + + permute(mode, pos, dst, src, len); + + pos += len; + } + + mode->pos = pos; +} + /* * CTR */ void ctr_init(ctr_t *mode, const cipher_t *cipher, const unsigned char *iv) { - memcpy(mode->ctr, iv, cipher->size); + memcpy(mode->iv, iv, cipher->size); /* Defensive memset. */ memset(mode->state, 0, cipher->size); mode->pos = 0; } +static void +ctr_stream(ctr_t *mode, const cipher_t *cipher) { + cipher_encrypt(cipher, mode->state, mode->iv); + increment_be_var(mode->iv, cipher->size); +} + +static void +ctr_xor(ctr_t *mode, size_t pos, unsigned char *dst, + const unsigned char *src, size_t len) { + torsion_memxor3(dst, src, mode->state + pos, len); +} + void ctr_crypt(ctr_t *mode, const cipher_t *cipher, unsigned char *dst, const unsigned char *src, size_t len) { - size_t mask = cipher->size - 1; - size_t i; - int j; - - for (i = 0; i < len; i++) { - if ((mode->pos & mask) == 0) { - cipher_encrypt(cipher, mode->state, mode->ctr); - - for (j = cipher->size - 1; j >= 0; j--) { - if (++mode->ctr[j] != 0x00) - break; - } - - mode->pos = 0; - } - - dst[i] = src[i] ^ mode->state[mode->pos++]; - } + stream_update(mode, cipher, ctr_stream, ctr_xor, dst, src, len); } /* @@ -6301,50 +6413,41 @@ ctr_crypt(ctr_t *mode, const cipher_t *cipher, void cfb_init(cfb_t *mode, const cipher_t *cipher, const unsigned char *iv) { - memcpy(mode->prev, iv, cipher->size); + memcpy(mode->iv, iv, cipher->size); /* Defensive memset. */ memset(mode->state, 0, cipher->size); mode->pos = 0; } -void -cfb_encrypt(cfb_t *mode, const cipher_t *cipher, - unsigned char *dst, const unsigned char *src, size_t len) { - size_t mask = cipher->size - 1; - size_t i; - - for (i = 0; i < len; i++) { - if ((mode->pos & mask) == 0) { - cipher_encrypt(cipher, mode->state, mode->prev); - mode->pos = 0; - } +static void +cfb_stream(cfb_t *mode, const cipher_t *cipher) { + cipher_encrypt(cipher, mode->state, mode->iv); +} - dst[i] = src[i] ^ mode->state[mode->pos]; +static void +cfb_xor_enc(cfb_t *mode, size_t pos, unsigned char *dst, + const unsigned char *src, size_t len) { + torsion_memxor3(dst, src, mode->state + pos, len); + memcpy(mode->iv + pos, dst, len); +} - mode->prev[mode->pos] = dst[i]; +static void +cfb_xor_dec(cfb_t *mode, size_t pos, unsigned char *dst, + const unsigned char *src, size_t len) { + memcpy(mode->iv + pos, src, len); + torsion_memxor3(dst, src, mode->state + pos, len); +} - mode->pos += 1; - } +void +cfb_encrypt(cfb_t *mode, const cipher_t *cipher, + unsigned char *dst, const unsigned char *src, size_t len) { + stream_update(mode, cipher, cfb_stream, cfb_xor_enc, dst, src, len); } void cfb_decrypt(cfb_t *mode, const cipher_t *cipher, unsigned char *dst, const unsigned char *src, size_t len) { - size_t mask = cipher->size - 1; - size_t i; - - for (i = 0; i < len; i++) { - if ((mode->pos & mask) == 0) { - cipher_encrypt(cipher, mode->state, mode->prev); - mode->pos = 0; - } - - mode->prev[mode->pos] = src[i]; - - dst[i] = src[i] ^ mode->state[mode->pos]; - - mode->pos += 1; - } + stream_update(mode, cipher, cfb_stream, cfb_xor_dec, dst, src, len); } /* @@ -6357,20 +6460,15 @@ ofb_init(ofb_t *mode, const cipher_t *cipher, const unsigned char *iv) { mode->pos = 0; } +static void +ofb_stream(ofb_t *mode, const cipher_t *cipher) { + cipher_encrypt(cipher, mode->state, mode->state); +} + void ofb_crypt(ofb_t *mode, const cipher_t *cipher, unsigned char *dst, const unsigned char *src, size_t len) { - size_t mask = cipher->size - 1; - size_t i; - - for (i = 0; i < len; i++) { - if ((mode->pos & mask) == 0) { - cipher_encrypt(cipher, mode->state, mode->state); - mode->pos = 0; - } - - dst[i] = src[i] ^ mode->state[mode->pos++]; - } + stream_update(mode, cipher, ofb_stream, ctr_xor, dst, src, len); } /* @@ -6384,8 +6482,8 @@ ofb_crypt(ofb_t *mode, const cipher_t *cipher, * https://github.com/DaGenix/rust-crypto/blob/master/src/ghash.rs */ -typedef struct __ghash_s ghash_t; -typedef struct __ghash_fe_s gfe_t; +typedef struct ghash_s ghash_t; +typedef struct ghash_fe_s gfe_t; static const uint16_t ghash_reduction[16] = { 0x0000, 0x1c20, 0x3840, 0x2460, @@ -6418,9 +6516,10 @@ gfe_dbl(gfe_t *z, const gfe_t *x) { } static void -gfe_mul(gfe_t *r, const gfe_t *x, const gfe_t *table) { +gfe_mul(gfe_t *z, const gfe_t *x, const gfe_t *table) { uint64_t word, msw; - gfe_t z = {0, 0}; + uint64_t lo = 0; + uint64_t hi = 0; const gfe_t *t; int i, j; @@ -6431,24 +6530,24 @@ gfe_mul(gfe_t *r, const gfe_t *x, const gfe_t *table) { word = x->lo; for (j = 0; j < 64; j += 4) { - msw = z.hi & 0x0f; + msw = hi & 0x0f; - z.hi >>= 4; - z.hi |= z.lo << 60; - z.lo >>= 4; - z.lo ^= (uint64_t)ghash_reduction[msw] << 48; + hi >>= 4; + hi |= lo << 60; + lo >>= 4; + lo ^= (uint64_t)ghash_reduction[msw] << 48; t = &table[word & 0x0f]; - z.lo ^= t->lo; - z.hi ^= t->hi; + lo ^= t->lo; + hi ^= t->hi; word >>= 4; } } - r->lo = z.lo; - r->hi = z.hi; + z->lo = lo; + z->hi = hi; } static void @@ -6461,53 +6560,51 @@ ghash_transform(ghash_t *ctx, const unsigned char *block) { static void ghash_absorb(ghash_t *ctx, const unsigned char *data, size_t len) { - size_t pos = ctx->size & 15; - size_t off = 0; - - if (len == 0) - return; - - ctx->size += len; + const unsigned char *raw = data; + size_t pos = ctx->pos; + size_t want = 16 - pos; - if (pos > 0) { - size_t want = 16 - pos; + if (len >= want) { + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - if (want > len) - want = len; + raw += want; + len -= want; + pos = 0; - memcpy(ctx->block + pos, data, want); - - pos += want; - len -= want; - off += want; - - if (pos < 16) - return; + ghash_transform(ctx, ctx->block); + } - ghash_transform(ctx, ctx->block); + while (len >= 16) { + ghash_transform(ctx, raw); + raw += 16; + len -= 16; + } } - while (len >= 16) { - ghash_transform(ctx, data + off); - off += 16; - len -= 16; + if (len > 0) { + memcpy(ctx->block + pos, raw, len); + pos += len; } - if (len > 0) - memcpy(ctx->block, data + off, len); + ctx->pos = pos; } static void ghash_pad(ghash_t *ctx) { - size_t pos = ctx->size & 15; + if (ctx->pos > 0) { + while (ctx->pos < 16) + ctx->block[ctx->pos++] = 0; + + ghash_transform(ctx, ctx->block); - if (pos > 0) - ghash_absorb(ctx, zero64, 16 - pos); + ctx->pos = 0; + } } static void ghash_init(ghash_t *ctx, const unsigned char *key) { - gfe_t x = {0, 0}; + gfe_t x; int i; /* Zero for struct assignment. */ @@ -6531,7 +6628,7 @@ ghash_init(ghash_t *ctx, const unsigned char *key) { ctx->adlen = 0; ctx->ctlen = 0; - ctx->size = 0; + ctx->pos = 0; } static void @@ -6542,9 +6639,6 @@ ghash_aad(ghash_t *ctx, const unsigned char *data, size_t len) { static void ghash_update(ghash_t *ctx, const unsigned char *data, size_t len) { - if (len == 0) - return; - if (ctx->ctlen == 0) ghash_pad(ctx); @@ -6570,39 +6664,27 @@ ghash_final(ghash_t *ctx, unsigned char *out) { * GCM */ +static void +gcm_stream(ctr_t *ctr, const cipher_t *cipher) { + cipher_encrypt(cipher, ctr->state, ctr->iv); + increment_be(ctr->iv + 12, 4); +} + static void gcm_crypt(gcm_t *mode, const cipher_t *cipher, unsigned char *dst, const unsigned char *src, size_t len) { - unsigned int cy; - size_t i; - int j; - - for (i = 0; i < len; i++) { - if ((mode->pos & 15) == 0) { - cipher_encrypt(cipher, mode->state, mode->ctr); - - cy = 1; - - for (j = 16 - 1; j >= 12; j--) { - cy += (unsigned int)mode->ctr[j]; - mode->ctr[j] = cy; - cy >>= 8; - } - - mode->pos = 0; - } - - dst[i] = src[i] ^ mode->state[mode->pos++]; - } + stream_update(&mode->ctr, cipher, gcm_stream, ctr_xor, dst, src, len); } int gcm_init(gcm_t *mode, const cipher_t *cipher, const unsigned char *iv, size_t iv_len) { static const unsigned char initial[4] = {0, 0, 0, 1}; + static const unsigned char zero16[16] = {0}; + ctr_t *ctr = &mode->ctr; unsigned char key[16]; if (cipher->size != 16) { @@ -6611,24 +6693,24 @@ gcm_init(gcm_t *mode, const cipher_t *cipher, } /* Defensive memset. */ - memset(mode->state, 0, 16); - memset(mode->ctr, 0, 16); + memset(ctr->state, 0, 16); + memset(ctr->iv, 0, 16); - mode->pos = 0; + ctr->pos = 0; - gcm_crypt(mode, cipher, key, zero64, 16); + gcm_crypt(mode, cipher, key, zero16, 16); if (iv_len == 12) { - memcpy(mode->ctr, iv, 12); - memcpy(mode->ctr + 12, initial, 4); + memcpy(ctr->iv, iv, 12); + memcpy(ctr->iv + 12, initial, 4); } else { ghash_init(&mode->hash, key); ghash_update(&mode->hash, iv, iv_len); - ghash_final(&mode->hash, mode->ctr); + ghash_final(&mode->hash, ctr->iv); } ghash_init(&mode->hash, key); - gcm_crypt(mode, cipher, mode->mask, zero64, 16); + gcm_crypt(mode, cipher, mode->mask, zero16, 16); return 1; } @@ -6666,7 +6748,7 @@ gcm_digest(gcm_t *mode, unsigned char *mac) { * CBC-MAC */ -typedef struct __cmac_s cbcmac_t; +typedef struct cmac_s cbcmac_t; static void cbcmac_init(cbcmac_t *ctx, const cipher_t *cipher) { @@ -6677,16 +6759,37 @@ cbcmac_init(cbcmac_t *ctx, const cipher_t *cipher) { static void cbcmac_update(cbcmac_t *ctx, const cipher_t *cipher, const unsigned char *data, size_t len) { - size_t i; + const unsigned char *raw = data; + size_t pos = ctx->pos; + size_t want = cipher->size - pos; - for (i = 0; i < len; i++) { - ctx->mac[ctx->pos++] ^= data[i]; + if (len >= want) { + if (pos > 0) { + torsion_memxor(ctx->mac + pos, raw, want); - if (ctx->pos == cipher->size) { cipher_encrypt(cipher, ctx->mac, ctx->mac); - ctx->pos = 0; + + raw += want; + len -= want; + pos = 0; + } + + while (len >= cipher->size) { + torsion_memxor(ctx->mac, raw, cipher->size); + + cipher_encrypt(cipher, ctx->mac, ctx->mac); + + raw += cipher->size; + len -= cipher->size; } } + + if (len > 0) { + torsion_memxor(ctx->mac + pos, raw, len); + pos += len; + } + + ctx->pos = pos; } static void @@ -6711,6 +6814,8 @@ cbcmac_final(cbcmac_t *ctx, const cipher_t *cipher, unsigned char *mac) { int ccm_init(ccm_t *mode, const cipher_t *cipher, const unsigned char *iv, size_t iv_len) { + ctr_t *ctr = &mode->ctr; + /* CCM is specified to have a block size of 16. */ if (cipher->size != 16) goto fail; @@ -6726,14 +6831,14 @@ ccm_init(ccm_t *mode, const cipher_t *cipher, cbcmac_init(&mode->hash, cipher); /* Defensive memsets. */ - memset(mode->ctr, 0, 16); - memset(mode->state + iv_len, 0, 16 - iv_len); + memset(ctr->iv, 0, 16); + memset(ctr->state, 0, 16); /* Store the IV here for now. Note that ccm_setup _must_ be called after this. */ - memcpy(mode->state, iv, iv_len); + memcpy(ctr->state, iv, iv_len); - mode->pos = iv_len; + ctr->pos = iv_len; return 1; fail: @@ -6741,29 +6846,30 @@ ccm_init(ccm_t *mode, const cipher_t *cipher, return 0; } -static unsigned int -ccm_log256(size_t lm) { - unsigned int L = 0; +static size_t +ccm_log256(size_t x) { + size_t z = 0; - while (lm > 0) { - L += 1; - lm >>= 1; + while (x > 0) { + x >>= 1; + z += 1; } - L = (L + 7) / 8; + z = (z + 7) / 8; - if (L < 2) - L = 2; + if (z < 2) + z = 2; - return L; + return z; } int ccm_setup(ccm_t *mode, const cipher_t *cipher, size_t msg_len, size_t tag_len, const unsigned char *aad, size_t aad_len) { - const unsigned char *iv = mode->state; - size_t iv_len = mode->pos; + ctr_t *ctr = &mode->ctr; + const unsigned char *iv = ctr->state; + size_t iv_len = ctr->pos; unsigned char block[16]; size_t Adata = (aad_len > 0); size_t lm = msg_len; @@ -6810,13 +6916,16 @@ ccm_setup(ccm_t *mode, const cipher_t *cipher, unsigned char buf[10]; if (aad_len < 0xff00) { + /* 0 < l(a) < (2^16 - 2^8) */ write16be(buf, aad_len); cbcmac_update(&mode->hash, cipher, buf, 2); - } else if (aad_len < 0xffffffff) { + } else if (aad_len - 1 < 0xffffffff) { + /* (2^16 - 2^8) <= l(a) < 2^32 */ write16be(buf + 0, 0xfffe); write32be(buf + 2, aad_len); cbcmac_update(&mode->hash, cipher, buf, 6); } else { + /* 2^32 <= l(a) < 2^64 */ write16be(buf + 0, 0xffff); write64be(buf + 2, aad_len); cbcmac_update(&mode->hash, cipher, buf, 10); @@ -6832,9 +6941,9 @@ ccm_setup(ccm_t *mode, const cipher_t *cipher, for (i = 14; i >= 1 + N; i--) block[i] = 0; - memcpy(mode->ctr, block, 16); + memcpy(ctr->iv, block, 16); - mode->pos = 0; + ctr->pos = 0; return 1; } @@ -6842,23 +6951,7 @@ ccm_setup(ccm_t *mode, const cipher_t *cipher, static void ccm_crypt(ccm_t *mode, const cipher_t *cipher, unsigned char *dst, const unsigned char *src, size_t len) { - size_t i; - int j; - - for (i = 0; i < len; i++) { - if ((mode->pos & 15) == 0) { - cipher_encrypt(cipher, mode->state, mode->ctr); - - for (j = 16 - 1; j >= 1; j--) { - if (++mode->ctr[j] != 0x00) - break; - } - - mode->pos = 0; - } - - dst[i] = src[i] ^ mode->state[mode->pos++]; - } + ctr_crypt(&mode->ctr, cipher, dst, src, len); } void @@ -6877,15 +6970,16 @@ ccm_decrypt(ccm_t *mode, const cipher_t *cipher, void ccm_digest(ccm_t *mode, const cipher_t *cipher, unsigned char *mac) { - int i = 16 - ((mode->ctr[0] & 7) + 1); + ctr_t *ctr = &mode->ctr; + int i = 16 - ((ctr->iv[0] & 7) + 1); cbcmac_final(&mode->hash, cipher, mac); /* Recreate S_0. */ while (i < 16) - mode->ctr[i++] = 0; + ctr->iv[i++] = 0; - mode->pos = 0; + ctr->pos = 0; ccm_crypt(mode, cipher, mac, mac, 16); } @@ -6895,7 +6989,7 @@ ccm_digest(ccm_t *mode, const cipher_t *cipher, unsigned char *mac) { * https://tools.ietf.org/html/rfc4493 */ -typedef struct __cmac_s cmac_t; +typedef struct cmac_s cmac_t; static void cmac_init(cmac_t *ctx, const cipher_t *cipher, int flag) { @@ -6904,52 +6998,71 @@ cmac_init(cmac_t *ctx, const cipher_t *cipher, int flag) { ctx->pos = 0; if (flag != -1) { - ctx->mac[cipher->size - 1] ^= (unsigned char)flag; + ctx->mac[cipher->size - 1] ^= (flag & 0xff); ctx->pos = cipher->size; } } static void cmac_shift(uint8_t *dst, const uint8_t *src, size_t size) { + /* Big-endian doubling. */ uint32_t poly = poly_table[size >> 4]; - size_t i = size; - uint8_t cy = 0; - uint8_t c; + uint8_t c = src[0] >> 7; + size_t i; - while (i--) { - c = src[i] >> 7; + for (i = 0; i < size - 1; i++) + dst[i] = (src[i] << 1) | (src[i + 1] >> 7); - dst[i] = (src[i] << 1) | cy; + dst[size - 1] = src[size - 1] << 1; - cy = c; - } - - dst[size - 3] ^= (uint8_t)(poly >> 16) & -cy; - dst[size - 2] ^= (uint8_t)(poly >> 8) & -cy; - dst[size - 1] ^= (uint8_t)(poly >> 0) & -cy; + dst[size - 3] ^= (uint8_t)(poly >> 16) & -c; + dst[size - 2] ^= (uint8_t)(poly >> 8) & -c; + dst[size - 1] ^= (uint8_t)(poly >> 0) & -c; } static void cmac_update(cmac_t *ctx, const cipher_t *cipher, const unsigned char *data, size_t len) { - size_t i; + const unsigned char *raw = data; + size_t pos = ctx->pos; + size_t want = cipher->size - pos; + + if (len > want) { + if (pos > 0) { + torsion_memxor(ctx->mac + pos, raw, want); + + cipher_encrypt(cipher, ctx->mac, ctx->mac); + + raw += want; + len -= want; + pos = 0; + } + + while (len > cipher->size) { + torsion_memxor(ctx->mac, raw, cipher->size); - for (i = 0; i < len; i++) { - if (ctx->pos == cipher->size) { cipher_encrypt(cipher, ctx->mac, ctx->mac); - ctx->pos = 0; + + raw += cipher->size; + len -= cipher->size; } + } - ctx->mac[ctx->pos++] ^= data[i]; + if (len > 0) { + torsion_memxor(ctx->mac + pos, raw, len); + pos += len; } + + ctx->pos = pos; } static void cmac_final(cmac_t *ctx, const cipher_t *cipher, unsigned char *mac) { + static const unsigned char zero[CIPHER_MAX_BLOCK_SIZE] = {0}; unsigned char k[CIPHER_MAX_BLOCK_SIZE]; size_t i; - cipher_encrypt(cipher, k, zero64); + cipher_encrypt(cipher, k, zero); cmac_shift(k, k, cipher->size); @@ -6971,21 +7084,23 @@ cmac_final(cmac_t *ctx, const cipher_t *cipher, unsigned char *mac) { int eax_init(eax_t *mode, const cipher_t *cipher, const unsigned char *iv, size_t iv_len) { + ctr_t *ctr = &mode->ctr; + if (iv_len == 0) { memset(mode, 0, sizeof(*mode)); return 0; } - mode->pos = 0; + ctr->pos = 0; cmac_init(&mode->hash1, cipher, 0); cmac_update(&mode->hash1, cipher, iv, iv_len); cmac_final(&mode->hash1, cipher, mode->mask); - memcpy(mode->ctr, mode->mask, cipher->size); + memcpy(ctr->iv, mode->mask, cipher->size); /* Defensive memset. */ - memset(mode->state, 0, cipher->size); + memset(ctr->state, 0, cipher->size); cmac_init(&mode->hash1, cipher, 1); cmac_init(&mode->hash2, cipher, 2); @@ -6999,34 +7114,19 @@ eax_aad(eax_t *mode, const cipher_t *cipher, cmac_update(&mode->hash1, cipher, aad, len); } +static void +eax_stream(ctr_t *ctr, const cipher_t *cipher) { + cipher_encrypt(cipher, ctr->state, ctr->iv); + increment_be(ctr->iv, cipher->size); +} + static void eax_crypt(eax_t *mode, const cipher_t *cipher, unsigned char *dst, const unsigned char *src, size_t len) { - size_t mask = cipher->size - 1; - unsigned int cy; - size_t i; - int j; - - for (i = 0; i < len; i++) { - if ((mode->pos & mask) == 0) { - cipher_encrypt(cipher, mode->state, mode->ctr); - - cy = 1; - - for (j = cipher->size - 1; j >= 0; j--) { - cy += (unsigned int)mode->ctr[j]; - mode->ctr[j] = cy; - cy >>= 8; - } - - mode->pos = 0; - } - - dst[i] = src[i] ^ mode->state[mode->pos++]; - } + stream_update(&mode->ctr, cipher, eax_stream, ctr_xor, dst, src, len); } void @@ -7060,11 +7160,11 @@ eax_digest(eax_t *mode, const cipher_t *cipher, unsigned char *mac) { * Cipher Mode */ -typedef struct __cipher_mode_s cipher_mode_t; +typedef struct cipher_mode_s cipher_mode_t; static int cipher_mode_init(cipher_mode_t *ctx, const cipher_t *cipher, - int type, const unsigned char *iv, size_t iv_len) { + mode_id_t type, const unsigned char *iv, size_t iv_len) { ctx->type = type; switch (ctx->type) { @@ -7081,7 +7181,7 @@ cipher_mode_init(cipher_mode_t *ctx, const cipher_t *cipher, if (iv_len != cipher->size) goto fail; - cbc_init(&ctx->mode.cbc, cipher, iv); + cbc_init(&ctx->mode.block, cipher, iv); return 1; } @@ -7090,7 +7190,7 @@ cipher_mode_init(cipher_mode_t *ctx, const cipher_t *cipher, if (iv_len != cipher->size) goto fail; - xts_init(&ctx->mode.xts, cipher, iv); + xts_init(&ctx->mode.block, cipher, iv); return 1; } @@ -7099,7 +7199,7 @@ cipher_mode_init(cipher_mode_t *ctx, const cipher_t *cipher, if (iv_len != cipher->size) goto fail; - ctr_init(&ctx->mode.ctr, cipher, iv); + ctr_init(&ctx->mode.stream, cipher, iv); return 1; } @@ -7108,7 +7208,7 @@ cipher_mode_init(cipher_mode_t *ctx, const cipher_t *cipher, if (iv_len != cipher->size) goto fail; - cfb_init(&ctx->mode.cfb, cipher, iv); + cfb_init(&ctx->mode.stream, cipher, iv); return 1; } @@ -7117,7 +7217,7 @@ cipher_mode_init(cipher_mode_t *ctx, const cipher_t *cipher, if (iv_len != cipher->size) goto fail; - ofb_init(&ctx->mode.ofb, cipher, iv); + ofb_init(&ctx->mode.stream, cipher, iv); return 1; } @@ -7148,7 +7248,7 @@ cipher_mode_xts_setup(cipher_mode_t *ctx, if (ctx->type != CIPHER_MODE_XTS) return 0; - return xts_setup(&ctx->mode.xts, cipher, key, key_len); + return xts_setup(&ctx->mode.block, cipher, key, key_len); } static int @@ -7194,19 +7294,19 @@ cipher_mode_encrypt(cipher_mode_t *ctx, break; case CIPHER_MODE_CBC: case CIPHER_MODE_CTS: - cbc_encrypt(&ctx->mode.cbc, cipher, dst, src, len); + cbc_encrypt(&ctx->mode.block, cipher, dst, src, len); break; case CIPHER_MODE_XTS: - xts_encrypt(&ctx->mode.xts, cipher, dst, src, len); + xts_encrypt(&ctx->mode.block, cipher, dst, src, len); break; case CIPHER_MODE_CTR: - ctr_crypt(&ctx->mode.ctr, cipher, dst, src, len); + ctr_crypt(&ctx->mode.stream, cipher, dst, src, len); break; case CIPHER_MODE_CFB: - cfb_encrypt(&ctx->mode.cfb, cipher, dst, src, len); + cfb_encrypt(&ctx->mode.stream, cipher, dst, src, len); break; case CIPHER_MODE_OFB: - ofb_crypt(&ctx->mode.ofb, cipher, dst, src, len); + ofb_crypt(&ctx->mode.stream, cipher, dst, src, len); break; case CIPHER_MODE_GCM: gcm_encrypt(&ctx->mode.gcm, cipher, dst, src, len); @@ -7236,19 +7336,19 @@ cipher_mode_decrypt(cipher_mode_t *ctx, break; case CIPHER_MODE_CBC: case CIPHER_MODE_CTS: - cbc_decrypt(&ctx->mode.cbc, cipher, dst, src, len); + cbc_decrypt(&ctx->mode.block, cipher, dst, src, len); break; case CIPHER_MODE_XTS: - xts_decrypt(&ctx->mode.xts, cipher, dst, src, len); + xts_decrypt(&ctx->mode.block, cipher, dst, src, len); break; case CIPHER_MODE_CTR: - ctr_crypt(&ctx->mode.ctr, cipher, dst, src, len); + ctr_crypt(&ctx->mode.stream, cipher, dst, src, len); break; case CIPHER_MODE_CFB: - cfb_decrypt(&ctx->mode.cfb, cipher, dst, src, len); + cfb_decrypt(&ctx->mode.stream, cipher, dst, src, len); break; case CIPHER_MODE_OFB: - ofb_crypt(&ctx->mode.ofb, cipher, dst, src, len); + ofb_crypt(&ctx->mode.stream, cipher, dst, src, len); break; case CIPHER_MODE_GCM: gcm_decrypt(&ctx->mode.gcm, cipher, dst, src, len); @@ -7273,10 +7373,10 @@ cipher_mode_steal(cipher_mode_t *ctx, size_t len) { switch (ctx->type) { case CIPHER_MODE_CTS: - cbc_steal(&ctx->mode.cbc, cipher, last, block, len); + cbc_steal(&ctx->mode.block, cipher, last, block, len); break; case CIPHER_MODE_XTS: - xts_steal(&ctx->mode.xts, cipher, last, block, len); + xts_steal(&ctx->mode.block, cipher, last, block, len); break; default: torsion_abort(); /* LCOV_EXCL_LINE */ @@ -7292,10 +7392,10 @@ cipher_mode_unsteal(cipher_mode_t *ctx, size_t len) { switch (ctx->type) { case CIPHER_MODE_CTS: - cbc_unsteal(&ctx->mode.cbc, cipher, last, block, len); + cbc_unsteal(&ctx->mode.block, cipher, last, block, len); break; case CIPHER_MODE_XTS: - xts_unsteal(&ctx->mode.xts, cipher, last, block, len); + xts_unsteal(&ctx->mode.block, cipher, last, block, len); break; default: torsion_abort(); /* LCOV_EXCL_LINE */ @@ -7347,7 +7447,7 @@ cipher_mode_verify(cipher_mode_t *ctx, int cipher_stream_init(cipher_stream_t *ctx, - int type, int mode, int encrypt, + cipher_id_t type, mode_id_t mode, int encrypt, const unsigned char *key, size_t key_len, const unsigned char *iv, size_t iv_len) { int is_pad = mode == CIPHER_MODE_ECB || mode == CIPHER_MODE_CBC; @@ -7550,7 +7650,7 @@ cipher_stream_update(cipher_stream_t *ctx, } if (input_len >= ctx->block_size) { - size_t aligned = input_len - (input_len & (ctx->block_size - 1)); + size_t aligned = input_len & -ctx->block_size; cipher_stream_encipher(ctx, output, input, aligned); @@ -7598,7 +7698,7 @@ cipher_stream_update_size(const cipher_stream_t *ctx, size_t input_len) { } if (input_len >= ctx->block_size) - output_len += input_len - (input_len & (ctx->block_size - 1)); + output_len += input_len & -ctx->block_size; ASSERT(output_len >= ctx->block_size); @@ -7725,11 +7825,42 @@ cipher_stream_final(cipher_stream_t *ctx, break; } + + default: { + break; + } } return 1; } +size_t +cipher_stream_final_size(const cipher_stream_t *ctx) { + switch (ctx->mode.type) { + case CIPHER_MODE_ECB: + case CIPHER_MODE_CBC: { + if (!ctx->padding) + return 0; + + return ctx->block_size; + } + + case CIPHER_MODE_CTS: + case CIPHER_MODE_XTS: { + if (!ctx->padding) + return 0; + + return ctx->block_size + ctx->block_pos; + } + + default: { + break; + } + } + + return 0; +} + /* * Static Encryption/Decryption */ @@ -7737,8 +7868,8 @@ cipher_stream_final(cipher_stream_t *ctx, static int cipher_static_crypt(unsigned char *output, size_t *output_len, - int type, - int mode, + cipher_id_t type, + mode_id_t mode, int encrypt, const unsigned char *key, size_t key_len, @@ -7766,15 +7897,15 @@ cipher_static_crypt(unsigned char *output, *output_len = len1 + len2; r = 1; fail: - torsion_cleanse(&ctx, sizeof(ctx)); + torsion_memzero(&ctx, sizeof(ctx)); return r; } int cipher_static_encrypt(unsigned char *ct, size_t *ct_len, - int type, - int mode, + cipher_id_t type, + mode_id_t mode, const unsigned char *key, size_t key_len, const unsigned char *iv, @@ -7791,8 +7922,8 @@ cipher_static_encrypt(unsigned char *ct, int cipher_static_decrypt(unsigned char *pt, size_t *pt_len, - int type, - int mode, + cipher_id_t type, + mode_id_t mode, const unsigned char *key, size_t key_len, const unsigned char *iv, diff --git a/node_modules/bcrypto/deps/torsion/src/drbg.c b/node_modules/bcrypto/deps/torsion/src/drbg.c index c916f450f..2d389ccc0 100644 --- a/node_modules/bcrypto/deps/torsion/src/drbg.c +++ b/node_modules/bcrypto/deps/torsion/src/drbg.c @@ -17,15 +17,6 @@ #include "bio.h" #include "internal.h" -/* - * Constants - */ - -static const unsigned char ZERO[1] = {0x00}; -static const unsigned char ONE[1] = {0x01}; -static const unsigned char TWO[1] = {0x02}; -static const unsigned char THREE[1] = {0x03}; - /* * HMAC-DRBG */ @@ -34,9 +25,12 @@ static void hmac_drbg_update(hmac_drbg_t *drbg, const unsigned char *seed, size_t seed_len) { + static const unsigned char zero[1] = {0x00}; + static const unsigned char one[1] = {0x01}; + hmac_init(&drbg->kmac, drbg->type, drbg->K, drbg->size); hmac_update(&drbg->kmac, drbg->V, drbg->size); - hmac_update(&drbg->kmac, ZERO, 1); + hmac_update(&drbg->kmac, zero, 1); hmac_update(&drbg->kmac, seed, seed_len); hmac_final(&drbg->kmac, drbg->K); @@ -47,7 +41,7 @@ hmac_drbg_update(hmac_drbg_t *drbg, if (seed_len > 0) { hmac_init(&drbg->kmac, drbg->type, drbg->K, drbg->size); hmac_update(&drbg->kmac, drbg->V, drbg->size); - hmac_update(&drbg->kmac, ONE, 1); + hmac_update(&drbg->kmac, one, 1); hmac_update(&drbg->kmac, seed, seed_len); hmac_final(&drbg->kmac, drbg->K); @@ -61,7 +55,7 @@ hmac_drbg_update(hmac_drbg_t *drbg, void hmac_drbg_init(hmac_drbg_t *drbg, - int type, + hash_id_t type, const unsigned char *seed, size_t seed_len) { size_t size = hash_output_size(type); @@ -125,7 +119,7 @@ hmac_drbg_rng(void *out, size_t size, void *arg) { void hash_drbg_init(hash_drbg_t *drbg, - int type, + hash_id_t type, const unsigned char *seed, size_t seed_len) { size_t size = hash_output_size(type); @@ -232,30 +226,31 @@ hash_drbg_reseed(hash_drbg_t *drbg, static void accumulate(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) { - unsigned int cy = 0; + unsigned int c = 0; ASSERT(dlen >= slen); while (slen > 0) { - cy += (unsigned int)src[--slen] + dst[--dlen]; - dst[dlen] = cy & 0xff; - cy >>= 8; + c += (unsigned int)src[--slen] + dst[--dlen]; + dst[dlen] = c & 0xff; + c >>= 8; } - while (cy > 0 && dlen > 0) { - cy += (unsigned int)dst[--dlen]; - dst[dlen] = cy & 0xff; - cy >>= 8; + while (dlen > 0) { + c += (unsigned int)dst[--dlen]; + dst[dlen] = c & 0xff; + c >>= 8; } } static void hash_drbg_update(hash_drbg_t *drbg) { + static const unsigned char three[1] = {0x03}; unsigned char H[HASH_MAX_OUTPUT_SIZE]; unsigned char L[8]; hash_init(&drbg->hash, drbg->type); - hash_update(&drbg->hash, THREE, 1); + hash_update(&drbg->hash, three, 1); hash_update(&drbg->hash, drbg->V, drbg->length); hash_final(&drbg->hash, H, drbg->size); @@ -273,13 +268,15 @@ hash_drbg_generate(hash_drbg_t *drbg, size_t len, const unsigned char *add, size_t add_len) { + static const unsigned char one[1] = {0x01}; + static const unsigned char two[1] = {0x02}; unsigned char *raw = (unsigned char *)out; unsigned char H[HASH_MAX_OUTPUT_SIZE]; unsigned char V[111]; if (add_len > 0) { hash_init(&drbg->hash, drbg->type); - hash_update(&drbg->hash, TWO, 1); + hash_update(&drbg->hash, two, 1); hash_update(&drbg->hash, drbg->V, drbg->length); hash_update(&drbg->hash, add, add_len); hash_final(&drbg->hash, H, drbg->size); @@ -303,7 +300,7 @@ hash_drbg_generate(hash_drbg_t *drbg, hash_final(&drbg->hash, raw, drbg->size); - accumulate(V, drbg->length, ONE, 1); + accumulate(V, drbg->length, one, 1); raw += drbg->size; len -= drbg->size; @@ -340,13 +337,7 @@ ctr_drbg_rekey(ctr_drbg_t *drbg, static void ctr_drbg_encrypt(ctr_drbg_t *drbg, unsigned char *out) { - size_t i = drbg->blk_size; - - while (i--) { - if (++drbg->state[i] != 0x00) - break; - } - + increment_be(drbg->state, drbg->blk_size); aes_encrypt(&drbg->aes, out, drbg->state); } diff --git a/node_modules/bcrypto/deps/torsion/src/dsa.c b/node_modules/bcrypto/deps/torsion/src/dsa.c index 7472db695..843ee78e0 100644 --- a/node_modules/bcrypto/deps/torsion/src/dsa.c +++ b/node_modules/bcrypto/deps/torsion/src/dsa.c @@ -165,16 +165,17 @@ dsa_group_export_dumb(unsigned char *out, } static int -dsa_group_generate(dsa_group_t *group, int bits, const unsigned char *entropy) { +dsa_group_generate(dsa_group_t *group, mp_bits_t bits, + const unsigned char *entropy) { /* [FIPS186] Page 31, Appendix A.1. * Page 41, Appendix A.2. * [DSA] "Parameter generation". */ - int L = bits; - int N = bits < 2048 ? 160 : 256; + mp_bits_t L = bits; + mp_bits_t N = bits < 2048 ? 160 : 256; mpz_t q, p, t, h, pm1, e, g; + mp_bits_t i, b; drbg_t rng; - int i, b; if (!(L == 1024 && N == 160) && !(L == 2048 && N == 224) @@ -252,17 +253,17 @@ dsa_group_generate(dsa_group_t *group, int bits, const unsigned char *entropy) { mpz_cleanse(e); mpz_cleanse(g); - torsion_cleanse(&rng, sizeof(rng)); + torsion_memzero(&rng, sizeof(rng)); return 1; } static int dsa_group_is_sane(const dsa_group_t *group) { - int pbits = mpz_bitlen(group->p); - int qbits = mpz_bitlen(group->q); - mpz_t pm1; + mp_bits_t pbits = mpz_bitlen(group->p); + mp_bits_t qbits = mpz_bitlen(group->q); int ret = 0; + mpz_t pm1; mpz_init(pm1); @@ -412,8 +413,8 @@ dsa_pub_export_dumb(unsigned char *out, size_t *out_len, const dsa_pub_t *k) { static int dsa_pub_is_sane(const dsa_pub_t *k) { dsa_group_t group; - mpz_t pm1; int ret = 0; + mpz_t pm1; dsa_group_roset_pub(&group, k); @@ -620,16 +621,16 @@ dsa_priv_create(dsa_priv_t *k, mpz_powm_sec(k->y, k->g, k->x, k->p); - torsion_cleanse(&rng, sizeof(rng)); + torsion_memzero(&rng, sizeof(rng)); } static int -dsa_priv_generate(dsa_priv_t *k, int bits, const unsigned char *entropy) { +dsa_priv_generate(dsa_priv_t *k, mp_bits_t bits, const unsigned char *entropy) { unsigned char entropy1[ENTROPY_SIZE]; unsigned char entropy2[ENTROPY_SIZE]; dsa_group_t group; - drbg_t rng; int ret = 0; + drbg_t rng; dsa_group_init(&group); @@ -644,9 +645,9 @@ dsa_priv_generate(dsa_priv_t *k, int bits, const unsigned char *entropy) { ret = 1; fail: dsa_group_clear(&group); - torsion_cleanse(&rng, sizeof(rng)); - torsion_cleanse(entropy1, sizeof(entropy1)); - torsion_cleanse(entropy2, sizeof(entropy2)); + torsion_memzero(&rng, sizeof(rng)); + torsion_memzero(entropy1, sizeof(entropy1)); + torsion_memzero(entropy2, sizeof(entropy2)); return ret; } @@ -764,9 +765,9 @@ dsa_sig_export_rs(unsigned char *out, size_t *out_len, int dsa_params_create(unsigned char *out, size_t *out_len, const unsigned char *key, size_t key_len) { + dsa_group_t group; dsa_priv_t priv; dsa_pub_t pub; - dsa_group_t group; int ret = 0; dsa_priv_init(&priv); @@ -815,7 +816,7 @@ dsa_params_generate(unsigned char *out, unsigned int dsa_params_bits(const unsigned char *params, size_t params_len) { - unsigned int bits = 0; + mp_bits_t bits = 0; dsa_group_t group; dsa_group_init(&group); @@ -834,7 +835,7 @@ dsa_params_bits(const unsigned char *params, size_t params_len) { unsigned int dsa_params_qbits(const unsigned char *params, size_t params_len) { - unsigned int bits = 0; + mp_bits_t bits = 0; dsa_group_t group; dsa_group_init(&group); @@ -963,7 +964,7 @@ dsa_privkey_generate(unsigned char *out, unsigned int dsa_privkey_bits(const unsigned char *key, size_t key_len) { - unsigned int bits = 0; + mp_bits_t bits = 0; dsa_priv_t k; dsa_priv_init(&k); @@ -982,7 +983,7 @@ dsa_privkey_bits(const unsigned char *key, size_t key_len) { unsigned int dsa_privkey_qbits(const unsigned char *key, size_t key_len) { - unsigned int bits = 0; + mp_bits_t bits = 0; dsa_priv_t k; dsa_priv_init(&k); @@ -1026,8 +1027,13 @@ dsa_privkey_import(unsigned char *out, size_t *out_len, if (!dsa_priv_import_dumb(&k, key, key_len)) goto fail; - if (!dsa_priv_recover(&k)) - goto fail; + if (mpz_sgn(k.y) == 0) { + if (!dsa_priv_recover(&k)) + goto fail; + } else { + if (!dsa_priv_is_sane(&k)) + goto fail; + } dsa_priv_export(out, out_len, &k); ret = 1; @@ -1082,7 +1088,7 @@ dsa_pubkey_create(unsigned char *out, size_t *out_len, unsigned int dsa_pubkey_bits(const unsigned char *key, size_t key_len) { - unsigned int bits = 0; + mp_bits_t bits = 0; dsa_pub_t k; dsa_pub_init(&k); @@ -1101,7 +1107,7 @@ dsa_pubkey_bits(const unsigned char *key, size_t key_len) { unsigned int dsa_pubkey_qbits(const unsigned char *key, size_t key_len) { - unsigned int bits = 0; + mp_bits_t bits = 0; dsa_pub_t k; dsa_pub_init(&k); @@ -1325,8 +1331,8 @@ dsa_sign(unsigned char *out, size_t *out_len, mpz_t m, b, bx, bm, k, r, s; drbg_t drbg, rng; dsa_priv_t priv; - dsa_sig_t S; size_t qsize; + dsa_sig_t S; int ret = 0; mpz_init(m); @@ -1414,9 +1420,9 @@ dsa_sign(unsigned char *out, size_t *out_len, mpz_cleanse(r); mpz_cleanse(s); dsa_priv_clear(&priv); - torsion_cleanse(&drbg, sizeof(drbg)); - torsion_cleanse(&rng, sizeof(rng)); - torsion_cleanse(bytes, sizeof(bytes)); + torsion_memzero(&drbg, sizeof(drbg)); + torsion_memzero(&rng, sizeof(rng)); + torsion_memzero(bytes, sizeof(bytes)); return ret; } @@ -1445,9 +1451,9 @@ dsa_verify(const unsigned char *msg, size_t msg_len, * r == r' mod q */ mpz_t r, s, m, si, u1, u2, e1, e2, re; + size_t qsize; dsa_pub_t k; dsa_sig_t S; - size_t qsize; int ret = 0; mpz_init(m); @@ -1519,8 +1525,8 @@ dsa_derive(unsigned char *out, size_t *out_len, const unsigned char *priv, size_t priv_len) { dsa_pub_t k1; dsa_priv_t k2; - mpz_t e; int ret = 0; + mpz_t e; dsa_pub_init(&k1); dsa_priv_init(&k2); diff --git a/node_modules/bcrypto/deps/torsion/src/ecc.c b/node_modules/bcrypto/deps/torsion/src/ecc.c index a545156a1..a542343a1 100644 --- a/node_modules/bcrypto/deps/torsion/src/ecc.c +++ b/node_modules/bcrypto/deps/torsion/src/ecc.c @@ -172,6 +172,8 @@ typedef uint32_t fe_word_t; # define MAX_FIELD_WORDS 19 #endif +typedef int fe_size_t; + TORSION_BARRIER(int, int) TORSION_BARRIER(fe_word_t, fe_word) @@ -210,7 +212,7 @@ TORSION_BARRIER(fe_word_t, fe_word) #define ECC_MIN(x, y) ((x) < (y) ? (x) : (y)) #define ECC_MAX(x, y) ((x) > (y) ? (x) : (y)) -#define cleanse torsion_cleanse +#define cleanse torsion_memzero /* * Scalar Field @@ -224,10 +226,10 @@ typedef void sc_invert_f(const struct scalar_field_s *, sc_t, const sc_t); typedef struct scalar_field_s { int endian; - int bits; - int endo_bits; - int limbs; - int shift; + mp_bits_t bits; + mp_bits_t endo_bits; + mp_size_t limbs; + mp_size_t shift; size_t size; unsigned int mask; mp_limb_t n[MAX_SCALAR_LIMBS]; @@ -239,7 +241,7 @@ typedef struct scalar_field_s { } scalar_field_t; typedef struct scalar_def_s { - int bits; + mp_bits_t bits; const unsigned char n[MAX_FIELD_SIZE]; sc_invert_f *invert; } scalar_def_t; @@ -273,9 +275,9 @@ typedef void fe_legendre_f(fe_word_t *, const fe_word_t *); typedef struct prime_field_s { int endian; - int bits; - int words; - int limbs; + mp_bits_t bits; + fe_size_t words; + mp_size_t limbs; size_t size; size_t adj_size; unsigned int mask; @@ -311,8 +313,8 @@ typedef struct prime_field_s { } prime_field_t; typedef struct prime_def_s { - int bits; - int words; + mp_bits_t bits; + fe_size_t words; const unsigned char p[MAX_FIELD_SIZE]; fe_add_f *add; fe_sub_f *sub; @@ -348,7 +350,7 @@ typedef struct endo_def_s { const unsigned char b2[MAX_SCALAR_SIZE]; const unsigned char g1[MAX_SCALAR_SIZE]; const unsigned char g2[MAX_SCALAR_SIZE]; - int prec; + mp_bits_t prec; } endo_def_t; /* @@ -384,8 +386,8 @@ typedef struct jge_s { } jge_t; typedef struct wei_s { - int hash; - int xof; + hash_id_t hash; + hash_id_t xof; prime_field_t fe; scalar_field_t sc; unsigned int h; @@ -417,12 +419,12 @@ typedef struct wei_s { sc_t g1; sc_t g2; wge_t wnd_endo[NAF_SIZE_PRE]; /* 19kb */ - int prec; + mp_bits_t prec; } wei_t; typedef struct wei_def_s { - int hash; - int xof; + hash_id_t hash; + hash_id_t xof; const prime_def_t *fe; const scalar_def_t *sc; unsigned int h; @@ -543,7 +545,7 @@ typedef struct xge_s { } xge_t; typedef struct edwards_s { - int hash; + hash_id_t hash; int context; const char *prefix; prime_field_t fe; @@ -572,7 +574,7 @@ typedef struct edwards_s { } edwards_t; typedef struct edwards_def_s { - int hash; + hash_id_t hash; int context; const char *prefix; const prime_def_t *fe; @@ -744,12 +746,14 @@ sc_set_word(const scalar_field_t *sc, sc_t z, mp_limb_t x) { static void sc_select(const scalar_field_t *sc, sc_t z, const sc_t x, const sc_t y, int flag) { - mpn_select(z, x, y, sc->limbs, flag); + mpn_cnd_select(z, x, y, sc->limbs, flag); } static void sc_select_zero(const scalar_field_t *sc, sc_t z, const sc_t x, int flag) { - mpn_select_zero(z, x, sc->limbs, flag); + static const sc_t y = {0}; + + sc_select(sc, z, x, y, flag); } static int @@ -782,18 +786,19 @@ sc_is_high_var(const scalar_field_t *sc, const sc_t x) { return mpn_cmp(x, sc->nh, sc->limbs) > 0; } -static int +static mp_bits_t sc_bitlen_var(const scalar_field_t *sc, const sc_t x) { return mpn_bitlen(x, sc->limbs); } -static int -sc_get_bit(const scalar_field_t *sc, const sc_t x, int pos) { +static mp_limb_t +sc_get_bit(const scalar_field_t *sc, const sc_t x, mp_bits_t pos) { return mpn_getbit(x, sc->limbs, pos); } -static int -sc_get_bits(const scalar_field_t *sc, const sc_t x, int pos, int width) { +static mp_limb_t +sc_get_bits(const scalar_field_t *sc, const sc_t x, + mp_bits_t pos, mp_bits_t width) { return mpn_getbits(x, sc->limbs, pos, width); } @@ -845,10 +850,10 @@ sc_reduce(const scalar_field_t *sc, sc_t z, const mp_limb_t *xp) { } static void -sc_mod(const scalar_field_t *sc, sc_t z, const mp_limb_t *xp, int xn) { +sc_mod(const scalar_field_t *sc, sc_t z, const mp_limb_t *xp, mp_size_t xn) { /* Called on initialization only. */ mp_limb_t zp[MAX_REDUCE_LIMBS]; /* 160 bytes */ - int zn = sc->shift; + mp_size_t zn = sc->shift; ASSERT(xn <= zn); @@ -861,7 +866,7 @@ sc_mod(const scalar_field_t *sc, sc_t z, const mp_limb_t *xp, int xn) { static void sc_mul(const scalar_field_t *sc, sc_t z, const sc_t x, const sc_t y) { mp_limb_t zp[MAX_REDUCE_LIMBS]; /* 160 bytes */ - int zn = sc->limbs * 2; + mp_size_t zn = sc->limbs * 2; mpn_mul_n(zp, x, y, sc->limbs); @@ -874,7 +879,7 @@ TORSION_UNUSED static void sc_sqr(const scalar_field_t *sc, sc_t z, const sc_t x) { mp_limb_t scratch[MPN_SQR_ITCH(MAX_SCALAR_LIMBS)]; /* 144 bytes */ mp_limb_t zp[MAX_REDUCE_LIMBS]; /* 160 bytes */ - int zn = sc->limbs * 2; + mp_size_t zn = sc->limbs * 2; mpn_sqr(zp, x, sc->limbs, scratch); @@ -886,7 +891,7 @@ sc_sqr(const scalar_field_t *sc, sc_t z, const sc_t x) { static void sc_mul_word(const scalar_field_t *sc, sc_t z, const sc_t x, mp_limb_t y) { mp_limb_t zp[MAX_REDUCE_LIMBS]; /* 160 bytes */ - int zn = sc->limbs + 1; + mp_size_t zn = sc->limbs + 1; zp[sc->limbs] = mpn_mul_1(zp, x, sc->limbs, y); @@ -897,7 +902,7 @@ sc_mul_word(const scalar_field_t *sc, sc_t z, const sc_t x, mp_limb_t y) { static void sc_mulshift(const scalar_field_t *sc, sc_t z, - const sc_t x, const sc_t y, int shift) { + const sc_t x, const sc_t y, mp_bits_t shift) { mp_limb_t scratch[MPN_MULSHIFT_ITCH(MAX_SCALAR_LIMBS)]; /* 144 bytes */ ASSERT(mpn_mulshift(z, x, y, sc->limbs, shift, scratch) == 0); @@ -907,7 +912,7 @@ static void sc_montmul(const scalar_field_t *sc, sc_t z, const sc_t x, const sc_t y) { mp_limb_t scratch[MPN_MONTMUL_ITCH(MAX_SCALAR_LIMBS)]; /* 144 bytes */ - mpn_montmul(z, x, y, sc->n, sc->limbs, sc->k, scratch); + mpn_sec_montmul(z, x, y, sc->n, sc->limbs, sc->k, scratch); } static void @@ -1061,9 +1066,10 @@ static void sc_pow(const scalar_field_t *sc, sc_t z, const sc_t x, const mp_limb_t *ep) { /* Used for inversion if not available otherwise. */ /* Note that our exponent is not secret. */ - int steps = WND_STEPS(sc->bits); + mp_bits_t steps = WND_STEPS(sc->bits); sc_t wnd[WND_SIZE]; /* 1152 bytes */ - int i, b; + mp_bits_t i; + mp_limb_t b; sc_mont(sc, wnd[0], sc_one); sc_mont(sc, wnd[1], x); @@ -1136,10 +1142,13 @@ sc_minimize_var(const scalar_field_t *sc, sc_t z, const sc_t x) { return high; } -static int +static mp_bits_t sc_naf_var0(const scalar_field_t *sc, - int *naf, const sc_t k, - int sign, int width, int max) { + int *naf, + const sc_t k, + int sign, + mp_bits_t width, + mp_bits_t max) { /* Computing the width-w NAF of a positive integer. * * [GECC] Algorithm 3.35, Page 100, Section 3.3. @@ -1148,10 +1157,10 @@ sc_naf_var0(const scalar_field_t *sc, * method of recoding. The more optimal method * below was ported from libsecp256k1. */ - int bits = sc_bitlen_var(sc, k) + 1; + mp_bits_t bits = sc_bitlen_var(sc, k) + 1; + mp_bits_t len = 0; + mp_bits_t i = 0; int carry = 0; - int len = 0; - int i = 0; int word; ASSERT(bits <= max); @@ -1160,7 +1169,7 @@ sc_naf_var0(const scalar_field_t *sc, naf[max] = 0; while (i < bits) { - if (sc_get_bit(sc, k, i) == carry) { + if (sc_get_bit(sc, k, i) == (mp_limb_t)carry) { i += 1; continue; } @@ -1181,20 +1190,21 @@ sc_naf_var0(const scalar_field_t *sc, return len; } -static int -sc_naf_var(const scalar_field_t *sc, int *naf, const sc_t k, int width) { +static mp_bits_t +sc_naf_var(const scalar_field_t *sc, int *naf, const sc_t k, mp_bits_t width) { return sc_naf_var0(sc, naf, k, 1, width, sc->bits + 1); } -static int +static mp_bits_t sc_naf_endo_var(const scalar_field_t *sc, int *naf1, int *naf2, const sc_t k1, const sc_t k2, - int width) { - int s1, s2, len1, len2; + mp_bits_t width) { + mp_bits_t len1, len2; sc_t c1, c2; + int s1, s2; /* Minimize scalars. */ s1 = sc_minimize_var(sc, c1, k1) ? -1 : 1; @@ -1207,24 +1217,24 @@ sc_naf_endo_var(const scalar_field_t *sc, return ECC_MAX(len1, len2); } -static int +static mp_bits_t sc_jsf_var0(const scalar_field_t *sc, int *naf, const sc_t k1, int s1, const sc_t k2, int s2, - int max) { + mp_bits_t max) { /* Joint sparse form. * * [GECC] Algorithm 3.50, Page 111, Section 3.3. */ - int bits1 = sc_bitlen_var(sc, k1) + 1; - int bits2 = sc_bitlen_var(sc, k2) + 1; - int bits = ECC_MAX(bits1, bits2); + mp_bits_t bits1 = sc_bitlen_var(sc, k1) + 1; + mp_bits_t bits2 = sc_bitlen_var(sc, k2) + 1; + mp_bits_t bits = ECC_MAX(bits1, bits2); + mp_bits_t i; int d1 = 0; int d2 = 0; - int i; /* JSF->NAF conversion table. */ static const int table[9] = { @@ -1295,12 +1305,12 @@ sc_jsf_var0(const scalar_field_t *sc, return i; } -static int +static mp_bits_t sc_jsf_var(const scalar_field_t *sc, int *naf, const sc_t k1, const sc_t k2) { return sc_jsf_var0(sc, naf, k1, 1, k2, 1, sc->bits + 1); } -static int +static mp_bits_t sc_jsf_endo_var(const scalar_field_t *sc, int *naf, const sc_t k1, @@ -1341,7 +1351,7 @@ sc_random(const scalar_field_t *sc, sc_t z, drbg_t *rng) { static void fe_zero(const prime_field_t *fe, fe_t z) { - int i; + fe_size_t i; for (i = 0; i < fe->words; i++) z[i] = 0; @@ -1421,16 +1431,15 @@ fe_export(const prime_field_t *fe, unsigned char *raw, const fe_t x) { static void fe_swap(const prime_field_t *fe, fe_t x, fe_t y, int flag) { - fe_word_t cond = (flag != 0); - fe_word_t mask = fe_word_barrier(-cond); - fe_word_t word; - int i; + fe_word_t m = -fe_word_barrier(flag != 0); + fe_word_t w; + fe_size_t i; for (i = 0; i < fe->words; i++) { - word = (x[i] ^ y[i]) & mask; + w = (x[i] ^ y[i]) & m; - x[i] ^= word; - y[i] ^= word; + x[i] ^= w; + y[i] ^= w; } } @@ -1445,7 +1454,7 @@ fe_select(const prime_field_t *fe, static void fe_set(const prime_field_t *fe, fe_t z, const fe_t x) { - int i; + fe_size_t i; for (i = 0; i < fe->words; i++) z[i] = x[i]; @@ -1470,10 +1479,10 @@ fe_get_limbs(const prime_field_t *fe, mp_limb_t *zp, const fe_t x) { } static void -fe_mod(const prime_field_t *fe, fe_t z, const mp_limb_t *xp, int xn) { +fe_mod(const prime_field_t *fe, fe_t z, const mp_limb_t *xp, mp_size_t xn) { /* Called on initialization only. */ mp_limb_t zp[MAX_FIELD_LIMBS]; - int zn = fe->limbs; + mp_size_t zn = fe->limbs; if (xn >= fe->limbs) { mpn_mod(zp, xp, xn, fe->p, fe->limbs); @@ -1506,7 +1515,7 @@ fe_set_sc(const prime_field_t *fe, static void fe_set_word(const prime_field_t *fe, fe_t z, fe_word_t x) { - int i; + fe_size_t i; z[0] = x; @@ -1558,7 +1567,7 @@ fe_equal(const prime_field_t *fe, const fe_t x, const fe_t y) { fe_word_t z = 0; if (fe->from_montgomery != NULL) { - int i; + fe_size_t i; for (i = 0; i < fe->words; i++) z |= x[i] ^ y[i]; @@ -1687,9 +1696,10 @@ fe_mul8(const prime_field_t *fe, fe_t z, const fe_t x) { static void fe_pow(const prime_field_t *fe, fe_t z, const fe_t x, const mp_limb_t *ep) { /* Used for inversion and square roots if not available otherwise. */ - int steps = WND_STEPS(fe->bits); + mp_bits_t steps = WND_STEPS(fe->bits); fe_t wnd[WND_SIZE]; /* 1152 bytes */ - int i, j, b; + mp_bits_t i, j; + mp_limb_t b; fe_set(fe, wnd[0], fe->one); fe_set(fe, wnd[1], x); @@ -2744,10 +2754,10 @@ static void wge_fixed_points_var(const wei_t *ec, wge_t *out, const wge_t *p) { /* NOTE: Only called on initialization. */ const scalar_field_t *sc = &ec->sc; - int steps = FIXED_STEPS(sc->bits); - int size = steps * FIXED_SIZE; - jge_t *wnds = checked_malloc(size * sizeof(jge_t)); /* 442.2kb */ - int i, j; + mp_bits_t steps = FIXED_STEPS(sc->bits); + mp_bits_t size = steps * FIXED_SIZE; + jge_t *wnds = (jge_t *)checked_malloc(size * sizeof(jge_t)); /* 442.2kb */ + mp_bits_t i, j; jge_t g; jge_set_wge(ec, &g, p); @@ -2773,7 +2783,7 @@ static void wge_naf_points_var(const wei_t *ec, wge_t *out, const wge_t *p, int width) { /* NOTE: Only called on initialization. */ int size = 1 << (width - 2); - jge_t *wnd = checked_malloc(size * sizeof(jge_t)); /* 216kb */ + jge_t *wnd = (jge_t *)checked_malloc(size * sizeof(jge_t)); /* 216kb */ jge_t j, dbl; int i; @@ -4224,8 +4234,8 @@ wei_jmul_g(const wei_t *ec, jge_t *r, const sc_t k) { */ const scalar_field_t *sc = &ec->sc; const wge_t *wnds = ec->wnd_fixed; - int steps = FIXED_STEPS(sc->bits); - int i, j, b; + mp_bits_t steps = FIXED_STEPS(sc->bits); + mp_bits_t i, j, b; sc_t k0; wge_t t; @@ -4268,9 +4278,9 @@ wei_jmul_normal(const wei_t *ec, jge_t *r, const wge_t *p, const sc_t k) { * [GECC] Page 95, Section 3.3. */ const scalar_field_t *sc = &ec->sc; - int steps = WND_STEPS(sc->bits); + mp_bits_t steps = WND_STEPS(sc->bits); jge_t wnd[WND_SIZE]; /* 3456 bytes */ - int i, j, b; + mp_bits_t i, j, b; jge_t t; /* Create window. */ @@ -4314,12 +4324,13 @@ wei_jmul_endo(const wei_t *ec, jge_t *r, const wge_t *p, const sc_t k) { * [GECC] Page 95, Section 3.3. */ const scalar_field_t *sc = &ec->sc; - int steps = WND_STEPS(sc->endo_bits); + mp_bits_t steps = WND_STEPS(sc->endo_bits); jge_t wnd1[WND_SIZE]; /* 3456 bytes */ jge_t wnd2[WND_SIZE]; /* 3456 bytes */ - int i, j, s1, s2, b1, b2; + mp_bits_t i, j, b1, b2; jge_t t1, t2; sc_t k1, k2; + int s1, s2; ASSERT(ec->endo == 1); @@ -4424,7 +4435,7 @@ wei_jmul_double_normal_var(const wei_t *ec, int naf1[MAX_SCALAR_BITS + 1]; /* 2088 bytes */ int naf2[MAX_SCALAR_BITS + 1]; /* 2088 bytes */ jge_t wnd2[NAF_SIZE]; /* 1728 bytes */ - int i, max, max1, max2; + mp_bits_t i, max, max1, max2; /* Compute NAFs. */ max1 = sc_naf_var(sc, naf1, k1, NAF_WIDTH_PRE); @@ -4475,7 +4486,7 @@ wei_jmul_double_endo_var(const wei_t *ec, int naf3[MAX_ENDO_BITS + 1]; /* 1048 bytes */ jge_t wnd3[JSF_SIZE]; /* 608 bytes */ sc_t c1, c2, c3, c4; /* 288 bytes */ - int i, max, max1, max2; + mp_bits_t i, max, max1, max2; ASSERT(ec->endo == 1); @@ -4565,7 +4576,7 @@ wei_jmul_multi_normal_var(const wei_t *ec, int naf1[MAX_SCALAR_BITS + 1]; /* 2088 bytes */ jge_t **wnds = scratch->wnds; int **nafs = scratch->nafs; - int i, max, size; + mp_bits_t i, max, size; size_t j; ASSERT(len <= scratch->size); @@ -4652,7 +4663,7 @@ wei_jmul_multi_endo_var(const wei_t *ec, int naf1[MAX_ENDO_BITS + 1]; /* 1048 bytes */ jge_t **wnds = scratch->wnds; int **nafs = scratch->nafs; - int i, max, size; + mp_bits_t i, max, size; sc_t k1, k2; size_t j; @@ -5966,7 +5977,7 @@ mont_clamp(const mont_t *ec, unsigned char *out, const unsigned char *scalar) { /* [RFC7748] Page 8, Section 5. */ const prime_field_t *fe = &ec->fe; const scalar_field_t *sc = &ec->sc; - int top = fe->bits & 7; + mp_bits_t top = fe->bits & 7; size_t i; ASSERT(sc->size <= fe->size); @@ -6075,10 +6086,10 @@ mont_mul(const mont_t *ec, pge_t *r, const pge_t *p, const sc_t k, int affine) { */ const prime_field_t *fe = &ec->fe; const scalar_field_t *sc = &ec->sc; - int swap = 0; - int bit = 0; + mp_limb_t swap = 0; + mp_limb_t bit = 0; + mp_bits_t i; pge_t a, b; - int i; pge_zero(ec, &a); pge_set(ec, &b, p); @@ -7044,7 +7055,7 @@ xge_normalize_all_var(const edwards_t *ec, xge_t *out, const xge_t *in, size_t len) { /* Montgomery's trick. */ const prime_field_t *fe = &ec->fe; - fe_t *invs = checked_malloc(len * sizeof(fe_t)); + fe_t *invs = (fe_t *)checked_malloc(len * sizeof(fe_t)); fe_t acc; size_t i; @@ -7075,9 +7086,9 @@ xge_normalize_all_var(const edwards_t *ec, xge_t *out, static void xge_fixed_points(const edwards_t *ec, xge_t *out, const xge_t *p) { const scalar_field_t *sc = &ec->sc; - int steps = FIXED_STEPS(sc->bits); - int size = steps * FIXED_SIZE; - int i, j; + mp_bits_t steps = FIXED_STEPS(sc->bits); + mp_bits_t size = steps * FIXED_SIZE; + mp_bits_t i, j; xge_t g; xge_set(ec, &g, p); @@ -7257,7 +7268,7 @@ edwards_clamp(const edwards_t *ec, /* [RFC8032] Section 5.1.5 & 5.2.5. */ const prime_field_t *fe = &ec->fe; const scalar_field_t *sc = &ec->sc; - int top = fe->bits & 7; + mp_bits_t top = fe->bits & 7; size_t i; ASSERT(sc->size <= fe->size); @@ -7339,8 +7350,8 @@ edwards_mul_g(const edwards_t *ec, xge_t *r, const sc_t k) { */ const scalar_field_t *sc = &ec->sc; const xge_t *wnds = ec->wnd_fixed; - int steps = FIXED_STEPS(sc->bits); - int i, j, b; + mp_bits_t steps = FIXED_STEPS(sc->bits); + mp_bits_t i, j, b; sc_t k0; xge_t t; @@ -7375,9 +7386,9 @@ edwards_mul(const edwards_t *ec, xge_t *r, const xge_t *p, const sc_t k) { */ const prime_field_t *fe = &ec->fe; const scalar_field_t *sc = &ec->sc; - int steps = WND_STEPS(fe->bits); + mp_bits_t steps = WND_STEPS(fe->bits); xge_t wnd[WND_SIZE]; /* 4608 bytes */ - int i, j, b; + mp_bits_t i, j, b; xge_t t; /* Create window. */ @@ -7429,7 +7440,7 @@ edwards_mul_double_var(const edwards_t *ec, int naf1[MAX_SCALAR_BITS + 1]; /* 2088 bytes */ int naf2[MAX_SCALAR_BITS + 1]; /* 2088 bytes */ xge_t wnd2[NAF_SIZE]; /* 2304 bytes */ - int i, max, max1, max2; + mp_bits_t i, max, max1, max2; /* Compute NAFs. */ max1 = sc_naf_var(sc, naf1, k1, NAF_WIDTH_PRE); @@ -7482,7 +7493,7 @@ edwards_mul_multi_var(const edwards_t *ec, int naf1[MAX_SCALAR_BITS + 1]; /* 2088 bytes */ xge_t **wnds = scratch->wnds; int **nafs = scratch->nafs; - int i, max, size; + mp_bits_t i, max, size; size_t j; ASSERT(len <= scratch->size); @@ -10256,13 +10267,13 @@ static const edwards_def_t *edwards_curves[3] = { */ wei_t * -wei_curve_create(int type) { +wei_curve_create(wei_curve_id_t type) { wei_t *ec = NULL; - if (type < 0 || (size_t)type > ARRAY_SIZE(wei_curves)) + if (type < 0 || (size_t)type >= ARRAY_SIZE(wei_curves)) return NULL; - ec = checked_malloc(sizeof(wei_t)); + ec = (wei_t *)checked_malloc(sizeof(wei_t)); wei_init(ec, wei_curves[type]); @@ -10305,24 +10316,25 @@ wei_curve_field_bits(const wei_t *ec) { wei__scratch_t * wei_scratch_create(const wei_t *ec, size_t size) { - wei__scratch_t *scratch = checked_malloc(sizeof(wei__scratch_t)); + wei__scratch_t *scratch = + (wei__scratch_t *)checked_malloc(sizeof(wei__scratch_t)); size_t length = ec->endo ? size : size / 2; size_t bits = ec->endo ? ec->sc.endo_bits : ec->sc.bits; size_t i; scratch->size = size; - scratch->wnd = checked_malloc(length * JSF_SIZE * sizeof(jge_t)); - scratch->wnds = checked_malloc(length * sizeof(jge_t *)); - scratch->naf = checked_malloc(length * (bits + 1) * sizeof(int)); - scratch->nafs = checked_malloc(length * sizeof(int *)); + scratch->wnd = (jge_t *)checked_malloc(length * JSF_SIZE * sizeof(jge_t)); + scratch->wnds = (jge_t **)checked_malloc(length * sizeof(jge_t *)); + scratch->naf = (int *)checked_malloc(length * (bits + 1) * sizeof(int)); + scratch->nafs = (int **)checked_malloc(length * sizeof(int *)); for (i = 0; i < length; i++) { scratch->wnds[i] = &scratch->wnd[i * JSF_SIZE]; scratch->nafs[i] = &scratch->naf[i * (bits + 1)]; } - scratch->points = checked_malloc(size * sizeof(wge_t)); - scratch->coeffs = checked_malloc(size * sizeof(sc_t)); + scratch->points = (wge_t *)checked_malloc(size * sizeof(wge_t)); + scratch->coeffs = (sc_t *)checked_malloc(size * sizeof(sc_t)); return scratch; } @@ -10347,13 +10359,13 @@ wei_scratch_destroy(const wei_t *ec, wei__scratch_t *scratch) { */ mont_t * -mont_curve_create(int type) { +mont_curve_create(mont_curve_id_t type) { mont_t *ec = NULL; - if (type < 0 || (size_t)type > ARRAY_SIZE(mont_curves)) + if (type < 0 || (size_t)type >= ARRAY_SIZE(mont_curves)) return NULL; - ec = checked_malloc(sizeof(mont_t)); + ec = (mont_t *)checked_malloc(sizeof(mont_t)); mont_init(ec, mont_curves[type]); @@ -10391,13 +10403,13 @@ mont_curve_field_bits(const mont_t *ec) { */ edwards_t * -edwards_curve_create(int type) { +edwards_curve_create(edwards_curve_id_t type) { edwards_t *ec = NULL; - if (type < 0 || (size_t)type > ARRAY_SIZE(edwards_curves)) + if (type < 0 || (size_t)type >= ARRAY_SIZE(edwards_curves)) return NULL; - ec = checked_malloc(sizeof(edwards_t)); + ec = (edwards_t *)checked_malloc(sizeof(edwards_t)); edwards_init(ec, edwards_curves[type]); @@ -10440,24 +10452,25 @@ edwards_curve_field_bits(const edwards_t *ec) { edwards__scratch_t * edwards_scratch_create(const edwards_t *ec, size_t size) { - edwards__scratch_t *scratch = checked_malloc(sizeof(edwards__scratch_t)); + edwards__scratch_t *scratch = + (edwards__scratch_t *)checked_malloc(sizeof(edwards__scratch_t)); size_t length = size / 2; size_t bits = ec->sc.bits; size_t i; scratch->size = size; - scratch->wnd = checked_malloc(length * JSF_SIZE * sizeof(xge_t)); - scratch->wnds = checked_malloc(length * sizeof(xge_t *)); - scratch->naf = checked_malloc(length * (bits + 1) * sizeof(int)); - scratch->nafs = checked_malloc(length * sizeof(int *)); + scratch->wnd = (xge_t *)checked_malloc(length * JSF_SIZE * sizeof(xge_t)); + scratch->wnds = (xge_t **)checked_malloc(length * sizeof(xge_t *)); + scratch->naf = (int *)checked_malloc(length * (bits + 1) * sizeof(int)); + scratch->nafs = (int **)checked_malloc(length * sizeof(int *)); for (i = 0; i < length; i++) { scratch->wnds[i] = &scratch->wnd[i * JSF_SIZE]; scratch->nafs[i] = &scratch->naf[i * (bits + 1)]; } - scratch->points = checked_malloc(size * sizeof(xge_t)); - scratch->coeffs = checked_malloc(size * sizeof(sc_t)); + scratch->points = (xge_t *)checked_malloc(size * sizeof(xge_t)); + scratch->coeffs = (sc_t *)checked_malloc(size * sizeof(sc_t)); return scratch; } @@ -11447,26 +11460,26 @@ ecdsa_derive(const wei_t *ec, } /* - * Schnorr Legacy + * BIP-Schnorr */ int -schnorr_legacy_support(const wei_t *ec) { +bipschnorr_support(const wei_t *ec) { /* [SCHNORR] "Footnotes". */ /* Must be congruent to 3 mod 4. */ return (ec->fe.p[0] & 3) == 3; } size_t -schnorr_legacy_sig_size(const wei_t *ec) { +bipschnorr_sig_size(const wei_t *ec) { return ec->fe.size + ec->sc.size; } static void -schnorr_legacy_hash_nonce(const wei_t *ec, sc_t k, - const unsigned char *scalar, - const unsigned char *msg, - size_t msg_len) { +bipschnorr_hash_nonce(const wei_t *ec, sc_t k, + const unsigned char *scalar, + const unsigned char *msg, + size_t msg_len) { const scalar_field_t *sc = &ec->sc; unsigned char bytes[MAX_SCALAR_SIZE]; hash_t hash; @@ -11487,11 +11500,11 @@ schnorr_legacy_hash_nonce(const wei_t *ec, sc_t k, } static void -schnorr_legacy_hash_challenge(const wei_t *ec, sc_t e, - const unsigned char *R, - const unsigned char *A, - const unsigned char *msg, - size_t msg_len) { +bipschnorr_hash_challenge(const wei_t *ec, sc_t e, + const unsigned char *R, + const unsigned char *A, + const unsigned char *msg, + size_t msg_len) { const prime_field_t *fe = &ec->fe; const scalar_field_t *sc = &ec->sc; unsigned char bytes[MAX_SCALAR_SIZE]; @@ -11514,12 +11527,12 @@ schnorr_legacy_hash_challenge(const wei_t *ec, sc_t e, } int -schnorr_legacy_sign(const wei_t *ec, - unsigned char *sig, - const unsigned char *msg, - size_t msg_len, - const unsigned char *priv) { - /* Schnorr Signing. +bipschnorr_sign(const wei_t *ec, + unsigned char *sig, + const unsigned char *msg, + size_t msg_len, + const unsigned char *priv) { + /* BIP-Schnorr Signing. * * [SCHNORR] "Signing". * [CASH] "Recommended practices for secure signature generation". @@ -11561,7 +11574,7 @@ schnorr_legacy_sign(const wei_t *ec, wei_mul_g(ec, &A, a); - schnorr_legacy_hash_nonce(ec, k, priv, msg, msg_len); + bipschnorr_hash_nonce(ec, k, priv, msg, msg_len); ret &= sc_is_zero(sc, k) ^ 1; @@ -11572,7 +11585,7 @@ schnorr_legacy_sign(const wei_t *ec, ret &= wge_export_x(ec, Rraw, &R); ret &= wge_export(ec, Araw, NULL, &A, 1); - schnorr_legacy_hash_challenge(ec, e, Rraw, Araw, msg, msg_len); + bipschnorr_hash_challenge(ec, e, Rraw, Araw, msg, msg_len); sc_mul(sc, s, e, a); sc_add(sc, s, s, k); @@ -11593,13 +11606,13 @@ schnorr_legacy_sign(const wei_t *ec, } int -schnorr_legacy_verify(const wei_t *ec, - const unsigned char *msg, - size_t msg_len, - const unsigned char *sig, - const unsigned char *pub, - size_t pub_len) { - /* Schnorr Verification. +bipschnorr_verify(const wei_t *ec, + const unsigned char *msg, + size_t msg_len, + const unsigned char *sig, + const unsigned char *pub, + size_t pub_len) { + /* BIP-Schnorr Verification. * * [SCHNORR] "Verification". * [CASH] "Signature verification algorithm". @@ -11658,7 +11671,7 @@ schnorr_legacy_verify(const wei_t *ec, ASSERT(wge_export(ec, Araw, NULL, &A, 1)); - schnorr_legacy_hash_challenge(ec, e, Rraw, Araw, msg, msg_len); + bipschnorr_hash_challenge(ec, e, Rraw, Araw, msg, msg_len); sc_neg(sc, e, e); @@ -11674,15 +11687,15 @@ schnorr_legacy_verify(const wei_t *ec, } int -schnorr_legacy_verify_batch(const wei_t *ec, - const unsigned char *const *msgs, - const size_t *msg_lens, - const unsigned char *const *sigs, - const unsigned char *const *pubs, - const size_t *pub_lens, - size_t len, - wei__scratch_t *scratch) { - /* Schnorr Batch Verification. +bipschnorr_verify_batch(const wei_t *ec, + const unsigned char *const *msgs, + const size_t *msg_lens, + const unsigned char *const *sigs, + const unsigned char *const *pubs, + const size_t *pub_lens, + size_t len, + wei__scratch_t *scratch) { + /* BIP-Schnorr Batch Verification. * * [SCHNORR] "Batch Verification". * @@ -11783,7 +11796,7 @@ schnorr_legacy_verify_batch(const wei_t *ec, ASSERT(wge_export(ec, Araw, NULL, &A, 1)); - schnorr_legacy_hash_challenge(ec, e, Rraw, Araw, msg, msg_len); + bipschnorr_hash_challenge(ec, e, Rraw, Araw, msg, msg_len); if (j == 0) sc_set_word(sc, a, 1); @@ -11829,42 +11842,42 @@ schnorr_legacy_verify_batch(const wei_t *ec, } /* - * Schnorr + * BIP340 */ size_t -schnorr_privkey_size(const wei_t *ec) { +bip340_privkey_size(const wei_t *ec) { return ec->sc.size; } size_t -schnorr_pubkey_size(const wei_t *ec) { +bip340_pubkey_size(const wei_t *ec) { return ec->fe.size; } size_t -schnorr_sig_size(const wei_t *ec) { +bip340_sig_size(const wei_t *ec) { return ec->fe.size + ec->sc.size; } void -schnorr_privkey_generate(const wei_t *ec, - unsigned char *out, - const unsigned char *entropy) { +bip340_privkey_generate(const wei_t *ec, + unsigned char *out, + const unsigned char *entropy) { ecdsa_privkey_generate(ec, out, entropy); } int -schnorr_privkey_verify(const wei_t *ec, const unsigned char *priv) { +bip340_privkey_verify(const wei_t *ec, const unsigned char *priv) { return ecdsa_privkey_verify(ec, priv); } int -schnorr_privkey_export(const wei_t *ec, - unsigned char *d_raw, - unsigned char *x_raw, - unsigned char *y_raw, - const unsigned char *priv) { +bip340_privkey_export(const wei_t *ec, + unsigned char *d_raw, + unsigned char *x_raw, + unsigned char *y_raw, + const unsigned char *priv) { const prime_field_t *fe = &ec->fe; const scalar_field_t *sc = &ec->sc; int ret = 1; @@ -11895,18 +11908,18 @@ schnorr_privkey_export(const wei_t *ec, } int -schnorr_privkey_import(const wei_t *ec, - unsigned char *out, - const unsigned char *bytes, - size_t len) { +bip340_privkey_import(const wei_t *ec, + unsigned char *out, + const unsigned char *bytes, + size_t len) { return ecdsa_privkey_import(ec, out, bytes, len); } int -schnorr_privkey_tweak_add(const wei_t *ec, - unsigned char *out, - const unsigned char *priv, - const unsigned char *tweak) { +bip340_privkey_tweak_add(const wei_t *ec, + unsigned char *out, + const unsigned char *priv, + const unsigned char *tweak) { const scalar_field_t *sc = &ec->sc; int ret = 1; sc_t a, t; @@ -11934,24 +11947,24 @@ schnorr_privkey_tweak_add(const wei_t *ec, } int -schnorr_privkey_tweak_mul(const wei_t *ec, - unsigned char *out, - const unsigned char *priv, - const unsigned char *tweak) { +bip340_privkey_tweak_mul(const wei_t *ec, + unsigned char *out, + const unsigned char *priv, + const unsigned char *tweak) { return ecdsa_privkey_tweak_mul(ec, out, priv, tweak); } int -schnorr_privkey_invert(const wei_t *ec, - unsigned char *out, - const unsigned char *priv) { +bip340_privkey_invert(const wei_t *ec, + unsigned char *out, + const unsigned char *priv) { return ecdsa_privkey_invert(ec, out, priv); } int -schnorr_pubkey_create(const wei_t *ec, - unsigned char *pub, - const unsigned char *priv) { +bip340_pubkey_create(const wei_t *ec, + unsigned char *pub, + const unsigned char *priv) { const scalar_field_t *sc = &ec->sc; int ret = 1; wge_t A; @@ -11972,9 +11985,9 @@ schnorr_pubkey_create(const wei_t *ec, } void -schnorr_pubkey_from_uniform(const wei_t *ec, - unsigned char *out, - const unsigned char *bytes) { +bip340_pubkey_from_uniform(const wei_t *ec, + unsigned char *out, + const unsigned char *bytes) { wge_t A; wei_point_from_uniform(ec, &A, bytes); @@ -11983,10 +11996,10 @@ schnorr_pubkey_from_uniform(const wei_t *ec, } int -schnorr_pubkey_to_uniform(const wei_t *ec, - unsigned char *out, - const unsigned char *pub, - unsigned int hint) { +bip340_pubkey_to_uniform(const wei_t *ec, + unsigned char *out, + const unsigned char *pub, + unsigned int hint) { int ret = 1; wge_t A; @@ -11997,9 +12010,9 @@ schnorr_pubkey_to_uniform(const wei_t *ec, } int -schnorr_pubkey_from_hash(const wei_t *ec, - unsigned char *out, - const unsigned char *bytes) { +bip340_pubkey_from_hash(const wei_t *ec, + unsigned char *out, + const unsigned char *bytes) { wge_t A; wei_point_from_hash(ec, &A, bytes); @@ -12008,11 +12021,11 @@ schnorr_pubkey_from_hash(const wei_t *ec, } int -schnorr_pubkey_to_hash(const wei_t *ec, - unsigned char *out, - const unsigned char *pub, - unsigned int subgroup, - const unsigned char *entropy) { +bip340_pubkey_to_hash(const wei_t *ec, + unsigned char *out, + const unsigned char *pub, + unsigned int subgroup, + const unsigned char *entropy) { int ret = 1; wge_t A; @@ -12024,17 +12037,17 @@ schnorr_pubkey_to_hash(const wei_t *ec, } int -schnorr_pubkey_verify(const wei_t *ec, const unsigned char *pub) { +bip340_pubkey_verify(const wei_t *ec, const unsigned char *pub) { wge_t A; return wge_import_even(ec, &A, pub); } int -schnorr_pubkey_export(const wei_t *ec, - unsigned char *x_raw, - unsigned char *y_raw, - const unsigned char *pub) { +bip340_pubkey_export(const wei_t *ec, + unsigned char *x_raw, + unsigned char *y_raw, + const unsigned char *pub) { const prime_field_t *fe = &ec->fe; int ret = 1; wge_t A; @@ -12048,12 +12061,12 @@ schnorr_pubkey_export(const wei_t *ec, } int -schnorr_pubkey_import(const wei_t *ec, - unsigned char *out, - const unsigned char *x_raw, - size_t x_len, - const unsigned char *y_raw, - size_t y_len) { +bip340_pubkey_import(const wei_t *ec, + unsigned char *out, + const unsigned char *x_raw, + size_t x_len, + const unsigned char *y_raw, + size_t y_len) { const prime_field_t *fe = &ec->fe; int has_x = (x_len > 0); int has_y = (y_len > 0); @@ -12076,11 +12089,11 @@ schnorr_pubkey_import(const wei_t *ec, } int -schnorr_pubkey_tweak_add(const wei_t *ec, - unsigned char *out, - int *negated, - const unsigned char *pub, - const unsigned char *tweak) { +bip340_pubkey_tweak_add(const wei_t *ec, + unsigned char *out, + int *negated, + const unsigned char *pub, + const unsigned char *tweak) { const scalar_field_t *sc = &ec->sc; int ret = 1; wge_t A; @@ -12107,17 +12120,17 @@ schnorr_pubkey_tweak_add(const wei_t *ec, } int -schnorr_pubkey_tweak_add_check(const wei_t *ec, - const unsigned char *pub, - const unsigned char *tweak, - const unsigned char *expect, - int negated) { +bip340_pubkey_tweak_add_check(const wei_t *ec, + const unsigned char *pub, + const unsigned char *tweak, + const unsigned char *expect, + int negated) { const prime_field_t *fe = &ec->fe; unsigned char raw[MAX_FIELD_SIZE]; int ret = 1; int sign; - ret &= schnorr_pubkey_tweak_add(ec, raw, &sign, pub, tweak); + ret &= bip340_pubkey_tweak_add(ec, raw, &sign, pub, tweak); ret &= torsion_memequal(raw, expect, fe->size); ret &= (sign == (negated != 0)); @@ -12125,11 +12138,11 @@ schnorr_pubkey_tweak_add_check(const wei_t *ec, } int -schnorr_pubkey_tweak_mul(const wei_t *ec, - unsigned char *out, - int *negated, - const unsigned char *pub, - const unsigned char *tweak) { +bip340_pubkey_tweak_mul(const wei_t *ec, + unsigned char *out, + int *negated, + const unsigned char *pub, + const unsigned char *tweak) { const scalar_field_t *sc = &ec->sc; int ret = 1; wge_t A; @@ -12151,17 +12164,17 @@ schnorr_pubkey_tweak_mul(const wei_t *ec, } int -schnorr_pubkey_tweak_mul_check(const wei_t *ec, - const unsigned char *pub, - const unsigned char *tweak, - const unsigned char *expect, - int negated) { +bip340_pubkey_tweak_mul_check(const wei_t *ec, + const unsigned char *pub, + const unsigned char *tweak, + const unsigned char *expect, + int negated) { const prime_field_t *fe = &ec->fe; unsigned char raw[MAX_FIELD_SIZE]; int ret = 1; int sign; - ret &= schnorr_pubkey_tweak_mul(ec, raw, &sign, pub, tweak); + ret &= bip340_pubkey_tweak_mul(ec, raw, &sign, pub, tweak); ret &= torsion_memequal(raw, expect, fe->size); ret &= (sign == (negated != 0)); @@ -12169,10 +12182,10 @@ schnorr_pubkey_tweak_mul_check(const wei_t *ec, } int -schnorr_pubkey_add(const wei_t *ec, - unsigned char *out, - const unsigned char *pub1, - const unsigned char *pub2) { +bip340_pubkey_add(const wei_t *ec, + unsigned char *out, + const unsigned char *pub1, + const unsigned char *pub2) { int ret = 1; wge_t P, Q; @@ -12187,10 +12200,10 @@ schnorr_pubkey_add(const wei_t *ec, } int -schnorr_pubkey_combine(const wei_t *ec, - unsigned char *out, - const unsigned char *const *pubs, - size_t len) { +bip340_pubkey_combine(const wei_t *ec, + unsigned char *out, + const unsigned char *const *pubs, + size_t len) { int ret = 1; size_t i; wge_t A; @@ -12218,7 +12231,7 @@ schnorr_pubkey_combine(const wei_t *ec, } static void -schnorr_hash_init(hash_t *hash, int type, const char *tag) { +bip340_hash_init(hash_t *hash, hash_id_t type, const char *tag) { /* [BIP340] "Tagged Hashes". */ size_t hash_size = hash_output_size(type); size_t block_size = hash_block_size(type); @@ -12240,10 +12253,10 @@ schnorr_hash_init(hash_t *hash, int type, const char *tag) { } static void -schnorr_hash_aux(const wei_t *ec, - unsigned char *out, - const unsigned char *scalar, - const unsigned char *aux) { +bip340_hash_aux(const wei_t *ec, + unsigned char *out, + const unsigned char *scalar, + const unsigned char *aux) { const scalar_field_t *sc = &ec->sc; unsigned char bytes[MAX_SCALAR_SIZE]; hash_t hash; @@ -12266,7 +12279,7 @@ schnorr_hash_aux(const wei_t *ec, hash.type = HASH_SHA256; } else { - schnorr_hash_init(&hash, ec->xof, "BIP0340/aux"); + bip340_hash_init(&hash, ec->xof, "BIP0340/aux"); } hash_update(&hash, aux, 32); @@ -12280,12 +12293,12 @@ schnorr_hash_aux(const wei_t *ec, } static void -schnorr_hash_nonce(const wei_t *ec, sc_t k, - const unsigned char *scalar, - const unsigned char *point, - const unsigned char *msg, - size_t msg_len, - const unsigned char *aux) { +bip340_hash_nonce(const wei_t *ec, sc_t k, + const unsigned char *scalar, + const unsigned char *point, + const unsigned char *msg, + size_t msg_len, + const unsigned char *aux) { const prime_field_t *fe = &ec->fe; const scalar_field_t *sc = &ec->sc; unsigned char secret[MAX_SCALAR_SIZE]; @@ -12295,7 +12308,7 @@ schnorr_hash_nonce(const wei_t *ec, sc_t k, STATIC_ASSERT(MAX_SCALAR_SIZE >= HASH_MAX_OUTPUT_SIZE); if (aux != NULL) - schnorr_hash_aux(ec, secret, scalar, aux); + bip340_hash_aux(ec, secret, scalar, aux); else memcpy(secret, scalar, sc->size); @@ -12314,7 +12327,7 @@ schnorr_hash_nonce(const wei_t *ec, sc_t k, hash.type = HASH_SHA256; } else { - schnorr_hash_init(&hash, ec->xof, "BIP0340/nonce"); + bip340_hash_init(&hash, ec->xof, "BIP0340/nonce"); } hash_update(&hash, secret, sc->size); @@ -12332,11 +12345,11 @@ schnorr_hash_nonce(const wei_t *ec, sc_t k, } static void -schnorr_hash_challenge(const wei_t *ec, sc_t e, - const unsigned char *R, - const unsigned char *A, - const unsigned char *msg, - size_t msg_len) { +bip340_hash_challenge(const wei_t *ec, sc_t e, + const unsigned char *R, + const unsigned char *A, + const unsigned char *msg, + size_t msg_len) { const prime_field_t *fe = &ec->fe; const scalar_field_t *sc = &ec->sc; unsigned char bytes[MAX_SCALAR_SIZE]; @@ -12359,7 +12372,7 @@ schnorr_hash_challenge(const wei_t *ec, sc_t e, hash.type = HASH_SHA256; } else { - schnorr_hash_init(&hash, ec->xof, "BIP0340/challenge"); + bip340_hash_init(&hash, ec->xof, "BIP0340/challenge"); } hash_update(&hash, R, fe->size); @@ -12376,13 +12389,13 @@ schnorr_hash_challenge(const wei_t *ec, sc_t e, } int -schnorr_sign(const wei_t *ec, - unsigned char *sig, - const unsigned char *msg, - size_t msg_len, - const unsigned char *priv, - const unsigned char *aux) { - /* Schnorr Signing. +bip340_sign(const wei_t *ec, + unsigned char *sig, + const unsigned char *msg, + size_t msg_len, + const unsigned char *priv, + const unsigned char *aux) { + /* BIP340 Signing. * * [BIP340] "Default Signing". * @@ -12433,7 +12446,7 @@ schnorr_sign(const wei_t *ec, ret &= wge_export_x(ec, Araw, &A); - schnorr_hash_nonce(ec, k, araw, Araw, msg, msg_len, aux); + bip340_hash_nonce(ec, k, araw, Araw, msg, msg_len, aux); ret &= sc_is_zero(sc, k) ^ 1; @@ -12443,7 +12456,7 @@ schnorr_sign(const wei_t *ec, ret &= wge_export_x(ec, Rraw, &R); - schnorr_hash_challenge(ec, e, Rraw, Araw, msg, msg_len); + bip340_hash_challenge(ec, e, Rraw, Araw, msg, msg_len); sc_mul(sc, s, e, a); sc_add(sc, s, s, k); @@ -12465,12 +12478,12 @@ schnorr_sign(const wei_t *ec, } int -schnorr_verify(const wei_t *ec, - const unsigned char *msg, - size_t msg_len, - const unsigned char *sig, - const unsigned char *pub) { - /* Schnorr Verification. +bip340_verify(const wei_t *ec, + const unsigned char *msg, + size_t msg_len, + const unsigned char *sig, + const unsigned char *pub) { + /* BIP340 Verification. * * [BIP340] "Verification". * @@ -12519,7 +12532,7 @@ schnorr_verify(const wei_t *ec, if (!wge_import_even(ec, &A, pub)) return 0; - schnorr_hash_challenge(ec, e, Rraw, pub, msg, msg_len); + bip340_hash_challenge(ec, e, Rraw, pub, msg, msg_len); sc_neg(sc, e, e); @@ -12535,14 +12548,14 @@ schnorr_verify(const wei_t *ec, } int -schnorr_verify_batch(const wei_t *ec, - const unsigned char *const *msgs, - const size_t *msg_lens, - const unsigned char *const *sigs, - const unsigned char *const *pubs, - size_t len, - wei__scratch_t *scratch) { - /* Schnorr Batch Verification. +bip340_verify_batch(const wei_t *ec, + const unsigned char *const *msgs, + const size_t *msg_lens, + const unsigned char *const *sigs, + const unsigned char *const *pubs, + size_t len, + wei__scratch_t *scratch) { + /* BIP340 Batch Verification. * * [BIP340] "Batch Verification". * @@ -12631,7 +12644,7 @@ schnorr_verify_batch(const wei_t *ec, if (!wge_import_even(ec, &A, pub)) return 0; - schnorr_hash_challenge(ec, e, Rraw, pub, msg, msg_len); + bip340_hash_challenge(ec, e, Rraw, pub, msg, msg_len); if (j == 0) sc_set_word(sc, a, 1); @@ -12677,10 +12690,10 @@ schnorr_verify_batch(const wei_t *ec, } int -schnorr_derive(const wei_t *ec, - unsigned char *secret, - const unsigned char *pub, - const unsigned char *priv) { +bip340_derive(const wei_t *ec, + unsigned char *secret, + const unsigned char *pub, + const unsigned char *priv) { const scalar_field_t *sc = &ec->sc; int ret = 1; wge_t A, P; diff --git a/node_modules/bcrypto/deps/torsion/src/encoding.c b/node_modules/bcrypto/deps/torsion/src/encoding.c index bd8ffffce..9b0de8636 100644 --- a/node_modules/bcrypto/deps/torsion/src/encoding.c +++ b/node_modules/bcrypto/deps/torsion/src/encoding.c @@ -73,66 +73,11 @@ base16_encode_size0(size_t len) { return len * 2; } -static void -base16_encode0(char *dst, size_t *dstlen, - const uint8_t *src, size_t srclen, - int endian) { - size_t i = endian < 0 ? srclen - 1 : 0; - size_t j = 0; - - while (srclen--) { - dst[j++] = base16_charset[src[i] >> 4]; - dst[j++] = base16_charset[src[i] & 15]; - - i += endian; - } - - dst[j] = '\0'; - - if (dstlen != NULL) - *dstlen = j; -} - static size_t base16_decode_size0(size_t len) { return len / 2; } -static int -base16_decode0(uint8_t *dst, size_t *dstlen, - const char *src, size_t srclen, - int endian) { - size_t i = endian < 0 ? srclen - 2 : 0; - size_t j = 0; - uint8_t z = 0; - - if (srclen & 1) - return 0; - - srclen /= 2; - endian *= 2; - - while (srclen--) { - uint8_t hi = base16_table[(uint8_t)src[i + 0]]; - uint8_t lo = base16_table[(uint8_t)src[i + 1]]; - - z |= hi | lo; - - dst[j++] = (hi << 4) | lo; - - i += endian; - } - - /* Check for errors at the end. */ - if (z & 0x80) - return 0; - - if (dstlen != NULL) - *dstlen = j; - - return 1; -} - static int base16_test0(const char *str, size_t len) { if (len & 1) @@ -158,7 +103,20 @@ base16_encode_size(size_t len) { void base16_encode(char *dst, size_t *dstlen, const uint8_t *src, size_t srclen) { - base16_encode0(dst, dstlen, src, srclen, 1); + size_t i = 0; + size_t j = 0; + + while (srclen--) { + uint8_t ch = src[i++]; + + dst[j++] = base16_charset[ch >> 4]; + dst[j++] = base16_charset[ch & 15]; + } + + dst[j] = '\0'; + + if (dstlen != NULL) + *dstlen = j; } size_t @@ -169,7 +127,32 @@ base16_decode_size(size_t len) { int base16_decode(uint8_t *dst, size_t *dstlen, const char *src, size_t srclen) { - return base16_decode0(dst, dstlen, src, srclen, 1); + size_t i = 0; + size_t j = 0; + uint8_t z = 0; + + if (srclen & 1) + return 0; + + srclen >>= 1; + + while (srclen--) { + uint8_t hi = base16_table[(uint8_t)src[i++]]; + uint8_t lo = base16_table[(uint8_t)src[i++]]; + + z |= hi | lo; + + dst[j++] = (hi << 4) | lo; + } + + /* Check for errors at the end. */ + if (z & 0x80) + return 0; + + if (dstlen != NULL) + *dstlen = j; + + return 1; } int @@ -189,7 +172,20 @@ base16le_encode_size(size_t len) { void base16le_encode(char *dst, size_t *dstlen, const uint8_t *src, size_t srclen) { - base16_encode0(dst, dstlen, src, srclen, -1); + size_t i = srclen; + size_t j = 0; + + while (srclen--) { + uint8_t ch = src[--i]; + + dst[j++] = base16_charset[ch >> 4]; + dst[j++] = base16_charset[ch & 15]; + } + + dst[j] = '\0'; + + if (dstlen != NULL) + *dstlen = j; } size_t @@ -200,7 +196,32 @@ base16le_decode_size(size_t len) { int base16le_decode(uint8_t *dst, size_t *dstlen, const char *src, size_t srclen) { - return base16_decode0(dst, dstlen, src, srclen, -1); + size_t i = srclen; + size_t j = 0; + uint8_t z = 0; + + if (srclen & 1) + return 0; + + srclen >>= 1; + + while (srclen--) { + uint8_t lo = base16_table[(uint8_t)src[--i]]; + uint8_t hi = base16_table[(uint8_t)src[--i]]; + + z |= hi | lo; + + dst[j++] = (hi << 4) | lo; + } + + /* Check for errors at the end. */ + if (z & 0x80) + return 0; + + if (dstlen != NULL) + *dstlen = j; + + return 1; } int @@ -654,7 +675,7 @@ base58_encode(char *dst, size_t *dstlen, } size = (uint64_t)(srclen - zeroes) * 138 / 100 + 1; - b58 = malloc(size); + b58 = (uint8_t *)malloc(size); if (b58 == NULL) return 0; @@ -721,7 +742,7 @@ base58_decode(uint8_t *dst, size_t *dstlen, } size = (uint64_t)srclen * 733 / 1000 + 1; - b256 = malloc(size); + b256 = (uint8_t *)malloc(size); if (b256 == NULL) return 0; @@ -1222,7 +1243,8 @@ int bech32_serialize(char *str, const char *hrp, const uint8_t *data, - size_t data_len) { + size_t data_len, + uint32_t checksum) { uint32_t chk = 1; size_t i, hlen; size_t j = 0; @@ -1274,7 +1296,7 @@ bech32_serialize(char *str, for (i = 0; i < 6; i++) chk = bech32_polymod(chk); - chk ^= 1; + chk ^= checksum; for (i = 0; i < 6; i++) str[j++] = bech32_charset[(chk >> ((5 - i) * 5)) & 0x1f]; @@ -1288,7 +1310,8 @@ int bech32_deserialize(char *hrp, uint8_t *data, size_t *data_len, - const char *str) { + const char *str, + uint32_t checksum) { uint32_t chk = 1; size_t hlen = 0; size_t i, slen; @@ -1355,7 +1378,7 @@ bech32_deserialize(char *hrp, data[j++] = val; } - if (chk != 1) + if (chk != checksum) return 0; *data_len = j; @@ -1364,12 +1387,12 @@ bech32_deserialize(char *hrp, } int -bech32_is(const char *str) { +bech32_is(const char *str, uint32_t checksum) { char hrp[BECH32_MAX_HRP_SIZE + 1]; uint8_t data[BECH32_MAX_DESERIALIZE_SIZE]; size_t data_len; - return bech32_deserialize(hrp, data, &data_len, str); + return bech32_deserialize(hrp, data, &data_len, str, checksum); } int @@ -1417,7 +1440,8 @@ bech32_encode(char *addr, const char *hrp, unsigned int version, const uint8_t *hash, - size_t hash_len) { + size_t hash_len, + uint32_t checksum) { uint8_t data[BECH32_MAX_DATA_SIZE]; size_t data_len; @@ -1438,7 +1462,7 @@ bech32_encode(char *addr, data_len += 1; - return bech32_serialize(addr, hrp, data, data_len); + return bech32_serialize(addr, hrp, data, data_len, checksum); } int @@ -1446,11 +1470,12 @@ bech32_decode(char *hrp, unsigned int *version, uint8_t *hash, size_t *hash_len, - const char *addr) { + const char *addr, + uint32_t checksum) { uint8_t data[BECH32_MAX_DESERIALIZE_SIZE]; size_t data_len; - if (!bech32_deserialize(hrp, data, &data_len, addr)) + if (!bech32_deserialize(hrp, data, &data_len, addr, checksum)) return 0; if (data_len == 0 || data_len > BECH32_MAX_DATA_SIZE) @@ -1475,13 +1500,13 @@ bech32_decode(char *hrp, } int -bech32_test(const char *addr) { +bech32_test(const char *addr, uint32_t checksum) { char hrp[BECH32_MAX_HRP_SIZE + 1]; unsigned int version; uint8_t hash[BECH32_MAX_DECODE_SIZE]; size_t hash_len; - return bech32_decode(hrp, &version, hash, &hash_len, addr); + return bech32_decode(hrp, &version, hash, &hash_len, addr, checksum); } /* diff --git a/node_modules/bcrypto/deps/torsion/src/entropy/entropy.h b/node_modules/bcrypto/deps/torsion/src/entropy/entropy.h index b60f271d1..9f55c2f91 100644 --- a/node_modules/bcrypto/deps/torsion/src/entropy/entropy.h +++ b/node_modules/bcrypto/deps/torsion/src/entropy/entropy.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_ENTROPY_H -#define _TORSION_ENTROPY_H +#ifndef TORSION_ENTROPY_H +#define TORSION_ENTROPY_H #include #include @@ -14,18 +14,18 @@ * Alias */ -#define torsion_envrand __torsion_envrand -#define torsion_hrtime __torsion_hrtime -#define torsion_rdtsc __torsion_rdtsc -#define torsion_has_cpuid __torsion_has_cpuid -#define torsion_cpuid __torsion_cpuid -#define torsion_has_rdrand __torsion_has_rdrand -#define torsion_has_rdseed __torsion_has_rdseed -#define torsion_rdrand __torsion_rdrand -#define torsion_rdseed __torsion_rdseed -#define torsion_hwrand __torsion_hwrand -#define torsion_getpid __torsion_getpid -#define torsion_sysrand __torsion_sysrand +#define torsion_envrand torsion__envrand +#define torsion_hrtime torsion__hrtime +#define torsion_rdtsc torsion__rdtsc +#define torsion_has_cpuid torsion__has_cpuid +#define torsion_cpuid torsion__cpuid +#define torsion_has_rdrand torsion__has_rdrand +#define torsion_has_rdseed torsion__has_rdseed +#define torsion_rdrand torsion__rdrand +#define torsion_rdseed torsion__rdseed +#define torsion_hwrand torsion__hwrand +#define torsion_getpid torsion__getpid +#define torsion_sysrand torsion__sysrand /* * Entropy @@ -72,4 +72,4 @@ torsion_getpid(void); int torsion_sysrand(void *dst, size_t size); -#endif /* _TORSION_ENTROPY_H */ +#endif /* TORSION_ENTROPY_H */ diff --git a/node_modules/bcrypto/deps/torsion/src/entropy/env.c b/node_modules/bcrypto/deps/torsion/src/entropy/env.c index c0af1b1ae..88222dc3c 100644 --- a/node_modules/bcrypto/deps/torsion/src/entropy/env.c +++ b/node_modules/bcrypto/deps/torsion/src/entropy/env.c @@ -77,7 +77,6 @@ #undef HAVE_CLOCK_GETTIME #undef HAVE_GETHOSTNAME #undef HAVE_GETSID -#undef HAVE_OS_IPHONE #if defined(_WIN32) # include /* required by iphlpapi.h */ @@ -111,7 +110,7 @@ # include /* clock_gettime */ # ifdef __linux__ # if defined(__GLIBC_PREREQ) -# define TORSION_GLIBC_PREREQ(maj, min) __GLIBC_PREREQ(maj, min) +# define TORSION_GLIBC_PREREQ __GLIBC_PREREQ # else # define TORSION_GLIBC_PREREQ(maj, min) 0 # endif @@ -147,11 +146,8 @@ # endif # ifdef __APPLE__ # include -# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE -# define HAVE_OS_IPHONE -# endif # endif -# if defined(__APPLE__) && !defined(HAVE_OS_IPHONE) +# if defined(__APPLE__) && !TARGET_OS_IPHONE # include # define environ (*_NSGetEnviron()) # else @@ -283,7 +279,7 @@ sha512_write_file(sha512_t *hash, const char *file) { #ifdef HAVE_DLITERATEPHDR static int sha512_write_phdr(struct dl_phdr_info *info, size_t size, void *data) { - sha512_t *hash = data; + sha512_t *hash = (sha512_t *)data; (void)size; @@ -393,7 +389,7 @@ sha512_write_cpuids(sha512_t *hash) { for (subleaf = 0; subleaf <= 0xff; subleaf++) { sha512_write_cpuid(hash, &ax, &bx, &cx, &dx, leaf, subleaf); - /* Iterate subleafs for leaf values 4, 7, 11, 13. */ + /* Iterate subleaves for leaf values 4, 7, 11, 13. */ if (leaf == 4) { if ((ax & 0x1f) == 0) break; @@ -407,7 +403,7 @@ sha512_write_cpuids(sha512_t *hash) { if ((cx & 0xff00) == 0) break; } else if (leaf == 13) { - if (ax == 0 && bx == 0 && cx == 0 && dx == 0) + if ((ax | bx | cx | dx) == 0) break; } else { /* For any other leaf, stop after subleaf 0. */ @@ -434,7 +430,7 @@ sha512_write_cpuids(sha512_t *hash) { static void sha512_write_perfdata(sha512_t *hash, size_t max) { size_t size = max < 80 ? max : max / 40; - BYTE *data = malloc(size); + BYTE *data = (BYTE *)malloc(size); DWORD nread; LSTATUS ret; @@ -457,7 +453,7 @@ sha512_write_perfdata(sha512_t *hash, size_t max) { if (size > max) size = max; - data = realloc(data, size); + data = (BYTE *)realloc(data, size); if (data == NULL) break; @@ -608,7 +604,7 @@ sha512_write_static_env(sha512_t *hash) { ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, addrs, &size); if (ret == ERROR_BUFFER_OVERFLOW) { - addrs = realloc(addrs, size); + addrs = (IP_ADAPTER_ADDRESSES *)realloc(addrs, size); if (addrs == NULL) break; diff --git a/node_modules/bcrypto/deps/torsion/src/entropy/hw.c b/node_modules/bcrypto/deps/torsion/src/entropy/hw.c index 9055f3b17..c0f6903bd 100644 --- a/node_modules/bcrypto/deps/torsion/src/entropy/hw.c +++ b/node_modules/bcrypto/deps/torsion/src/entropy/hw.c @@ -44,7 +44,15 @@ * https://www.felixcloutier.com/x86/rdrand * https://www.felixcloutier.com/x86/rdseed * - * POWER9/POWER10 (darn): + * ARMv8.5-A (rndr, rndrrs, pmccntr_el0): + * https://developer.arm.com/documentation/dui0068/b/ARM-Instruction-Reference/Miscellaneous-ARM-instructions/MRS + * https://developer.arm.com/documentation/ddi0595/2021-03/AArch64-Registers/RNDR--Random-Number + * https://developer.arm.com/documentation/ddi0595/2021-03/AArch64-Registers/RNDRRS--Reseeded-Random-Number + * https://developer.arm.com/documentation/ddi0595/2021-03/AArch64-Registers/PMCCNTR-EL0--Performance-Monitors-Cycle-Count-Register + * https://developer.arm.com/documentation/ddi0595/2021-03/AArch64-Registers/ID-AA64ISAR0-EL1--AArch64-Instruction-Set-Attribute-Register-0 + * https://developer.arm.com/documentation/ddi0595/2021-03/AArch64-Registers/ID-DFR0-EL1--AArch32-Debug-Feature-Register-0 + * + * POWER9/POWER10 (darn, mftb): * https://www.docdroid.net/tWT7hjD/powerisa-v30-pdf * https://openpowerfoundation.org/?resource_lib=power-isa-version-3-0 */ @@ -54,10 +62,12 @@ * * One simple source of hardware entropy is the current cycle * count. This is accomplished via RDTSC on x86 CPUs. We only - * call RDTSC if there is an instrinsic for it (win32) or if + * use RDTSC if there is an instrinsic for it (win32) or if * the compiler supports inline ASM (gcc/clang). * - * For non-x86 hardware, we fallback to whatever system clocks + * For ARM and PPC, we use PMCCNTR_EL0 and MFTB respectively. + * + * For other hardware, we fallback to whatever system clocks * are available. This includes: * * - QueryPerformanceCounter, GetSystemTimeAsFileTime (win32) @@ -89,8 +99,13 @@ * use hardware entropy to supplement our full entropy pool. * * On POWER9 and POWER10, the `darn` (Deliver A Random Number) - * instruction is available. We have `torsion_rdrand` return - * the output of `darn` if this is the case. + * instruction is available. We have `torsion_rdrand` as well + * as `torsion_rdseed` return the output of `darn` if this is + * the case. + * + * ARMv8.5-A provides new system registers (RNDR and RNDRRS) + * to be used with the MRS instruction. Similar to `darn`, we + * have `torsion_{rdrand,rdseed}` output the proper values. * * For other hardware, torsion_rdrand and torsion_rdseed are * no-ops returning zero. torsion_has_rd{rand,seed} MUST be @@ -110,12 +125,27 @@ #undef HAVE_QPC #undef HAVE_CLOCK_GETTIME #undef HAVE_GETTIMEOFDAY -#undef HAVE_CPUIDEX #undef HAVE_RDTSC -#undef HAVE_INLINE_ASM -#undef HAVE_CPUID -#undef HAVE_DARN - +#undef HAVE_CPUIDEX +#undef HAVE_RDRAND +#undef HAVE_RDRAND32 +#undef HAVE_RDRAND64 +#undef HAVE_RDSEED +#undef HAVE_RDSEED32 +#undef HAVE_RDSEED64 +#undef HAVE_READSTATUSREG +#undef HAVE_ASM_INTEL +#undef HAVE_ASM_X86 +#undef HAVE_ASM_X64 +#undef HAVE_ASM_ARM64 +#undef HAVE_ASM_PPC64 +#undef HAVE_GETAUXVAL +#undef HAVE_ELFAUXINFO +#undef HAVE_POWERSET +#undef HAVE_AUXVAL +#undef HAVE_PERFMON /* Define if ARM FEAT_PMUv3 is supported. */ + +/* High-resolution time. */ #if defined(_WIN32) # include /* QueryPerformanceCounter, GetSystemTimeAsFileTime */ # pragma comment(lib, "kernel32.lib") @@ -154,23 +184,106 @@ # include /* time */ #endif -#if defined(_MSC_VER) && _MSC_VER >= 1900 /* VS 2015 */ +/* Detect intrinsic and ASM support. */ +#if defined(_MSC_VER) # if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) -# include /* __cpuidex, __rdtsc */ -# include /* _rd{rand,seed}{32,64}_step */ -# pragma intrinsic(__cpuidex, __rdtsc) -# define HAVE_CPUIDEX -# define HAVE_RDTSC +# if _MSC_VER >= 1400 /* VS 2005 */ +# include /* __cpuidex, __rdtsc */ +# pragma intrinsic(__rdtsc) +# define HAVE_RDTSC +# endif +# if _MSC_VER >= 1600 /* VS 2010 */ +# pragma intrinsic(__cpuidex) +# define HAVE_CPUIDEX +# endif +# if _MSC_VER >= 1700 /* VS 2012 */ +# include /* _rd{rand,seed}{32,64}_step */ +# define HAVE_RDRAND +# if defined(_M_AMD64) || defined(_M_X64) +# define HAVE_RDRAND64 +# else +# define HAVE_RDRAND32 +# endif +# endif +# if _MSC_VER >= 1800 /* VS 2013 */ +# define HAVE_RDSEED +# if defined(_M_AMD64) || defined(_M_X64) +# define HAVE_RDSEED64 +# else +# define HAVE_RDSEED32 +# endif +# endif +# elif defined(_M_ARM64) +# include +# define HAVE_READSTATUSREG # endif -#elif defined(__GNUC__) && __GNUC__ >= 4 -# define HAVE_INLINE_ASM -# if defined(__i386__) || defined(__amd64__) || defined(__x86_64__) -# define HAVE_CPUID -# elif defined(__powerpc64__) && (defined(_ARCH_PWR9) || defined(_ARCH_PWR10)) -# define HAVE_DARN +#elif (defined(__GNUC__) && __GNUC__ >= 4) || defined(__IBM_GCC_ASM) +# if defined(__amd64__) || defined(__x86_64__) +# define HAVE_ASM_INTEL +# define HAVE_ASM_X64 +# elif defined(__i386__) +# define HAVE_ASM_INTEL +# define HAVE_ASM_X86 +# elif defined(__aarch64__) +# define HAVE_ASM_ARM64 +# elif defined(__powerpc64__) || defined(_ARCH_PPC64) +# define HAVE_ASM_PPC64 # endif #endif +/* Some insanity to detect features at runtime. */ +#if defined(HAVE_ASM_ARM64) || defined(HAVE_ASM_PPC64) +# if defined(__GLIBC_PREREQ) +# define TORSION_GLIBC_PREREQ __GLIBC_PREREQ +# else +# define TORSION_GLIBC_PREREQ(maj, min) 0 +# endif +# if TORSION_GLIBC_PREREQ(2, 16) +# include /* getauxval */ +# define HAVE_GETAUXVAL +# define HAVE_AUXVAL +# elif defined(__FreeBSD__) +# include +# if defined(__FreeBSD_version) && __FreeBSD_version >= 1200000 /* 12.0 */ +# include /* elf_aux_info */ +# define HAVE_ELFAUXINFO +# define HAVE_AUXVAL +# endif +# elif defined(HAVE_ASM_PPC64) && defined(_AIX53) && !defined(__PASE__) +# include /* __power_set */ +# ifndef __power_set +# define __power_set(x) (_system_configuration.implementation & (x)) +# endif +# define HAVE_POWERSET +# endif +# ifdef HAVE_AUXVAL +# ifndef AT_HWCAP +# define AT_HWCAP 16 +# endif +# ifndef AT_HWCAP2 +# define AT_HWCAP2 26 +# endif +# endif +#endif + +/* + * Auxiliary Value + */ + +#if defined(HAVE_GETAUXVAL) +# define torsion_auxval getauxval +#elif defined(HAVE_ELFAUXINFO) +__attribute__((unused)) static unsigned long +torsion_auxval(unsigned long type) { + unsigned long val; + + if (elf_aux_info(type, &val, sizeof(val)) != 0) + return 0; + + return val; +} +#endif + /* * High-Resolution Time */ @@ -297,6 +410,8 @@ uint64_t torsion_rdtsc(void) { #if defined(HAVE_RDTSC) return __rdtsc(); +#elif defined(HAVE_READSTATUSREG) && defined(HAVE_PERFMON) + return _ReadStatusReg(0x5ce8); /* ARM64_PMCCNTR_EL0 */ #elif defined(HAVE_QPC) LARGE_INTEGER ctr; @@ -304,9 +419,8 @@ torsion_rdtsc(void) { abort(); return (uint64_t)ctr.QuadPart; -#elif defined(HAVE_INLINE_ASM) && defined(__i386__) - /* Borrowed from Bitcoin Core. */ - uint64_t ts = 0; +#elif defined(HAVE_ASM_X86) + uint64_t ts; __asm__ __volatile__ ( "rdtsc\n" @@ -314,10 +428,8 @@ torsion_rdtsc(void) { ); return ts; -#elif defined(HAVE_INLINE_ASM) && (defined(__amd64__) || defined(__x86_64__)) - /* Borrowed from Bitcoin Core. */ - uint64_t lo = 0; - uint64_t hi = 0; +#elif defined(HAVE_ASM_X64) + uint64_t lo, hi; __asm__ __volatile__ ( "rdtsc\n" @@ -326,6 +438,47 @@ torsion_rdtsc(void) { ); return (hi << 32) | lo; +#elif defined(HAVE_ASM_ARM64) && defined(HAVE_PERFMON) + uint64_t ts; + + /* Note that `mrs %0, pmccntr_el0` can be + * spelled out as: + * + * .inst (0xd5200000 | 0x1b9d00 | %0) + * | | | + * mrs sysreg reg + * + * Requires FEAT_PMUv3. We _could_ check: + * + * ((ID_DFR0_EL1 >> 24) & 15) >= 3 + * + * But that is an EL1 register and the + * kernel doesn't emulate the debug + * feature registers (yet). + */ + __asm__ __volatile__ ( + "mrs %0, s3_3_c9_c13_0\n" /* PMCCNTR_EL0 */ + : "=r" (ts) + ); + + return ts; +#elif defined(HAVE_ASM_PPC64) + uint64_t ts; + + /* mftb %0 = mftb %0, 268 + * = mfspr %0, 268 + * mftbu %0 = mftb %0, 269 + * = mfspr %0, 269 + * + * mfspr available since 2.01 + * (excludes 601 and POWER3). + */ + __asm__ __volatile__ ( + "mfspr %0, 268\n" /* mftb %0 */ + : "=r" (ts) + ); + + return ts; #else /* Fall back to high-resolution time. */ return torsion_hrtime(); @@ -340,8 +493,7 @@ int torsion_has_cpuid(void) { #if defined(HAVE_CPUIDEX) return 1; -#elif defined(HAVE_CPUID) -#if defined(__i386__) +#elif defined(HAVE_ASM_X86) uint32_t ax, bx; __asm__ __volatile__ ( @@ -362,9 +514,8 @@ torsion_has_cpuid(void) { ); return ((ax ^ bx) >> 21) & 1; -#else /* !__i386__ */ +#elif defined(HAVE_ASM_X64) return 1; -#endif /* !__i386__ */ #else return 0; #endif @@ -386,19 +537,7 @@ torsion_cpuid(uint32_t *a, *b = regs[1]; *c = regs[2]; *d = regs[3]; -#elif defined(HAVE_CPUID) - *a = 0; - *b = 0; - *c = 0; - *d = 0; -#if defined(__i386__) - /* Older GCC versions reserve %ebx as the global - * offset table register when compiling position - * independent code[1]. We borrow some assembly - * from libsodium to work around this. - * - * [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54232 - */ +#elif defined(HAVE_ASM_X86) if (torsion_has_cpuid()) { __asm__ __volatile__ ( "xchgl %%ebx, %k1\n" @@ -407,14 +546,18 @@ torsion_cpuid(uint32_t *a, : "=a" (*a), "=&r" (*b), "=c" (*c), "=d" (*d) : "0" (leaf), "2" (subleaf) ); + } else { + *a = 0; + *b = 0; + *c = 0; + *d = 0; } -#else /* !__i386__ */ +#elif defined(HAVE_ASM_X64) __asm__ __volatile__ ( "cpuid\n" : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) : "0" (leaf), "2" (subleaf) ); -#endif /* !__i386__ */ #else (void)leaf; (void)subleaf; @@ -432,15 +575,59 @@ torsion_cpuid(uint32_t *a, int torsion_has_rdrand(void) { -#if defined(HAVE_CPUIDEX) || defined(HAVE_CPUID) +#if defined(HAVE_ASM_INTEL) && defined(__RDRND__) + /* Explicitly built with RDRAND support (-mrdrnd). */ + return 1; +#elif defined(HAVE_RDRAND) || defined(HAVE_ASM_INTEL) uint32_t eax, ebx, ecx, edx; + torsion_cpuid(&eax, &ebx, &ecx, &edx, 0, 0); + + if (eax < 1) + return 0; + torsion_cpuid(&eax, &ebx, &ecx, &edx, 1, 0); return (ecx >> 30) & 1; -#elif defined(HAVE_DARN) - /* We have `darn` masquerade as `rdrand`. */ +#elif defined(HAVE_ASM_ARM64) && defined(__ARM_FEATURE_RNG) + /* Explicitly built with ARM RNG support (-march=armv8.5-a+rng). */ return 1; +#elif defined(HAVE_ASM_ARM64) && defined(HAVE_AUXVAL) + /* Bit 16 = RNG support (HWCAP2_RNG) */ + if ((torsion_auxval(AT_HWCAP2) >> 16) & 1) + return 1; + + /* Bit 11 = MRS emulation (HWCAP_CPUID) */ + /* https://www.kernel.org/doc/html/latest/arm64/cpu-feature-registers.html */ + if ((torsion_auxval(AT_HWCAP) >> 11) & 1) { + uint64_t isar0; + + /* Note that `mrs %0, id_aa64isar0_el1` can be + * spelled out as: + * + * .inst (0xd5200000 | 0x180600 | %0) + * | | | + * mrs sysreg reg + */ + __asm__ __volatile__ ( + "mrs %0, s3_0_c0_c6_0\n" /* ID_AA64ISAR0_EL1 */ + : "=r" (isar0) + ); + + /* Bits 63-60 = RNDR (0b0001) */ + return (isar0 >> 60) >= 1; + } + + return 0; +#elif defined(HAVE_ASM_PPC64) && (defined(_ARCH_PWR9) || defined(_ARCH_PWR10)) + /* Explicitly built for POWER9 (-mcpu=power9 or -mpower9-vector). */ + return 1; +#elif defined(HAVE_ASM_PPC64) && defined(HAVE_AUXVAL) + /* Bit 21 = DARN support (PPC_FEATURE2_DARN) */ + return (torsion_auxval(AT_HWCAP2) >> 21) & 1; +#elif defined(HAVE_ASM_PPC64) && defined(HAVE_POWERSET) + /* Check for POWER9 or greater. */ + return __power_set(0xffffffffU << 17) != 0; #else return 0; #endif @@ -448,12 +635,24 @@ torsion_has_rdrand(void) { int torsion_has_rdseed(void) { -#if defined(HAVE_CPUIDEX) || defined(HAVE_CPUID) +#if defined(HAVE_ASM_INTEL) && defined(__RDSEED__) + /* Explicitly built with RDSEED support (-mrdseed). */ + return 1; +#elif defined(HAVE_RDSEED) || defined(HAVE_ASM_INTEL) uint32_t eax, ebx, ecx, edx; + torsion_cpuid(&eax, &ebx, &ecx, &edx, 0, 0); + + if (eax < 7) + return 0; + torsion_cpuid(&eax, &ebx, &ecx, &edx, 7, 0); return (ebx >> 18) & 1; +#elif defined(HAVE_ASM_ARM64) + return torsion_has_rdrand(); +#elif defined(HAVE_ASM_PPC64) + return torsion_has_rdrand(); #else return 0; #endif @@ -461,8 +660,7 @@ torsion_has_rdseed(void) { uint64_t torsion_rdrand(void) { -#if defined(HAVE_CPUIDEX) -#if defined(_M_IX86) +#if defined(HAVE_RDRAND32) unsigned int lo, hi; int i; @@ -477,7 +675,7 @@ torsion_rdrand(void) { } return ((uint64_t)hi << 32) | lo; -#else /* !_M_IX86 */ +#elif defined(HAVE_RDRAND64) unsigned __int64 r; int i; @@ -487,9 +685,7 @@ torsion_rdrand(void) { } return r; -#endif /* !_M_IX86 */ -#elif defined(HAVE_CPUID) -#if defined(__i386__) +#elif defined(HAVE_ASM_X86) /* Borrowed from Bitcoin Core. */ uint32_t lo, hi; uint8_t ok; @@ -522,10 +718,10 @@ torsion_rdrand(void) { } return ((uint64_t)hi << 32) | lo; -#else /* !__i386__ */ +#elif defined(HAVE_ASM_X64) /* Borrowed from Bitcoin Core. */ - uint8_t ok; uint64_t r; + uint8_t ok; int i; for (i = 0; i < 10; i++) { @@ -542,21 +738,56 @@ torsion_rdrand(void) { } return r; -#endif /* !__i386__ */ -#elif defined(HAVE_DARN) - uint64_t r = 0; +#elif defined(HAVE_ASM_ARM64) + uint64_t r; + uint32_t ok; + int i; + + for (i = 0; i < 10; i++) { + /* Note that `mrs %0, rndr` can be spelled out as: + * + * .inst (0xd5200000 | 0x1b2400 | %0) + * | | | + * mrs sysreg reg + * + * Though, this presents a difficulty in that %0 + * will be expanded to `x` instead of ``. + * That is to say, %0 becomes x3 instead of 3. + * + * We can solve this with some crazy macros like + * the linux kernel does, but it's probably not + * worth the effort. + */ + __asm__ __volatile__ ( + "mrs %0, s3_3_c2_c4_0\n" /* RNDR */ + "cset %w1, ne\n" + : "=r" (r), "=r" (ok) + : + : "cc" + ); + + if (ok) + break; + } + + return r; +#elif defined(HAVE_ASM_PPC64) + uint64_t r; int i; for (i = 0; i < 10; i++) { - /* Note that `darn %0, 1` can be spelled out as: + /* Darn modes: * - * .long (0x7c0005e6 | (%0 << 21) | (1 << 16)) + * 0 = 32 bit (conditioned) + * 1 = 64 bit (conditioned) + * 2 = 64 bit (raw) + * 3 = reserved * - * The above was taken from the linux kernel + * Spelling below was taken from the linux kernel * (after stripping out a load of preprocessor). */ __asm__ __volatile__ ( - "darn %0, 1\n" + ".long (0x7c0005e6 | (%0 << 21) | (1 << 16))\n" /* darn %0, 1 */ : "=r" (r) ); @@ -574,8 +805,7 @@ torsion_rdrand(void) { uint64_t torsion_rdseed(void) { -#if defined(HAVE_CPUIDEX) -#if defined(_M_IX86) +#if defined(HAVE_RDSEED32) unsigned int lo, hi; for (;;) { @@ -597,7 +827,7 @@ torsion_rdseed(void) { } return ((uint64_t)hi << 32) | lo; -#else /* !_M_IX86 */ +#elif defined(HAVE_RDSEED64) unsigned __int64 r; for (;;) { @@ -610,9 +840,7 @@ torsion_rdseed(void) { } return r; -#endif /* !_M_IX86 */ -#elif defined(HAVE_CPUID) -#if defined(__i386__) +#elif defined(HAVE_ASM_X86) /* Borrowed from Bitcoin Core. */ uint32_t lo, hi; uint8_t ok; @@ -648,7 +876,7 @@ torsion_rdseed(void) { } return ((uint64_t)hi << 32) | lo; -#else /* !__i386__ */ +#elif defined(HAVE_ASM_X64) /* Borrowed from Bitcoin Core. */ uint64_t r; uint8_t ok; @@ -669,7 +897,49 @@ torsion_rdseed(void) { } return r; -#endif /* !__i386__ */ +#elif defined(HAVE_ASM_ARM64) + uint64_t r; + uint32_t ok; + + for (;;) { + /* Note that `mrs %0, rndrrs` can be spelled out as: + * + * .inst (0xd5200000 | 0x1b2420 | %0) + * | | | + * mrs sysreg reg + */ + __asm__ __volatile__ ( + "mrs %0, s3_3_c2_c4_1\n" /* RNDRRS */ + "cset %w1, ne\n" + : "=r" (r), "=r" (ok) + : + : "cc" + ); + + if (ok) + break; + + __asm__ __volatile__ ("yield\n"); + } + + return r; +#elif defined(HAVE_ASM_PPC64) + uint64_t r; + + for (;;) { + __asm__ __volatile__ ( + ".long (0x7c0005e6 | (%0 << 21) | (2 << 16))\n" /* darn %0, 2 */ + : "=r" (r) + ); + + if (r != UINT64_MAX) + break; + + /* https://stackoverflow.com/questions/5425506 */ + __asm__ __volatile__ ("or 27, 27, 27\n" ::: "cc"); + } + + return r; #else return 0; #endif @@ -681,7 +951,6 @@ torsion_rdseed(void) { int torsion_hwrand(void *dst, size_t size) { -#if defined(HAVE_CPUIDEX) || defined(HAVE_CPUID) || defined(HAVE_DARN) unsigned char *data = (unsigned char *)dst; int has_rdrand = torsion_has_rdrand(); int has_rdseed = torsion_has_rdseed(); @@ -714,9 +983,4 @@ torsion_hwrand(void *dst, size_t size) { } return 1; -#else - (void)dst; - (void)size; - return 0; -#endif } diff --git a/node_modules/bcrypto/deps/torsion/src/entropy/sys.c b/node_modules/bcrypto/deps/torsion/src/entropy/sys.c index 37a252f7c..2a72e6ad5 100644 --- a/node_modules/bcrypto/deps/torsion/src/entropy/sys.c +++ b/node_modules/bcrypto/deps/torsion/src/entropy/sys.c @@ -39,6 +39,9 @@ * https://man.openbsd.org/random.4 * * NetBSD: + * https://www.netbsd.org/~riastradh/tmp/20200510/getrandom.html + * https://github.com/NetBSD/src/blob/6ec11dd/sys/sys/random.h + * https://www.netbsd.org/changes/changes-10.0.html * https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+3+NetBSD-8.0 * https://github.com/NetBSD/src/commit/0a9d2ad * https://github.com/NetBSD/src/commit/3f78162 @@ -52,11 +55,14 @@ * https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html * https://docs.oracle.com/cd/E36784_01/html/E36884/random-7d.html * - * IBM i (PASE): - * https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_71/rzalf/rzalf.pdf - * * AIX: * https://www.ibm.com/support/knowledgecenter/ssw_aix_71/filesreference/random.html + * https://www.ibm.com/docs/en/aix/7.1?topic=files-random-urandom-devices + * https://www.ibm.com/docs/en/aix/7.2?topic=files-random-urandom-devices + * + * IBM i (with PASE): + * https://www.ibm.com/docs/pt/i/7.1?topic=pi-whats-new-i-71 + * https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_71/rzalf/rzalf.pdf * * Haiku: * No official documentation for /dev/random. @@ -85,10 +91,12 @@ * * Emscripten (wasm, asm.js): * https://emscripten.org/docs/api_reference/emscripten.h.html + * https://github.com/emscripten-core/emscripten/pull/6220 * https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues * https://nodejs.org/api/crypto.html#crypto_crypto_randomfillsync_buffer_offset_size * https://github.com/emscripten-core/emscripten/blob/7c3ced6/src/library_uuid.js#L31 * https://github.com/emscripten-core/emscripten/blob/32e1d73/system/include/uuid/uuid.h + * https://github.com/emscripten-core/emscripten/commit/385a660 */ /** @@ -158,9 +166,11 @@ * kern.arandom removed in OpenBSD 6.1 (2017). * * NetBSD: - * Source: sysctl(2) w/ kern.arandom - * Fallback: /dev/urandom - * Support: kern.arandom added in NetBSD 2.0 (2004). + * Source: getrandom(2) + * Fallback 1: sysctl(2) w/ kern.arandom + * Fallback 2: /dev/urandom + * Support: getrandom(2) added in NetBSD 10.0 (2021). + * kern.arandom added in NetBSD 2.0 (2004). * kern.arandom modernized in NetBSD 4.0 (2007). * * DragonFly BSD: @@ -173,14 +183,14 @@ * Fallback: /dev/random * Support: getrandom(2) added in Solaris 11.3 (2015) (SunOS 5.11.3). * - * IBM i (PASE): - * Source: /dev/urandom - * Fallback: none - * * AIX: * Source: /dev/random * Fallback: none * + * IBM i (with PASE): + * Source: /dev/urandom + * Fallback: none + * * Haiku: * Source: /dev/random * Fallback: none @@ -212,11 +222,13 @@ * * Emscripten (wasm, asm.js): * Browser: - * Source: window.crypto.getRandomValues - * Fallback: none + * Source: window.crypto.getRandomValues w/ EM_JS + * Fallback: uuid_generate(3) * Node.js - * Source: crypto.randomFillSync - * Fallback: none + * Source: crypto.randomFillSync w/ EM_JS + * Fallback: uuid_generate(3) + * Support: EM_JS added in Emscripten 1.37.36 (2018). + * uuid_generate(3) added in Emscripten 1.8.6 (2014). * * [1] https://docs.rs/getrandom/0.1.14/getrandom/ */ @@ -256,6 +268,9 @@ # define HAVE_BCRYPTGENRANDOM # else # define RtlGenRandom SystemFunction036 +# ifdef __cplusplus +extern "C" +# endif BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); # pragma comment(lib, "advapi32.lib") @@ -273,6 +288,9 @@ RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); # include /* cloudabi_sys_random_get */ #elif defined(__EMSCRIPTEN__) # include /* EM_JS */ +# ifndef EM_JS /* 1.37.36 (2018) */ +# include /* uuid_generate (1.8.6 (2014)) */ +# endif #elif defined(__wasi__) # include /* __wasi_random_get */ #elif defined(__unix) || defined(__unix__) \ @@ -300,7 +318,7 @@ RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); # endif # define DEV_RANDOM_NAME "/dev/random" # elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -# include +# include /* prior to 3.0.1 (1998) */ # if defined(__FreeBSD_version) && __FreeBSD_version >= 1200000 /* 12.0 (2018) */ # include /* getrandom, getentropy */ # define HAVE_GETRANDOM @@ -316,7 +334,7 @@ RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); # elif defined(__OpenBSD__) # include # if defined(OpenBSD) && OpenBSD >= 201411 /* 5.6 (2014) */ -# define HAVE_GETENTROPY /* resides in unistd.h */ +# define HAVE_GETENTROPY /* resides in */ # endif # if defined(OpenBSD) && OpenBSD >= 200511 /* 3.8 (2005) */ # include /* sysctl */ @@ -327,6 +345,10 @@ RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); # define DEV_RANDOM_NAME "/dev/urandom" # elif defined(__NetBSD__) # include +# if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 1000000000 /* 10.0 (2021) */ +# include /* getrandom */ +# define HAVE_GETRANDOM +# endif # if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 400000000 /* 4.0 (2007) */ # include /* sysctl */ # if defined(CTL_KERN) && defined(KERN_ARND) @@ -342,12 +364,13 @@ RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); # endif # define DEV_RANDOM_NAME "/dev/random" # elif defined(__sun) && defined(__SVR4) /* 11.3 (2015) */ -# if defined(__SUNPRO_C) && __SUNPRO_C >= 0x5140 /* 5.14 (2016) */ +# if (defined(__SUNPRO_C) && __SUNPRO_C >= 0x5140) \ + || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140) /* 5.14 (2016) */ # include /* getrandom */ # define HAVE_GETRANDOM # endif # define DEV_RANDOM_NAME "/dev/random" -# elif defined(__PASE__) +# elif defined(__PASE__) /* IBM i disguised as AIX */ # define DEV_RANDOM_NAME "/dev/urandom" # elif defined(_AIX) # define DEV_RANDOM_NAME "/dev/random" @@ -416,6 +439,7 @@ torsion_open(const char *name, int flags) { */ #ifdef __EMSCRIPTEN__ +#if defined(EM_JS) EM_JS(unsigned short, js_random_get, (unsigned char *dst, unsigned long len), { if (ENVIRONMENT_IS_NODE) { var crypto = module.require('crypto'); @@ -462,6 +486,30 @@ EM_JS(unsigned short, js_random_get, (unsigned char *dst, unsigned long len), { return 1; }) +#else /* !EM_JS */ +static uint16_t +js_random_get(uint8_t *dst, size_t len) { + unsigned char uuid[16]; + size_t max = 14; + + while (len > 0) { + if (max > len) + max = len; + + uuid_generate(uuid); + + uuid[6] = uuid[14]; + uuid[8] = uuid[15]; + + memcpy(dst, uuid, max); + + dst += max; + len -= max; + } + + return 0; +} +#endif /* !EM_JS */ #endif /* __EMSCRIPTEN__ */ /* @@ -477,7 +525,7 @@ torsion_callrand(void *dst, size_t size) { return RtlGenRandom((PVOID)dst, (ULONG)size) == TRUE; #elif defined(HAVE_RANDABYTES) /* __vxworks */ unsigned char *data = (unsigned char *)dst; - size_t max = (size_t)INT_MAX; + size_t max = INT_MAX; int ret; for (;;) { @@ -687,8 +735,8 @@ static int torsion_uuidrand(void *dst, size_t size) { /* Called if we cannot open /dev/urandom (idea from libuv). */ static int name[3] = {1, 40, 6}; /* kern.random.uuid */ + unsigned char *data = (unsigned char *)dst; struct torsion__sysctl_args args; - unsigned char *data = dst; size_t max = 14; char uuid[16]; size_t nread; diff --git a/node_modules/bcrypto/deps/torsion/src/hash.c b/node_modules/bcrypto/deps/torsion/src/hash.c index b4ee8825d..43cb561ca 100644 --- a/node_modules/bcrypto/deps/torsion/src/hash.c +++ b/node_modules/bcrypto/deps/torsion/src/hash.c @@ -49,36 +49,36 @@ blake2b_init(blake2b_t *ctx, size_t len, const unsigned char *key, size_t keylen) { - int i; - CHECK(len >= 1 && len <= 64); CHECK(keylen <= 64); - memset(ctx, 0, sizeof(*ctx)); - - ctx->len = len; + ctx->h[0] = blake2b_iv[0] ^ (0x01010000 | (keylen << 8) | len); + ctx->h[1] = blake2b_iv[1]; + ctx->h[2] = blake2b_iv[2]; + ctx->h[3] = blake2b_iv[3]; + ctx->h[4] = blake2b_iv[4]; + ctx->h[5] = blake2b_iv[5]; + ctx->h[6] = blake2b_iv[6]; + ctx->h[7] = blake2b_iv[7]; - for (i = 0; i < 8; i++) - ctx->h[i] = blake2b_iv[i]; + ctx->t[0] = 0; + ctx->t[1] = 0; - ctx->h[0] ^= 0x01010000 | (keylen << 8) | len; + ctx->pos = 0; + ctx->len = len; if (keylen > 0) { - unsigned char block[128]; + memset(ctx->block, 0x00, 128); + memcpy(ctx->block, key, keylen); - memcpy(block, key, keylen); - memset(block + keylen, 0x00, 128 - keylen); - - blake2b_update(ctx, block, 128); - - torsion_cleanse(block, 128); + ctx->pos = 128; } } static void -blake2b_increment(blake2b_t *ctx, uint64_t x) { - ctx->t[0] += x; - ctx->t[1] += (ctx->t[0] < x); +blake2b_increment(blake2b_t *ctx, uint64_t c) { + ctx->t[0] += c; + ctx->t[1] += (ctx->t[0] < c); } static void @@ -179,40 +179,43 @@ blake2b_update(blake2b_t *ctx, const void *data, size_t len) { size_t pos = ctx->pos; size_t want = 128 - pos; - if (len == 0) - return; - if (len > want) { - memcpy(ctx->block + pos, raw, want); + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - raw += want; - len -= want; + raw += want; + len -= want; + pos = 0; - blake2b_transform(ctx, ctx->block); + blake2b_transform(ctx, ctx->block); + } while (len > 128) { blake2b_transform(ctx, raw); raw += 128; len -= 128; } - - ctx->pos = 0; } - memcpy(ctx->block + ctx->pos, raw, len); + if (len > 0) { + memcpy(ctx->block + pos, raw, len); + pos += len; + } - ctx->pos += len; + ctx->pos = pos; } void blake2b_final(blake2b_t *ctx, unsigned char *out) { size_t count = ctx->len >> 3; + size_t pos = ctx->pos; size_t i; - memset(ctx->block + ctx->pos, 0x00, 128 - ctx->pos); + while (pos < 128) + ctx->block[pos++] = 0x00; blake2b_increment(ctx, ctx->pos); - blake2b_compress(ctx, ctx->block, UINT64_MAX); + blake2b_compress(ctx, ctx->block, -1); for (i = 0; i < count; i++) write64le(out + i * 8, ctx->h[i]); @@ -267,36 +270,36 @@ blake2s_init(blake2s_t *ctx, size_t len, const unsigned char *key, size_t keylen) { - int i; - CHECK(len >= 1 && len <= 32); CHECK(keylen <= 32); - memset(ctx, 0, sizeof(*ctx)); - - ctx->len = len; + ctx->h[0] = blake2s_iv[0] ^ (0x01010000 | (keylen << 8) | len); + ctx->h[1] = blake2s_iv[1]; + ctx->h[2] = blake2s_iv[2]; + ctx->h[3] = blake2s_iv[3]; + ctx->h[4] = blake2s_iv[4]; + ctx->h[5] = blake2s_iv[5]; + ctx->h[6] = blake2s_iv[6]; + ctx->h[7] = blake2s_iv[7]; - for (i = 0; i < 8; i++) - ctx->h[i] = blake2s_iv[i]; + ctx->t[0] = 0; + ctx->t[1] = 0; - ctx->h[0] ^= 0x01010000 | (keylen << 8) | len; + ctx->pos = 0; + ctx->len = len; if (keylen > 0) { - unsigned char block[64]; + memset(ctx->block, 0x00, 64); + memcpy(ctx->block, key, keylen); - memcpy(block, key, keylen); - memset(block + keylen, 0x00, 64 - keylen); - - blake2s_update(ctx, block, 64); - - torsion_cleanse(block, 64); + ctx->pos = 64; } } static void -blake2s_increment(blake2s_t *ctx, uint32_t x) { - ctx->t[0] += x; - ctx->t[1] += (ctx->t[0] < x); +blake2s_increment(blake2s_t *ctx, uint32_t c) { + ctx->t[0] += c; + ctx->t[1] += (ctx->t[0] < c); } static void @@ -393,40 +396,43 @@ blake2s_update(blake2s_t *ctx, const void *data, size_t len) { size_t pos = ctx->pos; size_t want = 64 - pos; - if (len == 0) - return; - if (len > want) { - memcpy(ctx->block + pos, raw, want); + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - raw += want; - len -= want; + raw += want; + len -= want; + pos = 0; - blake2s_transform(ctx, ctx->block); + blake2s_transform(ctx, ctx->block); + } while (len > 64) { blake2s_transform(ctx, raw); raw += 64; len -= 64; } - - ctx->pos = 0; } - memcpy(ctx->block + ctx->pos, raw, len); + if (len > 0) { + memcpy(ctx->block + pos, raw, len); + pos += len; + } - ctx->pos += len; + ctx->pos = pos; } void blake2s_final(blake2s_t *ctx, unsigned char *out) { size_t count = ctx->len >> 2; + size_t pos = ctx->pos; size_t i; - memset(ctx->block + ctx->pos, 0x00, 64 - ctx->pos); + while (pos < 64) + ctx->block[pos++] = 0x00; blake2s_increment(ctx, ctx->pos); - blake2s_compress(ctx, ctx->block, UINT32_MAX); + blake2s_compress(ctx, ctx->block, -1); for (i = 0; i < count; i++) write32le(out + i * 4, ctx->h[i]); @@ -547,7 +553,7 @@ gost94_p(uint8_t *zp, const uint8_t *xp) { } static void -gost94_s(uint8_t *zp, const uint8_t *xp) { +gost94_z(uint8_t *zp, const uint8_t *xp) { uint8_t z30 = xp[0] ^ xp[2] ^ xp[4] ^ xp[6] ^ xp[24] ^ xp[30]; uint8_t z31 = xp[1] ^ xp[3] ^ xp[5] ^ xp[7] ^ xp[25] ^ xp[31]; int i; @@ -602,14 +608,14 @@ gost94_compress(gost94_t *ctx, const uint8_t *mp) { gost94_e(tp + 24, kp); for (i = 0; i < 12; i++) - gost94_s(tp, tp); + gost94_z(tp, tp); gost94_x(tp, tp, mp); - gost94_s(tp, tp); + gost94_z(tp, tp); gost94_x(sp, sp, tp); for (i = 0; i < 61; i++) - gost94_s(sp, sp); + gost94_z(sp, sp); } static void @@ -618,7 +624,7 @@ gost94_sum(gost94_t *ctx, const uint8_t *mp) { int i; for (i = 0; i < 32; i++) { - c += ctx->sigma[i] + mp[i]; + c += (unsigned int)ctx->sigma[i] + mp[i]; ctx->sigma[i] = c; c >>= 8; } @@ -635,58 +641,61 @@ gost94_transform(gost94_t *ctx, const unsigned char *chunk) { gost94_sum(ctx, chunk); } +static void +gost94_increment(gost94_t *ctx, uint64_t c) { + ctx->size[0] += c; c = (ctx->size[0] < c); + ctx->size[1] += c; c = (ctx->size[1] < c); + ctx->size[2] += c; c = (ctx->size[2] < c); + ctx->size[3] += c; +} + void gost94_update(gost94_t *ctx, const void *data, size_t len) { const unsigned char *raw = (const unsigned char *)data; - size_t pos = ctx->size & 31; - - if (len == 0) - return; - - ctx->size += len; - - if (pos > 0) { - size_t want = 32 - pos; - - if (want > len) - want = len; + size_t pos = ctx->size[0] & 31; + size_t want = 32 - pos; - memcpy(ctx->block + pos, raw, want); + gost94_increment(ctx, len); - pos += want; - len -= want; - raw += want; + if (len >= want) { + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - if (pos < 32) - return; + raw += want; + len -= want; + pos = 0; - gost94_transform(ctx, ctx->block); - } + gost94_transform(ctx, ctx->block); + } - while (len >= 32) { - gost94_transform(ctx, raw); - raw += 32; - len -= 32; + while (len >= 32) { + gost94_transform(ctx, raw); + raw += 32; + len -= 32; + } } if (len > 0) - memcpy(ctx->block, raw, len); + memcpy(ctx->block + pos, raw, len); } void gost94_final(gost94_t *ctx, unsigned char *out) { - uint64_t bits = ctx->size << 3; - size_t pos = ctx->size & 31; - unsigned char D[32]; + size_t pos = ctx->size[0] & 31; - memset(D, 0x00, 32); + if (pos > 0) { + while (pos < 32) + ctx->block[pos++] = 0x00; - if (pos != 0) - gost94_update(ctx, D, 32 - pos); + gost94_transform(ctx, ctx->block); + } - write64le(D, bits); + write64le(ctx->block + 0, ctx->size[0] << 3); + write64le(ctx->block + 8, (ctx->size[1] << 3) | (ctx->size[0] >> 61)); + write64le(ctx->block + 16, (ctx->size[2] << 3) | (ctx->size[1] >> 61)); + write64le(ctx->block + 24, (ctx->size[3] << 3) | (ctx->size[2] >> 61)); - gost94_compress(ctx, D); + gost94_compress(ctx, ctx->block); gost94_compress(ctx, ctx->sigma); memcpy(out, ctx->state, 32); @@ -720,7 +729,7 @@ hash160_final(hash160_t *ctx, unsigned char *out) { ripemd160_update(&rmd, tmp, 32); ripemd160_final(&rmd, out); - torsion_cleanse(tmp, sizeof(tmp)); + torsion_memzero(tmp, sizeof(tmp)); } /* @@ -1047,44 +1056,37 @@ void keccak_update(keccak_t *ctx, const void *data, size_t len) { const unsigned char *raw = (const unsigned char *)data; size_t pos = ctx->pos; + size_t want = ctx->bs - pos; - if (len == 0) - return; - - if (pos > 0) { - size_t want = ctx->bs - pos; - - if (want > len) - want = len; - - memcpy(ctx->block + pos, raw, want); + if (len >= want) { + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - pos += want; - len -= want; - raw += want; + raw += want; + len -= want; + pos = 0; - if (pos < ctx->bs) { - ctx->pos = pos; - return; + keccak_transform(ctx, ctx->block); } - keccak_transform(ctx, ctx->block); + while (len >= ctx->bs) { + keccak_transform(ctx, raw); + raw += ctx->bs; + len -= ctx->bs; + } } - while (len >= ctx->bs) { - keccak_transform(ctx, raw); - raw += ctx->bs; - len -= ctx->bs; + if (len > 0) { + memcpy(ctx->block + pos, raw, len); + pos += len; } - if (len > 0) - memcpy(ctx->block, raw, len); - - ctx->pos = len; + ctx->pos = pos; } void keccak_final(keccak_t *ctx, unsigned char *out, unsigned int pad, size_t len) { + size_t pos = ctx->pos; size_t i, count; if (pad == 0) @@ -1095,9 +1097,11 @@ keccak_final(keccak_t *ctx, unsigned char *out, unsigned int pad, size_t len) { CHECK(len <= 200); - memset(ctx->block + ctx->pos, 0x00, ctx->bs - ctx->pos); + ctx->block[pos++] = pad & 0xff; + + while (pos < ctx->bs) + ctx->block[pos++] = 0x00; - ctx->block[ctx->pos] |= (pad & 0xff); ctx->block[ctx->bs - 1] |= 0x80; keccak_transform(ctx, ctx->block); @@ -1192,16 +1196,8 @@ md2_transform(md2_t *ctx, const unsigned char *chunk) { #define C (ctx->checksum) #define W ((uint8_t *)(chunk)) - /* The RFC doesn't describe the specifics - of XOR'ing the checksum, but OpenSSL - seems to do this. */ - l = C[15]; - for (j = 0; j < 16; j++) { c = W[j]; - l = C[j] ^ K[c ^ l]; - - C[j] = l; S[16 + j] = c; S[32 + j] = c ^ S[j]; @@ -1218,6 +1214,18 @@ md2_transform(md2_t *ctx, const unsigned char *chunk) { t = (t + j) & 0xff; } + /* The RFC doesn't describe the specifics + of XOR'ing the checksum, but OpenSSL + seems to do this. */ + l = C[15]; + + for (j = 0; j < 16; j++) { + c = W[j]; + l = C[j] ^ K[c ^ l]; + + C[j] = l; + } + #undef S #undef C #undef W @@ -1227,53 +1235,44 @@ void md2_update(md2_t *ctx, const void *data, size_t len) { const unsigned char *raw = (const unsigned char *)data; size_t pos = ctx->pos; + size_t want = 16 - pos; - if (len == 0) - return; - - if (pos > 0) { - size_t want = 16 - pos; - - if (want > len) - want = len; + if (len >= want) { + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - memcpy(ctx->block + pos, raw, want); + raw += want; + len -= want; + pos = 0; - pos += want; - len -= want; - raw += want; - - if (pos < 16) { - ctx->pos = pos; - return; + md2_transform(ctx, ctx->block); } - md2_transform(ctx, ctx->block); + while (len >= 16) { + md2_transform(ctx, raw); + raw += 16; + len -= 16; + } } - while (len >= 16) { - md2_transform(ctx, raw); - raw += 16; - len -= 16; + if (len > 0) { + memcpy(ctx->block + pos, raw, len); + pos += len; } - if (len > 0) - memcpy(ctx->block, raw, len); - - ctx->pos = len; + ctx->pos = pos; } void md2_final(md2_t *ctx, unsigned char *out) { - size_t left = 16 - ctx->pos; - unsigned char pad[16]; - size_t i; + size_t pos = ctx->pos; + size_t left = 16 - pos; - for (i = 0; i < left; i++) - pad[i] = left; + while (pos < 16) + ctx->block[pos++] = left; - md2_update(ctx, pad, left); - md2_update(ctx, ctx->checksum, 16); + md2_transform(ctx, ctx->block); + md2_transform(ctx, ctx->checksum); memcpy(out, ctx->state, 16); } @@ -1392,51 +1391,54 @@ void md4_update(md4_t *ctx, const void *data, size_t len) { const unsigned char *raw = (const unsigned char *)data; size_t pos = ctx->size & 63; - - if (len == 0) - return; + size_t want = 64 - pos; ctx->size += len; - if (pos > 0) { - size_t want = 64 - pos; - - if (want > len) - want = len; + if (len >= want) { + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - memcpy(ctx->block + pos, raw, want); + raw += want; + len -= want; + pos = 0; - pos += want; - len -= want; - raw += want; - - if (pos < 64) - return; - - md4_transform(ctx, ctx->block); - } + md4_transform(ctx, ctx->block); + } - while (len >= 64) { - md4_transform(ctx, raw); - raw += 64; - len -= 64; + while (len >= 64) { + md4_transform(ctx, raw); + raw += 64; + len -= 64; + } } if (len > 0) - memcpy(ctx->block, raw, len); + memcpy(ctx->block + pos, raw, len); } void md4_final(md4_t *ctx, unsigned char *out) { - static const unsigned char P[64] = { 0x80, 0x00 }; size_t pos = ctx->size & 63; - unsigned char D[8]; int i; - write64le(D, ctx->size << 3); + ctx->block[pos++] = 0x80; - md4_update(ctx, P, 1 + ((119 - pos) & 63)); - md4_update(ctx, D, 8); + if (pos > 56) { + while (pos < 64) + ctx->block[pos++] = 0x00; + + md4_transform(ctx, ctx->block); + + pos = 0; + } + + while (pos < 56) + ctx->block[pos++] = 0x00; + + write64le(ctx->block + 56, ctx->size << 3); + + md4_transform(ctx, ctx->block); for (i = 0; i < 4; i++) write32le(out + i * 4, ctx->state[i]); @@ -1568,51 +1570,54 @@ void md5_update(md5_t *ctx, const void *data, size_t len) { const unsigned char *raw = (const unsigned char *)data; size_t pos = ctx->size & 63; - - if (len == 0) - return; + size_t want = 64 - pos; ctx->size += len; - if (pos > 0) { - size_t want = 64 - pos; - - if (want > len) - want = len; + if (len >= want) { + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - memcpy(ctx->block + pos, raw, want); + raw += want; + len -= want; + pos = 0; - pos += want; - len -= want; - raw += want; - - if (pos < 64) - return; - - md5_transform(ctx, ctx->block); - } + md5_transform(ctx, ctx->block); + } - while (len >= 64) { - md5_transform(ctx, raw); - raw += 64; - len -= 64; + while (len >= 64) { + md5_transform(ctx, raw); + raw += 64; + len -= 64; + } } if (len > 0) - memcpy(ctx->block, raw, len); + memcpy(ctx->block + pos, raw, len); } void md5_final(md5_t *ctx, unsigned char *out) { - static const unsigned char P[64] = { 0x80, 0x00 }; size_t pos = ctx->size & 63; - unsigned char D[8]; int i; - write64le(D, ctx->size << 3); + ctx->block[pos++] = 0x80; - md5_update(ctx, P, 1 + ((119 - pos) & 63)); - md5_update(ctx, D, 8); + if (pos > 56) { + while (pos < 64) + ctx->block[pos++] = 0x00; + + md5_transform(ctx, ctx->block); + + pos = 0; + } + + while (pos < 56) + ctx->block[pos++] = 0x00; + + write64le(ctx->block + 56, ctx->size << 3); + + md5_transform(ctx, ctx->block); for (i = 0; i < 4; i++) write32le(out + i * 4, ctx->state[i]); @@ -1910,51 +1915,54 @@ void ripemd160_update(ripemd160_t *ctx, const void *data, size_t len) { const unsigned char *raw = (const unsigned char *)data; size_t pos = ctx->size & 63; - - if (len == 0) - return; + size_t want = 64 - pos; ctx->size += len; - if (pos > 0) { - size_t want = 64 - pos; - - if (want > len) - want = len; - - memcpy(ctx->block + pos, raw, want); + if (len >= want) { + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - pos += want; - len -= want; - raw += want; + raw += want; + len -= want; + pos = 0; - if (pos < 64) - return; - - ripemd160_transform(ctx, ctx->block); - } + ripemd160_transform(ctx, ctx->block); + } - while (len >= 64) { - ripemd160_transform(ctx, raw); - raw += 64; - len -= 64; + while (len >= 64) { + ripemd160_transform(ctx, raw); + raw += 64; + len -= 64; + } } if (len > 0) - memcpy(ctx->block, raw, len); + memcpy(ctx->block + pos, raw, len); } void ripemd160_final(ripemd160_t *ctx, unsigned char *out) { - static const unsigned char P[64] = { 0x80, 0x00 }; size_t pos = ctx->size & 63; - unsigned char D[8]; int i; - write64le(D, ctx->size << 3); + ctx->block[pos++] = 0x80; + + if (pos > 56) { + while (pos < 64) + ctx->block[pos++] = 0x00; + + ripemd160_transform(ctx, ctx->block); + + pos = 0; + } + + while (pos < 56) + ctx->block[pos++] = 0x00; + + write64le(ctx->block + 56, ctx->size << 3); - ripemd160_update(ctx, P, 1 + ((119 - pos) & 63)); - ripemd160_update(ctx, D, 8); + ripemd160_transform(ctx, ctx->block); for (i = 0; i < 5; i++) write32le(out + i * 4, ctx->state[i]); @@ -2152,51 +2160,54 @@ void sha1_update(sha1_t *ctx, const void *data, size_t len) { const unsigned char *raw = (const unsigned char *)data; size_t pos = ctx->size & 63; - - if (len == 0) - return; + size_t want = 64 - pos; ctx->size += len; - if (pos > 0) { - size_t want = 64 - pos; - - if (want > len) - want = len; - - memcpy(ctx->block + pos, raw, want); - - pos += want; - len -= want; - raw += want; + if (len >= want) { + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - if (pos < 64) - return; + raw += want; + len -= want; + pos = 0; - sha1_transform(ctx, ctx->block); - } + sha1_transform(ctx, ctx->block); + } - while (len >= 64) { - sha1_transform(ctx, raw); - raw += 64; - len -= 64; + while (len >= 64) { + sha1_transform(ctx, raw); + raw += 64; + len -= 64; + } } if (len > 0) - memcpy(ctx->block, raw, len); + memcpy(ctx->block + pos, raw, len); } void sha1_final(sha1_t *ctx, unsigned char *out) { - static const unsigned char P[64] = { 0x80, 0x00 }; size_t pos = ctx->size & 63; - unsigned char D[8]; int i; - write64be(D, ctx->size << 3); + ctx->block[pos++] = 0x80; + + if (pos > 56) { + while (pos < 64) + ctx->block[pos++] = 0x00; + + sha1_transform(ctx, ctx->block); + + pos = 0; + } + + while (pos < 56) + ctx->block[pos++] = 0x00; - sha1_update(ctx, P, 1 + ((119 - pos) & 63)); - sha1_update(ctx, D, 8); + write64be(ctx->block + 56, ctx->size << 3); + + sha1_transform(ctx, ctx->block); for (i = 0; i < 5; i++) write32be(out + i * 4, ctx->state[i]); @@ -2236,7 +2247,7 @@ sha224_final(sha224_t *ctx, unsigned char *out) { memcpy(out, tmp, 28); - torsion_cleanse(tmp, sizeof(tmp)); + torsion_memzero(tmp, sizeof(tmp)); } /* @@ -2420,51 +2431,54 @@ void sha256_update(sha256_t *ctx, const void *data, size_t len) { const unsigned char *raw = (const unsigned char *)data; size_t pos = ctx->size & 63; - - if (len == 0) - return; + size_t want = 64 - pos; ctx->size += len; - if (pos > 0) { - size_t want = 64 - pos; - - if (want > len) - want = len; - - memcpy(ctx->block + pos, raw, want); - - pos += want; - len -= want; - raw += want; + if (len >= want) { + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - if (pos < 64) - return; + raw += want; + len -= want; + pos = 0; - sha256_transform(ctx, ctx->block); - } + sha256_transform(ctx, ctx->block); + } - while (len >= 64) { - sha256_transform(ctx, raw); - raw += 64; - len -= 64; + while (len >= 64) { + sha256_transform(ctx, raw); + raw += 64; + len -= 64; + } } if (len > 0) - memcpy(ctx->block, raw, len); + memcpy(ctx->block + pos, raw, len); } void sha256_final(sha256_t *ctx, unsigned char *out) { - static const unsigned char P[64] = { 0x80, 0x00 }; size_t pos = ctx->size & 63; - unsigned char D[8]; int i; - write64be(D, ctx->size << 3); + ctx->block[pos++] = 0x80; + + if (pos > 56) { + while (pos < 64) + ctx->block[pos++] = 0x00; + + sha256_transform(ctx, ctx->block); + + pos = 0; + } + + while (pos < 56) + ctx->block[pos++] = 0x00; + + write64be(ctx->block + 56, ctx->size << 3); - sha256_update(ctx, P, 1 + ((119 - pos) & 63)); - sha256_update(ctx, D, 8); + sha256_transform(ctx, ctx->block); for (i = 0; i < 8; i++) write32be(out + i * 4, ctx->state[i]); @@ -2488,7 +2502,9 @@ sha384_init(sha384_t *ctx) { ctx->state[5] = UINT64_C(0x8eb44a8768581511); ctx->state[6] = UINT64_C(0xdb0c2e0d64f98fa7); ctx->state[7] = UINT64_C(0x47b5481dbefa4fa4); - ctx->size = 0; + + ctx->size[0] = 0; + ctx->size[1] = 0; } void @@ -2504,7 +2520,7 @@ sha384_final(sha384_t *ctx, unsigned char *out) { memcpy(out, tmp, 48); - torsion_cleanse(tmp, sizeof(tmp)); + torsion_memzero(tmp, sizeof(tmp)); } /* @@ -2525,7 +2541,9 @@ sha512_init(sha512_t *ctx) { ctx->state[5] = UINT64_C(0x9b05688c2b3e6c1f); ctx->state[6] = UINT64_C(0x1f83d9abfb41bd6b); ctx->state[7] = UINT64_C(0x5be0cd19137e2179); - ctx->size = 0; + + ctx->size[0] = 0; + ctx->size[1] = 0; } static void @@ -2700,56 +2718,65 @@ sha512_transform(sha512_t *ctx, const unsigned char *chunk) { ctx->state[7] += H; } +static void +sha512_increment(sha512_t *ctx, uint64_t c) { + ctx->size[0] += c; + ctx->size[1] += (ctx->size[0] < c); +} + void sha512_update(sha512_t *ctx, const void *data, size_t len) { const unsigned char *raw = (const unsigned char *)data; - size_t pos = ctx->size & 127; - - if (len == 0) - return; - - ctx->size += len; - - if (pos > 0) { - size_t want = 128 - pos; - - if (want > len) - want = len; + size_t pos = ctx->size[0] & 127; + size_t want = 128 - pos; - memcpy(ctx->block + pos, raw, want); + sha512_increment(ctx, len); - pos += want; - len -= want; - raw += want; + if (len >= want) { + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - if (pos < 128) - return; + raw += want; + len -= want; + pos = 0; - sha512_transform(ctx, ctx->block); - } + sha512_transform(ctx, ctx->block); + } - while (len >= 128) { - sha512_transform(ctx, raw); - raw += 128; - len -= 128; + while (len >= 128) { + sha512_transform(ctx, raw); + raw += 128; + len -= 128; + } } if (len > 0) - memcpy(ctx->block, raw, len); + memcpy(ctx->block + pos, raw, len); } void sha512_final(sha512_t *ctx, unsigned char *out) { - static const unsigned char P[128] = { 0x80, 0x00 }; - size_t pos = ctx->size & 127; - unsigned char D[16]; + size_t pos = ctx->size[0] & 127; int i; - write64be(D + 0, ctx->size >> (64 - 3)); - write64be(D + 8, ctx->size << 3); + ctx->block[pos++] = 0x80; - sha512_update(ctx, P, 1 + ((239 - pos) & 127)); - sha512_update(ctx, D, 16); + if (pos > 112) { + while (pos < 128) + ctx->block[pos++] = 0x00; + + sha512_transform(ctx, ctx->block); + + pos = 0; + } + + while (pos < 112) + ctx->block[pos++] = 0x00; + + write64be(ctx->block + 112, (ctx->size[1] << 3) | (ctx->size[0] >> 61)); + write64be(ctx->block + 120, ctx->size[0] << 3); + + sha512_transform(ctx, ctx->block); for (i = 0; i < 8; i++) write64be(out + i * 8, ctx->state[i]); @@ -3860,7 +3887,19 @@ static const uint64_t whirlpool_C7[256] = { void whirlpool_init(whirlpool_t *ctx) { - memset(ctx, 0, sizeof(*ctx)); + ctx->state[0] = UINT64_C(0x0000000000000000); + ctx->state[1] = UINT64_C(0x0000000000000000); + ctx->state[2] = UINT64_C(0x0000000000000000); + ctx->state[3] = UINT64_C(0x0000000000000000); + ctx->state[4] = UINT64_C(0x0000000000000000); + ctx->state[5] = UINT64_C(0x0000000000000000); + ctx->state[6] = UINT64_C(0x0000000000000000); + ctx->state[7] = UINT64_C(0x0000000000000000); + + ctx->size[0] = 0; + ctx->size[1] = 0; + ctx->size[2] = 0; + ctx->size[3] = 0; } static void @@ -3913,58 +3952,69 @@ whirlpool_transform(whirlpool_t *ctx, const unsigned char *chunk) { ctx->state[i] ^= S[i] ^ B[i]; } +static void +whirlpool_increment(whirlpool_t *ctx, uint64_t c) { + ctx->size[0] += c; c = (ctx->size[0] < c); + ctx->size[1] += c; c = (ctx->size[1] < c); + ctx->size[2] += c; c = (ctx->size[2] < c); + ctx->size[3] += c; +} + void whirlpool_update(whirlpool_t *ctx, const void *data, size_t len) { const unsigned char *raw = (const unsigned char *)data; - size_t pos = ctx->size & 63; - - if (len == 0) - return; - - ctx->size += len; - - if (pos > 0) { - size_t want = 64 - pos; - - if (want > len) - want = len; + size_t pos = ctx->size[0] & 63; + size_t want = 64 - pos; - memcpy(ctx->block + pos, raw, want); + whirlpool_increment(ctx, len); - pos += want; - len -= want; - raw += want; + if (len >= want) { + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - if (pos < 64) - return; + raw += want; + len -= want; + pos = 0; - whirlpool_transform(ctx, ctx->block); - } + whirlpool_transform(ctx, ctx->block); + } - while (len >= 64) { - whirlpool_transform(ctx, raw); - raw += 64; - len -= 64; + while (len >= 64) { + whirlpool_transform(ctx, raw); + raw += 64; + len -= 64; + } } if (len > 0) - memcpy(ctx->block, raw, len); + memcpy(ctx->block + pos, raw, len); } void whirlpool_final(whirlpool_t *ctx, unsigned char *out) { - static const unsigned char P[64] = { 0x80, 0x00 }; - size_t pos = ctx->size & 63; - unsigned char D[32]; + size_t pos = ctx->size[0] & 63; int i; - memset(D, 0x00, 16); + ctx->block[pos++] = 0x80; + + if (pos > 32) { + while (pos < 64) + ctx->block[pos++] = 0x00; + + whirlpool_transform(ctx, ctx->block); + + pos = 0; + } - write64be(D + 16, ctx->size >> (64 - 3)); - write64be(D + 24, ctx->size << 3); + while (pos < 32) + ctx->block[pos++] = 0x00; - whirlpool_update(ctx, P, 1 + ((95 - pos) & 63)); - whirlpool_update(ctx, D, 32); + write64be(ctx->block + 32, (ctx->size[3] << 3) | (ctx->size[2] >> 61)); + write64be(ctx->block + 40, (ctx->size[2] << 3) | (ctx->size[1] >> 61)); + write64be(ctx->block + 48, (ctx->size[1] << 3) | (ctx->size[0] >> 61)); + write64be(ctx->block + 56, ctx->size[0] << 3); + + whirlpool_transform(ctx, ctx->block); for (i = 0; i < 8; i++) write64be(out + i * 8, ctx->state[i]); @@ -3975,9 +4025,11 @@ whirlpool_final(whirlpool_t *ctx, unsigned char *out) { */ void -hash_init(hash_t *hash, int type) { +hash_init(hash_t *hash, hash_id_t type) { hash->type = type; switch (hash->type) { + case HASH_NONE: + break; case HASH_BLAKE2B_160: blake2b_init(&hash->ctx.blake2b, 20, NULL, 0); break; @@ -4081,6 +4133,8 @@ hash_init(hash_t *hash, int type) { void hash_update(hash_t *hash, const void *data, size_t len) { switch (hash->type) { + case HASH_NONE: + break; case HASH_BLAKE2B_160: case HASH_BLAKE2B_256: case HASH_BLAKE2B_384: @@ -4152,6 +4206,8 @@ hash_update(hash_t *hash, const void *data, size_t len) { void hash_final(hash_t *hash, unsigned char *out, size_t len) { switch (hash->type) { + case HASH_NONE: + break; case HASH_BLAKE2B_160: case HASH_BLAKE2B_256: case HASH_BLAKE2B_384: @@ -4229,8 +4285,10 @@ hash_final(hash_t *hash, unsigned char *out, size_t len) { } int -hash_has_backend(int type) { +hash_has_backend(hash_id_t type) { switch (type) { + case HASH_NONE: + return 0; case HASH_BLAKE2B_160: case HASH_BLAKE2B_256: case HASH_BLAKE2B_384: @@ -4269,8 +4327,10 @@ hash_has_backend(int type) { } size_t -hash_output_size(int type) { +hash_output_size(hash_id_t type) { switch (type) { + case HASH_NONE: + return 0; case HASH_BLAKE2B_160: return 20; case HASH_BLAKE2B_256: @@ -4341,8 +4401,10 @@ hash_output_size(int type) { } size_t -hash_block_size(int type) { +hash_block_size(hash_id_t type) { switch (type) { + case HASH_NONE: + return 0; case HASH_BLAKE2B_160: return 128; case HASH_BLAKE2B_256: @@ -4422,7 +4484,7 @@ hash_block_size(int type) { */ void -hmac_init(hmac_t *hmac, int type, const unsigned char *key, size_t len) { +hmac_init(hmac_t *hmac, hash_id_t type, const unsigned char *key, size_t len) { size_t hash_size = hash_output_size(type); size_t block_size = hash_block_size(type); unsigned char tmp[HASH_MAX_OUTPUT_SIZE]; @@ -4459,8 +4521,8 @@ hmac_init(hmac_t *hmac, int type, const unsigned char *key, size_t len) { hash_init(&hmac->outer, type); hash_update(&hmac->outer, pad, block_size); - torsion_cleanse(tmp, hash_size); - torsion_cleanse(pad, block_size); + torsion_memzero(tmp, hash_size); + torsion_memzero(pad, block_size); } void diff --git a/node_modules/bcrypto/deps/torsion/src/ies.c b/node_modules/bcrypto/deps/torsion/src/ies.c index caaf875d0..ba7418849 100644 --- a/node_modules/bcrypto/deps/torsion/src/ies.c +++ b/node_modules/bcrypto/deps/torsion/src/ies.c @@ -43,7 +43,7 @@ secretbox_seal(unsigned char *sealed, poly1305_update(&poly, ct, msg_len); poly1305_final(&poly, tag); - torsion_cleanse(&salsa, sizeof(salsa)); + torsion_memzero(&salsa, sizeof(salsa)); } int @@ -78,7 +78,7 @@ secretbox_open(unsigned char *msg, salsa20_crypt(&salsa, msg, ct, ct_len); - torsion_cleanse(&salsa, sizeof(salsa)); + torsion_memzero(&salsa, sizeof(salsa)); return ret; } diff --git a/node_modules/bcrypto/deps/torsion/src/internal.c b/node_modules/bcrypto/deps/torsion/src/internal.c index a600cd5bb..90febdd10 100644 --- a/node_modules/bcrypto/deps/torsion/src/internal.c +++ b/node_modules/bcrypto/deps/torsion/src/internal.c @@ -11,8 +11,8 @@ #include #include "internal.h" -void -__torsion_assert_fail(const char *file, int line, const char *expr) { +TORSION_NORETURN void +torsion__assert_fail(const char *file, int line, const char *expr) { /* LCOV_EXCL_START */ #if defined(TORSION_DEBUG) fprintf(stderr, "%s:%d: Assertion `%s' failed.\n", file, line, expr); @@ -26,15 +26,15 @@ __torsion_assert_fail(const char *file, int line, const char *expr) { /* LCOV_EXCL_STOP */ } -void -__torsion_abort(void) { +TORSION_NORETURN void +torsion__abort(void) { abort(); /* LCOV_EXCL_LINE */ } int -__torsion_memcmp(const void *s1, const void *s2, size_t n) { - const unsigned char *x = s1; - const unsigned char *y = s2; +torsion__memcmp(const void *s1, const void *s2, size_t n) { + const unsigned char *x = (const unsigned char *)s1; + const unsigned char *y = (const unsigned char *)s2; size_t i; for (i = 0; i < n; i++) { diff --git a/node_modules/bcrypto/deps/torsion/src/internal.h b/node_modules/bcrypto/deps/torsion/src/internal.h index 92431c188..d268c5059 100644 --- a/node_modules/bcrypto/deps/torsion/src/internal.h +++ b/node_modules/bcrypto/deps/torsion/src/internal.h @@ -4,8 +4,8 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_INTERNAL_H -#define _TORSION_INTERNAL_H +#ifndef TORSION_INTERNAL_H +#define TORSION_INTERNAL_H /* * Clang Compat @@ -34,31 +34,43 @@ #undef LIKELY #undef UNLIKELY +#undef UNPREDICTABLE #if TORSION_GNUC_PREREQ(3, 0) || TORSION_HAS_BUILTIN(__builtin_expect) -# define LIKELY(x) __builtin_expect(!!(x), 1) -# define UNLIKELY(x) __builtin_expect(!!(x), 0) +# define LIKELY(x) __builtin_expect(x, 1) +# define UNLIKELY(x) __builtin_expect(x, 0) #else # define LIKELY(x) (x) # define UNLIKELY(x) (x) #endif +#if TORSION_HAS_BUILTIN(__builtin_unpredictable) +# define UNPREDICTABLE __builtin_unpredictable +#else +# define UNPREDICTABLE(x) (x) +#endif + /* * Sanity Checks */ #undef CHECK_ALWAYS +#undef CHECK_NEVER #undef CHECK #define CHECK_ALWAYS(expr) do { \ if (UNLIKELY(!(expr))) \ - __torsion_abort(); \ + torsion__abort(); \ +} while (0) + +#define CHECK_NEVER(expr) do { \ + (void)(expr); \ } while (0) #if !defined(TORSION_COVERAGE) -# define CHECK(expr) CHECK_ALWAYS(expr) +# define CHECK CHECK_ALWAYS #else -# define CHECK(expr) do { (void)(expr); } while (0) +# define CHECK CHECK_NEVER #endif /* @@ -66,17 +78,22 @@ */ #undef ASSERT_ALWAYS +#undef ASSERT_NEVER #undef ASSERT -#define ASSERT_ALWAYS(expr) do { \ - if (UNLIKELY(!(expr))) \ - __torsion_assert_fail(__FILE__, __LINE__, #expr); \ +#define ASSERT_ALWAYS(expr) do { \ + if (UNLIKELY(!(expr))) \ + torsion__assert_fail(__FILE__, __LINE__, #expr); \ +} while (0) + +#define ASSERT_NEVER(expr) do { \ + (void)(expr); \ } while (0) #if defined(TORSION_DEBUG) && !defined(TORSION_COVERAGE) -# define ASSERT(expr) ASSERT_ALWAYS(expr) +# define ASSERT ASSERT_ALWAYS #else -# define ASSERT(expr) do { (void)(expr); } while (0) +# define ASSERT ASSERT_NEVER #endif /* @@ -88,13 +105,17 @@ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L # undef _Static_assert # define STATIC_ASSERT(expr) _Static_assert(expr, "") +#elif defined(__cplusplus) && (__cplusplus + 0L) >= 201703L +# define STATIC_ASSERT(expr) static_assert(expr) +#elif defined(__cplusplus) && (__cplusplus + 0L) >= 201103L +# define STATIC_ASSERT(expr) static_assert(expr, "") #elif TORSION_GNUC_PREREQ(2, 7) -# define __TORSION_STATIC_ASSERT(x, y) \ - typedef char __torsion_assert_ ## y[(x) ? 1 : -1] __attribute__((unused)) -# define _TORSION_STATIC_ASSERT(x, y) __TORSION_STATIC_ASSERT(x, y) -# define STATIC_ASSERT(expr) _TORSION_STATIC_ASSERT(expr, __LINE__) +# define STATIC_ASSERT_2(x, y) \ + typedef char torsion__assert_ ## y[(x) ? 1 : -1] __attribute__((unused)) +# define STATIC_ASSERT_1(x, y) STATIC_ASSERT_2(x, y) +# define STATIC_ASSERT(expr) STATIC_ASSERT_1(expr, __LINE__) #else -# define STATIC_ASSERT(expr) struct __torsion_assert_empty +# define STATIC_ASSERT(expr) struct torsion__assert_empty #endif /* @@ -103,10 +124,15 @@ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L # define TORSION_INLINE inline +#elif defined(__cplusplus) && (__cplusplus + 0L) >= 199711L +# define TORSION_INLINE inline #elif TORSION_GNUC_PREREQ(2, 7) # define TORSION_INLINE __inline__ #elif defined(_MSC_VER) && _MSC_VER >= 900 # define TORSION_INLINE __inline +#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x560) \ + || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x560) +# define TORSION_INLINE inline #else # define TORSION_INLINE #endif @@ -117,23 +143,34 @@ # define TORSION_RESTRICT __restrict__ #elif defined(_MSC_VER) && _MSC_VER >= 1400 # define TORSION_RESTRICT __restrict +#elif defined(__SUNPRO_C) && __SUNPRO_C >= 0x530 +# define TORSION_RESTRICT _Restrict #else # define TORSION_RESTRICT #endif #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L # define TORSION_NORETURN _Noreturn +#elif defined(__cplusplus) && (__cplusplus + 0L) >= 201103L +# undef noreturn +# define TORSION_NORETURN [[noreturn]] #elif TORSION_GNUC_PREREQ(2, 7) # undef noreturn # define TORSION_NORETURN __attribute__((noreturn)) #elif defined(_MSC_VER) && _MSC_VER >= 1200 # undef noreturn # define TORSION_NORETURN __declspec(noreturn) +#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) \ + || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590) +# undef noreturn +# define TORSION_NORETURN __attribute__((noreturn)) #else # define TORSION_NORETURN #endif -#if TORSION_GNUC_PREREQ(2, 7) +#if defined(__cplusplus) && (__cplusplus + 0L) >= 201703L +# define TORSION_UNUSED [[maybe_unused]] +#elif TORSION_GNUC_PREREQ(2, 7) # define TORSION_UNUSED __attribute__((unused)) #else # define TORSION_UNUSED @@ -150,10 +187,10 @@ */ /* Any decent compiler should be able to optimize this out. */ -static const unsigned long __torsion_endian_check TORSION_UNUSED = 1; +static const unsigned long torsion__endian_check TORSION_UNUSED = 1; #define TORSION_BIGENDIAN \ - (*((const unsigned char *)&__torsion_endian_check) == 0) + (*((const unsigned char *)&torsion__endian_check) == 0) /* * Configuration @@ -291,23 +328,23 @@ prefix ## _barrier(type x) { \ * Helpers */ -#define torsion_abort __torsion_abort +#define torsion_abort torsion__abort #if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) /* Avoid a GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95189 */ -# define torsion_memcmp __torsion_memcmp +# define torsion_memcmp torsion__memcmp #else /* Note: caller must include . */ # define torsion_memcmp memcmp #endif TORSION_NORETURN void -__torsion_assert_fail(const char *file, int line, const char *expr); +torsion__assert_fail(const char *file, int line, const char *expr); TORSION_NORETURN void -__torsion_abort(void); +torsion__abort(void); int -__torsion_memcmp(const void *s1, const void *s2, size_t n); +torsion__memcmp(const void *s1, const void *s2, size_t n); -#endif /* _TORSION_INTERNAL_H */ +#endif /* TORSION_INTERNAL_H */ diff --git a/node_modules/bcrypto/deps/torsion/src/kdf.c b/node_modules/bcrypto/deps/torsion/src/kdf.c index 665fb9d96..777375b6d 100644 --- a/node_modules/bcrypto/deps/torsion/src/kdf.c +++ b/node_modules/bcrypto/deps/torsion/src/kdf.c @@ -26,6 +26,7 @@ #include #include #include +#include "bf.h" #include "bio.h" /* @@ -280,8 +281,8 @@ bcrypt_hash192(unsigned char *out, for (j = 0; j < BCRYPT_BLOCKS192; j++) write32be(out + j * 4, cdata[j]); - torsion_cleanse(cdata, sizeof(cdata)); - torsion_cleanse(&state, sizeof(state)); + torsion_memzero(cdata, sizeof(cdata)); + torsion_memzero(&state, sizeof(state)); } void @@ -319,8 +320,8 @@ bcrypt_hash256(unsigned char *out, for (j = 0; j < BCRYPT_BLOCKS256; j++) write32le(out + j * 4, cdata[j]); - torsion_cleanse(cdata, sizeof(cdata)); - torsion_cleanse(&state, sizeof(state)); + torsion_memzero(cdata, sizeof(cdata)); + torsion_memzero(&state, sizeof(state)); } int @@ -398,12 +399,12 @@ bcrypt_pbkdf(unsigned char *key, keylen -= i; } - torsion_cleanse(out, sizeof(out)); - torsion_cleanse(tmpout, sizeof(tmpout)); - torsion_cleanse(sha2pass, sizeof(sha2pass)); - torsion_cleanse(sha2salt, sizeof(sha2salt)); - torsion_cleanse(&shash, sizeof(shash)); - torsion_cleanse(&hash, sizeof(hash)); + torsion_memzero(out, sizeof(out)); + torsion_memzero(tmpout, sizeof(tmpout)); + torsion_memzero(sha2pass, sizeof(sha2pass)); + torsion_memzero(sha2salt, sizeof(sha2salt)); + torsion_memzero(&shash, sizeof(shash)); + torsion_memzero(&hash, sizeof(hash)); return 1; } @@ -450,8 +451,8 @@ bcrypt_derive(unsigned char *out, memcpy(out, tmp, BCRYPT_HASH192); - torsion_cleanse(tmp, sizeof(tmp)); - torsion_cleanse(key, sizeof(key)); + torsion_memzero(tmp, sizeof(tmp)); + torsion_memzero(key, sizeof(key)); return 1; } @@ -521,7 +522,7 @@ bcrypt_verify(const unsigned char *pass, size_t pass_len, const char *record) { int eb2k_derive(unsigned char *key, unsigned char *iv, - int type, + hash_id_t type, const unsigned char *passwd, size_t passwd_len, const unsigned char *salt, @@ -587,8 +588,8 @@ eb2k_derive(unsigned char *key, } } - torsion_cleanse(prev, sizeof(prev)); - torsion_cleanse(&hash, sizeof(hash)); + torsion_memzero(prev, sizeof(prev)); + torsion_memzero(&hash, sizeof(hash)); return 1; } @@ -602,7 +603,7 @@ eb2k_derive(unsigned char *key, */ int -hkdf_extract(unsigned char *out, int type, +hkdf_extract(unsigned char *out, hash_id_t type, const unsigned char *ikm, size_t ikm_len, const unsigned char *salt, size_t salt_len) { hmac_t hmac; @@ -619,7 +620,7 @@ hkdf_extract(unsigned char *out, int type, int hkdf_expand(unsigned char *out, - int type, + hash_id_t type, const unsigned char *prk, const unsigned char *info, size_t info_len, @@ -670,9 +671,9 @@ hkdf_expand(unsigned char *out, len -= hash_size; } - torsion_cleanse(prev, sizeof(prev)); - torsion_cleanse(&pmac, sizeof(pmac)); - torsion_cleanse(&hmac, sizeof(hmac)); + torsion_memzero(prev, sizeof(prev)); + torsion_memzero(&pmac, sizeof(pmac)); + torsion_memzero(&hmac, sizeof(hmac)); return 1; } @@ -691,7 +692,7 @@ hkdf_expand(unsigned char *out, int pbkdf2_derive(unsigned char *out, - int type, + hash_id_t type, const unsigned char *pass, size_t pass_len, const unsigned char *salt, @@ -757,11 +758,11 @@ pbkdf2_derive(unsigned char *out, len -= hash_size; } - torsion_cleanse(block, sizeof(block)); - torsion_cleanse(mac, sizeof(mac)); - torsion_cleanse(&pmac, sizeof(pmac)); - torsion_cleanse(&smac, sizeof(smac)); - torsion_cleanse(&hmac, sizeof(hmac)); + torsion_memzero(block, sizeof(block)); + torsion_memzero(mac, sizeof(mac)); + torsion_memzero(&pmac, sizeof(pmac)); + torsion_memzero(&smac, sizeof(smac)); + torsion_memzero(&hmac, sizeof(hmac)); return 1; } @@ -775,7 +776,7 @@ pbkdf2_derive(unsigned char *out, int pgpdf_derive_simple(unsigned char *out, - int type, + hash_id_t type, const unsigned char *pass, size_t pass_len, size_t len) { @@ -784,7 +785,7 @@ pgpdf_derive_simple(unsigned char *out, int pgpdf_derive_salted(unsigned char *out, - int type, + hash_id_t type, const unsigned char *pass, size_t pass_len, const unsigned char *salt, @@ -821,15 +822,15 @@ pgpdf_derive_salted(unsigned char *out, i += 1; } - torsion_cleanse(buf, sizeof(buf)); - torsion_cleanse(&hash, sizeof(hash)); + torsion_memzero(buf, sizeof(buf)); + torsion_memzero(&hash, sizeof(hash)); return 1; } int pgpdf_derive_iterated(unsigned char *out, - int type, + hash_id_t type, const unsigned char *pass, size_t pass_len, const unsigned char *salt, @@ -898,8 +899,8 @@ pgpdf_derive_iterated(unsigned char *out, i += 1; } - torsion_cleanse(buf, sizeof(buf)); - torsion_cleanse(&hash, sizeof(hash)); + torsion_memzero(buf, sizeof(buf)); + torsion_memzero(&hash, sizeof(hash)); return 1; } @@ -931,8 +932,7 @@ scrypt_derive(unsigned char *out, uint32_t r, uint32_t p, size_t len) { - uint64_t len64 = len; - int t = HASH_SHA256; + hash_id_t t = HASH_SHA256; uint8_t *B = NULL; uint8_t *V = NULL; uint8_t *XY = NULL; @@ -944,7 +944,7 @@ scrypt_derive(unsigned char *out, if (N == 0 || R == 0 || P == 0) return 0; - if (len64 > ((UINT64_C(1) << 32) - 1) * 32) + if (len + 31 < len || (len + 31) / 32 > UINT32_MAX) return 0; if ((uint64_t)R * (uint64_t)P >= (UINT64_C(1) << 30)) @@ -965,9 +965,9 @@ scrypt_derive(unsigned char *out, if (len == 0) return 1; - B = malloc(128 * R * P); - XY = malloc(256 * R); - V = malloc(128 * R * N); + B = (uint8_t *)malloc(128 * R * P); + XY = (uint8_t *)malloc(256 * R); + V = (uint8_t *)malloc(128 * R * N); if (B == NULL || XY == NULL || V == NULL) goto fail; @@ -984,17 +984,17 @@ scrypt_derive(unsigned char *out, ret = 1; fail: if (B != NULL) { - torsion_cleanse(B, 128 * R * P); + torsion_memzero(B, 128 * R * P); free(B); } if (XY != NULL) { - torsion_cleanse(XY, 256 * R); + torsion_memzero(XY, 256 * R); free(XY); } if (V != NULL) { - torsion_cleanse(V, 128 * R * N); + torsion_memzero(V, 128 * R * N); free(V); } diff --git a/node_modules/bcrypto/deps/torsion/src/mac.c b/node_modules/bcrypto/deps/torsion/src/mac.c index ce6cc1f4f..cdf2f3628 100644 --- a/node_modules/bcrypto/deps/torsion/src/mac.c +++ b/node_modules/bcrypto/deps/torsion/src/mac.c @@ -20,6 +20,21 @@ #include "bio.h" #include "internal.h" +#undef HAVE_UMUL128 +#undef HAVE_UMULH + +#if defined(_MSC_VER) && _MSC_VER >= 1400 /* VS 2005 */ +# include +# if defined(_M_AMD64) || defined(_M_X64) +# pragma intrinsic(_umul128) +# define HAVE_UMUL128 +# endif +# if defined(_M_AMD64) || defined(_M_X64) || defined(_M_ARM64) +# pragma intrinsic(__umulh) +# define HAVE_UMULH +# endif +#endif + /* * Poly1305 * @@ -30,9 +45,60 @@ * https://github.com/floodyberry/poly1305-donna/blob/master/poly1305-donna-64.h */ +#if defined(TORSION_HAVE_INT128) + +#define POLY1305_HAVE_64BIT + +typedef torsion_uint128_t poly1305_uint128_t; + +#define poly1305_mul(z, x, y) ((z) = (poly1305_uint128_t)(x) * (y)) +#define poly1305_add(z, x) ((z) += (x)) +#define poly1305_add_1(z, x) ((z) += (x)) +#define poly1305_shr(x, n) ((uint64_t)((x) >> (n))) +#define poly1305_lo(x) ((uint64_t)(x)) + +#elif defined(HAVE_UMUL128) || defined(HAVE_UMULH) /* !TORSION_HAVE_INT128 */ + +#define POLY1305_HAVE_64BIT + +typedef struct poly1305_uint128_s { + uint64_t lo; + uint64_t hi; +} poly1305_uint128_t; + +#if defined(HAVE_UMUL128) +#define poly1305_mul(z, x, y) do { \ + (z).lo = _umul128((x), (y), &(z).hi); \ +} while (0) +#else +#define poly1305_mul(z, x, y) do { \ + (z).hi = __umulh(x, y); \ + (z).lo = (x) * (y); \ +} while (0) +#endif + +#define poly1305_add(z, x) do { \ + uint64_t _lo = (z).lo + (x).lo; \ + (z).hi += (x).hi + (_lo < (x).lo); \ + (z).lo = _lo; \ +} while (0) + +#define poly1305_add_1(z, x) do { \ + uint64_t _lo = (z).lo + (x); \ + (z).hi += (_lo < (x)); \ + (z).lo = _lo; \ +} while (0) + +#define poly1305_shr(x, n) \ + (((x).lo >> (n)) | ((x).hi << (64 - (n)))) + +#define poly1305_lo(x) ((x).lo) + +#endif /* HAVE_UMUL128 */ + void poly1305_init(poly1305_t *ctx, const unsigned char *key) { -#if defined(TORSION_HAVE_INT128) +#if defined(POLY1305_HAVE_64BIT) struct poly1305_64_s *st = &ctx->state.u64; uint64_t t0 = read64le(key + 0); uint64_t t1 = read64le(key + 8); @@ -51,8 +117,8 @@ poly1305_init(poly1305_t *ctx, const unsigned char *key) { st->pad[0] = read64le(key + 16); st->pad[1] = read64le(key + 24); - ctx->size = 0; -#else /* !TORSION_HAVE_INT128 */ + ctx->pos = 0; +#else /* !POLY1305_HAVE_64BIT */ struct poly1305_32_s *st = &ctx->state.u32; /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ @@ -75,15 +141,15 @@ poly1305_init(poly1305_t *ctx, const unsigned char *key) { st->pad[2] = read32le(key + 24); st->pad[3] = read32le(key + 28); - ctx->size = 0; -#endif /* !TORSION_HAVE_INT128 */ + ctx->pos = 0; +#endif /* !POLY1305_HAVE_64BIT */ } static void poly1305_blocks(poly1305_t *ctx, const unsigned char *data, size_t len, int final) { -#if defined(TORSION_HAVE_INT128) +#if defined(POLY1305_HAVE_64BIT) struct poly1305_64_s *st = &ctx->state.u64; uint64_t hibit = final ? 0 : (UINT64_C(1) << 40); /* 1 << 128 */ uint64_t r0 = st->r[0]; @@ -95,7 +161,7 @@ poly1305_blocks(poly1305_t *ctx, uint64_t s1 = r1 * (5 << 2); uint64_t s2 = r2 * (5 << 2); uint64_t c, t0, t1; - torsion_uint128_t d0, d1, d2, d; + poly1305_uint128_t d0, d1, d2, d; while (len >= 16) { /* h += m[i] */ @@ -107,38 +173,38 @@ poly1305_blocks(poly1305_t *ctx, h2 += (((t1 >> 24)) & UINT64_C(0x3ffffffffff)) | hibit; /* h *= r */ - d0 = (torsion_uint128_t)h0 * r0; - d = (torsion_uint128_t)h1 * s2; - d0 += d; - d = (torsion_uint128_t)h2 * s1; - d0 += d; - - d1 = (torsion_uint128_t)h0 * r1; - d = (torsion_uint128_t)h1 * r0; - d1 += d; - d = (torsion_uint128_t)h2 * s2; - d1 += d; - - d2 = (torsion_uint128_t)h0 * r2; - d = (torsion_uint128_t)h1 * r1; - d2 += d; - d = (torsion_uint128_t)h2 * r0; - d2 += d; + poly1305_mul(d0, h0, r0); + poly1305_mul(d, h1, s2); + poly1305_add(d0, d); + poly1305_mul(d, h2, s1); + poly1305_add(d0, d); + + poly1305_mul(d1, h0, r1); + poly1305_mul(d, h1, r0); + poly1305_add(d1, d); + poly1305_mul(d, h2, s2); + poly1305_add(d1, d); + + poly1305_mul(d2, h0, r2); + poly1305_mul(d, h1, r1); + poly1305_add(d2, d); + poly1305_mul(d, h2, r0); + poly1305_add(d2, d); /* (partial) h %= p */ - c = (uint64_t)(d0 >> 44); - h0 = (uint64_t)d0 & UINT64_C(0xfffffffffff); + c = poly1305_shr(d0, 44); + h0 = poly1305_lo(d0) & UINT64_C(0xfffffffffff); - d1 += c; - c = (uint64_t)(d1 >> 44); - h1 = (uint64_t)d1 & UINT64_C(0xfffffffffff); + poly1305_add_1(d1, c); + c = poly1305_shr(d1, 44); + h1 = poly1305_lo(d1) & UINT64_C(0xfffffffffff); - d2 += c; - c = (uint64_t)(d2 >> 42); - h2 = (uint64_t)d2 & UINT64_C(0x3ffffffffff); + poly1305_add_1(d2, c); + c = poly1305_shr(d2, 42); + h2 = poly1305_lo(d2) & UINT64_C(0x3ffffffffff); h0 += c * 5; - c = (h0 >> 44); + c = h0 >> 44; h0 &= UINT64_C(0xfffffffffff); h1 += c; @@ -150,7 +216,7 @@ poly1305_blocks(poly1305_t *ctx, st->h[0] = h0; st->h[1] = h1; st->h[2] = h2; -#else /* !TORSION_HAVE_INT128 */ +#else /* !POLY1305_HAVE_64BIT */ struct poly1305_32_s *st = &ctx->state.u32; uint32_t hibit = final ? 0 : (UINT32_C(1) << 24); /* 1 << 128 */ uint32_t r0 = st->r[0]; @@ -230,7 +296,7 @@ poly1305_blocks(poly1305_t *ctx, h4 = (uint32_t)d4 & 0x3ffffff; h0 += c * 5; - c = (h0 >> 26); + c = h0 >> 26; h0 &= 0x3ffffff; h1 += c; @@ -243,73 +309,74 @@ poly1305_blocks(poly1305_t *ctx, st->h[2] = h2; st->h[3] = h3; st->h[4] = h4; -#endif /* !TORSION_HAVE_INT128 */ +#endif /* !POLY1305_HAVE_64BIT */ } void poly1305_update(poly1305_t *ctx, const unsigned char *data, size_t len) { - size_t i; + const unsigned char *raw = data; + size_t pos = ctx->pos; + size_t want = 16 - pos; - /* Handle leftover. */ - if (ctx->size > 0) { - size_t want = 16 - ctx->size; + if (len >= want) { + if (pos > 0) { + memcpy(ctx->block + pos, raw, want); - if (want > len) - want = len; + raw += want; + len -= want; + pos = 0; - for (i = 0; i < want; i++) - ctx->block[ctx->size + i] = data[i]; + poly1305_blocks(ctx, ctx->block, 16, 0); + } - len -= want; - data += want; + if (len >= 16) { + size_t aligned = len & -16; - ctx->size += want; + poly1305_blocks(ctx, raw, aligned, 0); - if (ctx->size < 16) - return; - - poly1305_blocks(ctx, ctx->block, 16, 0); - - ctx->size = 0; + raw += aligned; + len -= aligned; + } } - /* Process full blocks. */ - if (len >= 16) { - size_t want = len & ~15; + if (len > 0) { + memcpy(ctx->block + pos, raw, len); + pos += len; + } - poly1305_blocks(ctx, data, want, 0); + ctx->pos = pos; +} - data += want; - len -= want; - } +void +poly1305_pad(poly1305_t *ctx) { + if (ctx->pos > 0) { + while (ctx->pos < 16) + ctx->block[ctx->pos++] = 0; - /* Store leftover. */ - if (len > 0) { - for (i = 0; i < len; i++) - ctx->block[ctx->size + i] = data[i]; + poly1305_blocks(ctx, ctx->block, 16, 0); - ctx->size += len; + ctx->pos = 0; } } void poly1305_final(poly1305_t *ctx, unsigned char *mac) { -#if defined(TORSION_HAVE_INT128) +#if defined(POLY1305_HAVE_64BIT) struct poly1305_64_s *st = &ctx->state.u64; uint64_t h0, h1, h2, c; uint64_t g0, g1, g2; uint64_t t0, t1; /* Process the remaining block. */ - if (ctx->size > 0) { - size_t i = ctx->size; + if (ctx->pos > 0) { + ctx->block[ctx->pos++] = 1; - ctx->block[i++] = 1; - - for (; i < 16; i++) - ctx->block[i] = 0; + while (ctx->pos < 16) + ctx->block[ctx->pos++] = 0; poly1305_blocks(ctx, ctx->block, 16, 1); + + ctx->pos = 0; } /* Fully carry h. */ @@ -317,37 +384,37 @@ poly1305_final(poly1305_t *ctx, unsigned char *mac) { h1 = st->h[1]; h2 = st->h[2]; - c = (h1 >> 44); + c = h1 >> 44; h1 &= UINT64_C(0xfffffffffff); h2 += c; - c = (h2 >> 42); + c = h2 >> 42; h2 &= UINT64_C(0x3ffffffffff); h0 += c * 5; - c = (h0 >> 44); + c = h0 >> 44; h0 &= UINT64_C(0xfffffffffff); h1 += c; - c = (h1 >> 44); + c = h1 >> 44; h1 &= UINT64_C(0xfffffffffff); h2 += c; - c = (h2 >> 42); + c = h2 >> 42; h2 &= UINT64_C(0x3ffffffffff); h0 += c * 5; - c = (h0 >> 44); + c = h0 >> 44; h0 &= UINT64_C(0xfffffffffff); h1 += c; /* Compute h + -p. */ g0 = h0 + 5; - c = (g0 >> 44); + c = g0 >> 44; g0 &= UINT64_C(0xfffffffffff); g1 = h1 + c; - c = (g1 >> 44); + c = g1 >> 44; g1 &= UINT64_C(0xfffffffffff); g2 = h2 + c - (UINT64_C(1) << 42); @@ -366,23 +433,23 @@ poly1305_final(poly1305_t *ctx, unsigned char *mac) { t1 = st->pad[1]; h0 += (t0 & UINT64_C(0xfffffffffff)); - c = (h0 >> 44); + c = h0 >> 44; h0 &= UINT64_C(0xfffffffffff); h1 += (((t0 >> 44) | (t1 << 20)) & UINT64_C(0xfffffffffff)) + c; - c = (h1 >> 44); + c = h1 >> 44; h1 &= UINT64_C(0xfffffffffff); h2 += (((t1 >> 24)) & UINT64_C(0x3ffffffffff)) + c; h2 &= UINT64_C(0x3ffffffffff); /* mac = h % (2^128) */ - h0 = (h0 | (h1 << 44)); - h1 = ((h1 >> 20) | (h2 << 24)); + h0 |= (h1 << 44); + h1 = (h1 >> 20) | (h2 << 24); write64le(mac + 0, h0); write64le(mac + 8, h1); -#else /* !TORSION_HAVE_INT128 */ +#else /* !POLY1305_HAVE_64BIT */ struct poly1305_32_s *st = &ctx->state.u32; uint32_t h0, h1, h2, h3, h4, c; uint32_t g0, g1, g2, g3, g4; @@ -390,15 +457,15 @@ poly1305_final(poly1305_t *ctx, unsigned char *mac) { uint64_t f; /* Process the remaining block. */ - if (ctx->size > 0) { - size_t i = ctx->size; + if (ctx->pos > 0) { + ctx->block[ctx->pos++] = 1; - ctx->block[i++] = 1; - - for (; i < 16; i++) - ctx->block[i] = 0; + while (ctx->pos < 16) + ctx->block[ctx->pos++] = 0; poly1305_blocks(ctx, ctx->block, 16, 1); + + ctx->pos = 0; } /* Fully carry h. */ @@ -484,7 +551,7 @@ poly1305_final(poly1305_t *ctx, unsigned char *mac) { write32le(mac + 4, h1); write32le(mac + 8, h2); write32le(mac + 12, h3); -#endif /* !TORSION_HAVE_INT128 */ +#endif /* !POLY1305_HAVE_64BIT */ } /* @@ -497,17 +564,7 @@ poly1305_final(poly1305_t *ctx, unsigned char *mac) { * https://github.com/bitcoin/bitcoin/blob/master/src/crypto/siphash.cpp */ -#undef HAVE_UMULH - -#if defined(_MSC_VER) && _MSC_VER >= 1400 /* VS 2005 */ -# if defined(_M_AMD64) || defined(_M_X64) -# include -# pragma intrinsic(__umulh) -# define HAVE_UMULH -# endif -#endif - -#define ROTL64(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) +#define ROTL64(w, b) (((w) << (b)) | ((w) >> (64 - (b)))) #define SIPROUND do { \ v0 += v1; v1 = ROTL64(v1, 13); v1 ^= v0; \ @@ -520,27 +577,23 @@ poly1305_final(poly1305_t *ctx, unsigned char *mac) { uint64_t siphash_sum(const unsigned char *data, size_t len, const unsigned char *key) { - uint64_t c0 = UINT64_C(0x736f6d6570736575); - uint64_t c1 = UINT64_C(0x646f72616e646f6d); - uint64_t c2 = UINT64_C(0x6c7967656e657261); - uint64_t c3 = UINT64_C(0x7465646279746573); - uint64_t f0 = (uint64_t)len << 56; - uint64_t f1 = 0xff; uint64_t k0 = read64le(key + 0); uint64_t k1 = read64le(key + 8); - uint64_t v0 = k0 ^ c0; - uint64_t v1 = k1 ^ c1; - uint64_t v2 = k0 ^ c2; - uint64_t v3 = k1 ^ c3; - uint64_t word; + uint64_t v0 = k0 ^ UINT64_C(0x736f6d6570736575); + uint64_t v1 = k1 ^ UINT64_C(0x646f72616e646f6d); + uint64_t v2 = k0 ^ UINT64_C(0x6c7967656e657261); + uint64_t v3 = k1 ^ UINT64_C(0x7465646279746573); + uint64_t f0 = (uint64_t)len << 56; + uint64_t f1 = 0xff; + uint64_t w; while (len >= 8) { - word = read64le(data); + w = read64le(data); - v3 ^= word; + v3 ^= w; SIPROUND; SIPROUND; - v0 ^= word; + v0 ^= w; data += 8; len -= 8; @@ -609,18 +662,14 @@ siphash_mod(const unsigned char *data, uint64_t siphash128_sum(uint64_t num, const unsigned char *key) { - uint64_t c0 = UINT64_C(0x736f6d6570736575); - uint64_t c1 = UINT64_C(0x646f72616e646f6d); - uint64_t c2 = UINT64_C(0x6c7967656e657261); - uint64_t c3 = UINT64_C(0x7465646279746573); - uint64_t f0 = num; - uint64_t f1 = 0xff; uint64_t k0 = read64le(key + 0); uint64_t k1 = read64le(key + 8); - uint64_t v0 = k0 ^ c0; - uint64_t v1 = k1 ^ c1; - uint64_t v2 = k0 ^ c2; - uint64_t v3 = k1 ^ c3; + uint64_t v0 = k0 ^ UINT64_C(0x736f6d6570736575); + uint64_t v1 = k1 ^ UINT64_C(0x646f72616e646f6d); + uint64_t v2 = k0 ^ UINT64_C(0x6c7967656e657261); + uint64_t v3 = k1 ^ UINT64_C(0x7465646279746573); + uint64_t f0 = num; + uint64_t f1 = 0xff; v3 ^= f0; SIPROUND; @@ -640,16 +689,12 @@ siphash128_sum(uint64_t num, const unsigned char *key) { uint64_t siphash256_sum(uint64_t num, const unsigned char *key) { + uint64_t v0 = read64le(key + 0); + uint64_t v1 = read64le(key + 8); + uint64_t v2 = read64le(key + 16); + uint64_t v3 = read64le(key + 24); uint64_t f0 = num; uint64_t f1 = 0xff; - uint64_t k0 = read64le(key + 0); - uint64_t k1 = read64le(key + 8); - uint64_t k2 = read64le(key + 16); - uint64_t k3 = read64le(key + 24); - uint64_t v0 = k0; - uint64_t v1 = k1; - uint64_t v2 = k2; - uint64_t v3 = k3; v3 ^= f0; SIPROUND; @@ -667,6 +712,5 @@ siphash256_sum(uint64_t num, const unsigned char *key) { return v0; } -#undef HAVE_UMULH #undef ROTL64 #undef SIPROUND diff --git a/node_modules/bcrypto/deps/torsion/src/mpi.c b/node_modules/bcrypto/deps/torsion/src/mpi.c index 6dbbb2c0e..998d28291 100644 --- a/node_modules/bcrypto/deps/torsion/src/mpi.c +++ b/node_modules/bcrypto/deps/torsion/src/mpi.c @@ -86,6 +86,20 @@ typedef uint64_t mp_wide_t; TORSION_BARRIER(mp_limb_t, mp_limb) +/* + * Compat + */ + +#if TORSION_GNUC_PREREQ(3, 4) +# define MP_GNUC_3_4 +#endif + +#if defined(__has_builtin) +# define mp_has_builtin __has_builtin +#else +# define mp_has_builtin(x) 0 +#endif + /* * Macros */ @@ -94,7 +108,7 @@ TORSION_BARRIER(mp_limb_t, mp_limb) #define MP_MAX(x, y) ((x) > (y) ? (x) : (y)) #define MP_ABS(x) ((x) < 0 ? -(x) : (x)) -#if defined(__GNUC__) || TORSION_HAS_BUILTIN(__builtin_alloca) +#if defined(__GNUC__) || mp_has_builtin(__builtin_alloca) /* Available since at least gcc 1.41 (1992). */ /* Available since clang 3.0.0 (2011). */ # define mp_alloca __builtin_alloca @@ -177,42 +191,34 @@ TORSION_BARRIER(mp_limb_t, mp_limb) * Builtins */ -#if TORSION_GNUC_PREREQ(3, 4) -# define mp_has_builtin(x) 1 -#elif defined(__has_builtin) -# define mp_has_builtin __has_builtin -#else -# define mp_has_builtin(x) 0 -#endif - #if MP_LIMB_MAX == UINT_MAX -# if mp_has_builtin(__builtin_popcount) +# if defined(MP_GNUC_3_4) || mp_has_builtin(__builtin_popcount) # define mp_builtin_popcount __builtin_popcount # endif -# if mp_has_builtin(__builtin_clz) +# if defined(MP_GNUC_3_4) || mp_has_builtin(__builtin_clz) # define mp_builtin_clz __builtin_clz # endif -# if mp_has_builtin(__builtin_ctz) +# if defined(MP_GNUC_3_4) || mp_has_builtin(__builtin_ctz) # define mp_builtin_ctz __builtin_ctz # endif #elif MP_LIMB_MAX == ULONG_MAX -# if mp_has_builtin(__builtin_popcountl) +# if defined(MP_GNUC_3_4) || mp_has_builtin(__builtin_popcountl) # define mp_builtin_popcount __builtin_popcountl # endif -# if mp_has_builtin(__builtin_clzl) +# if defined(MP_GNUC_3_4) || mp_has_builtin(__builtin_clzl) # define mp_builtin_clz __builtin_clzl # endif -# if mp_has_builtin(__builtin_ctzl) +# if defined(MP_GNUC_3_4) || mp_has_builtin(__builtin_ctzl) # define mp_builtin_ctz __builtin_ctzl # endif #elif defined(ULLONG_MAX) && MP_LIMB_MAX == ULLONG_MAX -# if mp_has_builtin(__builtin_popcountll) +# if defined(MP_GNUC_3_4) || mp_has_builtin(__builtin_popcountll) # define mp_builtin_popcount __builtin_popcountll # endif -# if mp_has_builtin(__builtin_clzll) +# if defined(MP_GNUC_3_4) || mp_has_builtin(__builtin_clzll) # define mp_builtin_clz __builtin_clzll # endif -# if mp_has_builtin(__builtin_ctzll) +# if defined(MP_GNUC_3_4) || mp_has_builtin(__builtin_ctzll) # define mp_builtin_ctz __builtin_ctzll # endif #endif @@ -463,37 +469,36 @@ TORSION_BARRIER(mp_limb_t, mp_limb) : "cc", "rax" \ ) -/* [z, c] = 0 - x - c = -(x + c) */ +/* [z, c] = ~x + c */ #define mp_neg_1(z, c, x) \ __asm__ ( \ + "notq %q0\n" \ "addq %q1, %q0\n" \ "setc %b1\n" \ - "negq %q0\n" \ - "adcq $0, %q1\n" \ : "=&r" (z), "+&r" (c) \ : "0" (x) \ : "cc" \ ) -/* [z, c] = 0 - x - c = -(x + c) */ +/* [z, c] = ~x + c */ #define mp_neg_1x4(zp, c, xp) \ __asm__ __volatile__ ( \ "shrq %q0\n" \ "movq (%q2), %%r8\n" \ + "notq %%r8\n" \ "adcq $0, %%r8\n" \ - "negq %%r8\n" \ "movq %%r8, (%q1)\n" \ "movq 8(%q2), %%r8\n" \ + "notq %%r8\n" \ "adcq $0, %%r8\n" \ - "negq %%r8\n" \ "movq %%r8, 8(%q1)\n" \ "movq 16(%q2), %%r8\n" \ + "notq %%r8\n" \ "adcq $0, %%r8\n" \ - "negq %%r8\n" \ "movq %%r8, 16(%q1)\n" \ "movq 24(%q2), %%r8\n" \ + "notq %%r8\n" \ "adcq $0, %%r8\n" \ - "negq %%r8\n" \ "movq %%r8, 24(%q1)\n" \ "setb %b0\n" \ : "+&r" (c) \ @@ -567,10 +572,10 @@ TORSION_BARRIER(mp_limb_t, mp_limb) (z) = _w; \ } while (0) -/* [z, c] = 0 - x - c = -(x + c) */ +/* [z, c] = ~x + c */ #define mp_neg_1(z, c, x) do { \ - mp_wide_t _w = -(mp_wide_t)(x) - (c); \ - (c) = -(_w >> MP_LIMB_BITS); \ + mp_wide_t _w = ~(x) + (mp_wide_t)(c); \ + (c) = _w >> MP_LIMB_BITS; \ (z) = _w; \ } while (0) @@ -741,13 +746,10 @@ TORSION_BARRIER(mp_limb_t, mp_limb) (z) = _lo; \ } while (0) -/* [z, c] = 0 - x - c = -(x + c) */ +/* [z, c] = ~x + c */ #define mp_neg_1(z, c, x) do { \ - mp_limb_t _z = (x) + (c); \ - mp_limb_t _c = (_z < (c)); \ - _z = -_z; \ - _c += (_z > 0); \ - (c) = _c; \ + mp_limb_t _z = ~(x) + (c); \ + (c) = (_z < (c)); \ (z) = _z; \ } while (0) @@ -821,13 +823,13 @@ typedef struct mp_divisor_s { * Allocation */ -mp_limb_t * +static mp_limb_t * mp_alloc_limbs(mp_size_t size) { mp_limb_t *ptr; CHECK(size > 0); - ptr = malloc(size * sizeof(mp_limb_t)); + ptr = (mp_limb_t *)malloc(size * sizeof(mp_limb_t)); if (ptr == NULL) torsion_abort(); /* LCOV_EXCL_LINE */ @@ -835,11 +837,11 @@ mp_alloc_limbs(mp_size_t size) { return ptr; } -mp_limb_t * +static mp_limb_t * mp_realloc_limbs(mp_limb_t *ptr, mp_size_t size) { CHECK(size > 0); - ptr = realloc(ptr, size * sizeof(mp_limb_t)); + ptr = (mp_limb_t *)realloc(ptr, size * sizeof(mp_limb_t)); if (ptr == NULL) torsion_abort(); /* LCOV_EXCL_LINE */ @@ -847,7 +849,7 @@ mp_realloc_limbs(mp_limb_t *ptr, mp_size_t size) { return ptr; } -void +static void mp_free_limbs(mp_limb_t *ptr) { free(ptr); } @@ -858,7 +860,7 @@ mp_alloc_str(size_t size) { CHECK(size != 0); - ptr = malloc(size); + ptr = (char *)malloc(size); if (ptr == NULL) torsion_abort(); /* LCOV_EXCL_LINE */ @@ -917,7 +919,7 @@ mp_clz(mp_limb_t x) { : "cc" ); - return 63 - z; + return (MP_LIMB_BITS - 1) - z; #elif defined(mp_builtin_clz) if (x == 0) return MP_LIMB_BITS; @@ -1046,7 +1048,7 @@ mp_long_cast(mp_limb_t x, mp_size_t sign) { if (UNLIKELY(x == MP_LIMB_HI)) return MP_LONG_MIN; - return -((mp_long_t)(x & (MP_LIMB_HI - 1))); + return -(mp_long_t)(x & (MP_LIMB_HI - 1)); } return x & (MP_LIMB_HI - 1); @@ -1095,42 +1097,87 @@ mp_str_limbs(const char *str, int base) { return (len + limb_len - 1) / limb_len; } -static mp_limb_t * -mp_eratosthenes(mp_limb_t n) { - /* Sieve of Eratosthenes. */ - mp_limb_t sn, i, p; - mp_limb_t *sp; - mp_bits_t lo; - - CHECK(n < MP_LOW_MASK * MP_LOW_MASK); - CHECK(n <= MP_LIMB_MAX - MP_LIMB_BITS); - CHECK(n <= MP_BITS_MAX); - - sn = (n + 1 + MP_LIMB_BITS - 1) / MP_LIMB_BITS; - - CHECK(sn <= MP_SIZE_MAX); - - sp = mp_alloc_limbs(sn); - - for (i = 0; i < sn; i++) - sp[i] = MP_LIMB_MAX; +static TORSION_INLINE mp_limb_t +mp_import_le(const unsigned char *xp) { +#if MP_LIMB_BITS == 64 + return ((mp_limb_t)xp[7] << 56) + | ((mp_limb_t)xp[6] << 48) + | ((mp_limb_t)xp[5] << 40) + | ((mp_limb_t)xp[4] << 32) + | ((mp_limb_t)xp[3] << 24) + | ((mp_limb_t)xp[2] << 16) + | ((mp_limb_t)xp[1] << 8) + | ((mp_limb_t)xp[0] << 0); +#else + return ((mp_limb_t)xp[3] << 24) + | ((mp_limb_t)xp[2] << 16) + | ((mp_limb_t)xp[1] << 8) + | ((mp_limb_t)xp[0] << 0); +#endif +} - for (p = 2; p * p <= n; p++) { - if (mpn_tstbit(sp, p)) { - for (i = p * p; i <= n; i += p) - mpn_clrbit(sp, i); - } - } +static TORSION_INLINE mp_limb_t +mp_import_be(const unsigned char *xp) { +#if MP_LIMB_BITS == 64 + return ((mp_limb_t)xp[0] << 56) + | ((mp_limb_t)xp[1] << 48) + | ((mp_limb_t)xp[2] << 40) + | ((mp_limb_t)xp[3] << 32) + | ((mp_limb_t)xp[4] << 24) + | ((mp_limb_t)xp[5] << 16) + | ((mp_limb_t)xp[6] << 8) + | ((mp_limb_t)xp[7] << 0); +#else + return ((mp_limb_t)xp[0] << 24) + | ((mp_limb_t)xp[1] << 16) + | ((mp_limb_t)xp[2] << 8) + | ((mp_limb_t)xp[3] << 0); +#endif +} - sp[0] &= ~MP_LIMB_C(3); +static TORSION_INLINE void +mp_export_le(unsigned char *zp, mp_limb_t x) { +#if MP_LIMB_BITS == 64 + zp[0] = (x >> 0) & 0xff; + zp[1] = (x >> 8) & 0xff; + zp[2] = (x >> 16) & 0xff; + zp[3] = (x >> 24) & 0xff; + zp[4] = (x >> 32) & 0xff; + zp[5] = (x >> 40) & 0xff; + zp[6] = (x >> 48) & 0xff; + zp[7] = (x >> 56) & 0xff; +#else + zp[0] = (x >> 0) & 0xff; + zp[1] = (x >> 8) & 0xff; + zp[2] = (x >> 16) & 0xff; + zp[3] = (x >> 24) & 0xff; +#endif +} - lo = (n + 1) % MP_LIMB_BITS; +static TORSION_INLINE void +mp_export_be(unsigned char *zp, mp_limb_t x) { +#if MP_LIMB_BITS == 64 + zp[7] = (x >> 0) & 0xff; + zp[6] = (x >> 8) & 0xff; + zp[5] = (x >> 16) & 0xff; + zp[4] = (x >> 24) & 0xff; + zp[3] = (x >> 32) & 0xff; + zp[2] = (x >> 40) & 0xff; + zp[1] = (x >> 48) & 0xff; + zp[0] = (x >> 56) & 0xff; +#else + zp[3] = (x >> 0) & 0xff; + zp[2] = (x >> 8) & 0xff; + zp[1] = (x >> 16) & 0xff; + zp[0] = (x >> 24) & 0xff; +#endif +} - if (lo != 0) - sp[sn - 1] &= MP_MASK(lo); +/* + * Globals + */ - return sp; -} +const int mp_bits_per_limb = MP_LIMB_BITS; /* * MPN Interface @@ -1152,12 +1199,27 @@ mpn_zero(mp_limb_t *zp, mp_size_t zn) { * Uninitialization */ +#ifdef __cplusplus +extern "C" +#endif void -torsion_cleanse(void *, size_t); +torsion_memzero(void *, size_t); void mpn_cleanse(mp_limb_t *zp, mp_size_t zn) { - torsion_cleanse(zp, zn * sizeof(mp_limb_t)); + torsion_memzero(zp, zn * sizeof(mp_limb_t)); +} + +/* + * Internal + */ + +static TORSION_INLINE mp_size_t +mpn_strip(const mp_limb_t *xp, mp_size_t xn) { + while (xn > 0 && xp[xn - 1] == 0) + xn -= 1; + + return xn; } /* @@ -1247,57 +1309,22 @@ mpn_cmp_1(const mp_limb_t *xp, mp_size_t xn, mp_limb_t y) { mp_limb_t mpn_add_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y) { - mp_limb_t c; - - if (xn == 0) - return y; - - mp_add(*zp, c, *xp, y); zp++; xp++; xn--; - - switch (xn & 3) { - case 3: - mp_add(*zp, c, *xp, c); zp++; xp++; - case 2: - mp_add(*zp, c, *xp, c); zp++; xp++; - case 1: - mp_add(*zp, c, *xp, c); zp++; xp++; - } - - xn >>= 2; - - while (xn--) { - /* [z, c] = x + c */ -#if defined(mp_add_x4) - mp_add_x4(zp, c, xp); -#else - mp_add(zp[0], c, xp[0], c); - mp_add(zp[1], c, xp[1], c); - mp_add(zp[2], c, xp[2], c); - mp_add(zp[3], c, xp[3], c); -#endif - - zp += 4; - xp += 4; - } - - return c; -} - -static mp_limb_t -mpn_add_var_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y) { mp_limb_t c = y; - mp_limb_t z; + mp_limb_t x, z; mp_size_t i; for (i = 0; i < xn && c != 0; i++) { /* [z, c] = x + c */ - z = xp[i] + c; + x = xp[i]; + z = x + c; c = (z < c); zp[i] = z; } - if (zp != xp && i < xn) - mpn_copyi(zp + i, xp + i, xn - i); + if (zp != xp) { + for (; i < xn; i++) + zp[i] = xp[i]; + } return c; } @@ -1353,54 +1380,39 @@ mpn_add(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, return c; } -static mp_limb_t -mpn_add_var(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, - const mp_limb_t *yp, mp_size_t yn) { - mp_limb_t c; - - CHECK(xn >= yn); - - c = mpn_add_n(zp, xp, yp, yn); - - if (xn > yn) - c = mpn_add_var_1(zp + yn, xp + yn, xn - yn, c); - - return c; -} - /* - * Subtraction + * Secure Addition */ mp_limb_t -mpn_sub_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y) { +mpn_sec_add_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y) { mp_limb_t c; - if (xn == 0) + if (UNLIKELY(xn == 0)) return y; - mp_sub(*zp, c, *xp, y); zp++; xp++; xn--; + mp_add(*zp, c, *xp, y); zp++; xp++; xn--; switch (xn & 3) { case 3: - mp_sub(*zp, c, *xp, c); zp++; xp++; + mp_add(*zp, c, *xp, c); zp++; xp++; case 2: - mp_sub(*zp, c, *xp, c); zp++; xp++; + mp_add(*zp, c, *xp, c); zp++; xp++; case 1: - mp_sub(*zp, c, *xp, c); zp++; xp++; + mp_add(*zp, c, *xp, c); zp++; xp++; } xn >>= 2; while (xn--) { - /* [z, c] = x - c */ -#if defined(mp_sub_x4) - mp_sub_x4(zp, c, xp); + /* [z, c] = x + c */ +#if defined(mp_add_x4) + mp_add_x4(zp, c, xp); #else - mp_sub(zp[0], c, xp[0], c); - mp_sub(zp[1], c, xp[1], c); - mp_sub(zp[2], c, xp[2], c); - mp_sub(zp[3], c, xp[3], c); + mp_add(zp[0], c, xp[0], c); + mp_add(zp[1], c, xp[1], c); + mp_add(zp[2], c, xp[2], c); + mp_add(zp[3], c, xp[3], c); #endif zp += 4; @@ -1410,21 +1422,43 @@ mpn_sub_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y) { return c; } -static mp_limb_t -mpn_sub_var_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y) { +mp_limb_t +mpn_sec_add(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, + const mp_limb_t *yp, mp_size_t yn) { + mp_limb_t c; + + CHECK(xn >= yn); + + c = mpn_add_n(zp, xp, yp, yn); + + if (xn > yn) + c = mpn_sec_add_1(zp + yn, xp + yn, xn - yn, c); + + return c; +} + +/* + * Subtraction + */ + +mp_limb_t +mpn_sub_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y) { mp_limb_t c = y; - mp_limb_t z; + mp_limb_t x, z; mp_size_t i; for (i = 0; i < xn && c != 0; i++) { /* [z, c] = x - c */ - z = xp[i] - c; - c = (z > xp[i]); + x = xp[i]; + z = x - c; + c = (z > x); zp[i] = z; } - if (zp != xp && i < xn) - mpn_copyi(zp + i, xp + i, xn - i); + if (zp != xp) { + for (; i < xn; i++) + zp[i] = xp[i]; + } return c; } @@ -1480,21 +1514,6 @@ mpn_sub(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, return c; } -static mp_limb_t -mpn_sub_var(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, - const mp_limb_t *yp, mp_size_t yn) { - mp_limb_t c; - - CHECK(xn >= yn); - - c = mpn_sub_n(zp, xp, yp, yn); - - if (xn > yn) - c = mpn_sub_var_1(zp + yn, xp + yn, xn - yn, c); - - return c; -} - static void mpn_sub_mod(mp_limb_t *zp, const mp_limb_t *xp, const mp_limb_t *yp, @@ -1510,6 +1529,63 @@ mpn_sub_mod(mp_limb_t *zp, const mp_limb_t *xp, } } +/* + * Secure Subtraction + */ + +mp_limb_t +mpn_sec_sub_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y) { + mp_limb_t c; + + if (UNLIKELY(xn == 0)) + return y; + + mp_sub(*zp, c, *xp, y); zp++; xp++; xn--; + + switch (xn & 3) { + case 3: + mp_sub(*zp, c, *xp, c); zp++; xp++; + case 2: + mp_sub(*zp, c, *xp, c); zp++; xp++; + case 1: + mp_sub(*zp, c, *xp, c); zp++; xp++; + } + + xn >>= 2; + + while (xn--) { + /* [z, c] = x - c */ +#if defined(mp_sub_x4) + mp_sub_x4(zp, c, xp); +#else + mp_sub(zp[0], c, xp[0], c); + mp_sub(zp[1], c, xp[1], c); + mp_sub(zp[2], c, xp[2], c); + mp_sub(zp[3], c, xp[3], c); +#endif + + zp += 4; + xp += 4; + } + + return c; +} + +mp_limb_t +mpn_sec_sub(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, + const mp_limb_t *yp, mp_size_t yn) { + mp_limb_t c; + + CHECK(xn >= yn); + + c = mpn_sub_n(zp, xp, yp, yn); + + if (xn > yn) + c = mpn_sec_sub_1(zp + yn, xp + yn, xn - yn, c); + + return c; +} + /* * Multiplication */ @@ -1613,7 +1689,7 @@ mpn_mul(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, const mp_limb_t *yp, mp_size_t yn) { mp_size_t i; - if (yn == 0) { + if (UNLIKELY(yn == 0)) { mpn_zero(zp, xn); return; } @@ -1630,7 +1706,7 @@ mpn_sqr(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t *scratch) { mp_limb_t *tp = scratch; mp_size_t i; - if (xn == 0) + if (UNLIKELY(xn == 0)) return; mp_sqr(zp[1], zp[0], xp[0]); @@ -1678,16 +1754,15 @@ mpn_mulshift(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t zn = tn - s; mp_limb_t b; - /* Ensure L <= bits <= 2 * L. */ - ASSERT(s >= n && s <= n * 2); - ASSERT(zn >= 0 && zn <= n); - ASSERT(zn != 0); + /* Ensure L <= bits < 2 * L. */ + ASSERT(s >= n && s < n * 2); + ASSERT(zn > 0 && zn <= n); /* t = x * y */ mpn_mul_n(tp, xp, yp, n); /* b = (t >> (bits - 1)) & 1 */ - b = mpn_getbit(tp, tn, bits - 1); + b = mpn_tstbit(tp, bits - 1); /* z = t >> bits */ if (r != 0) @@ -1698,226 +1773,11 @@ mpn_mulshift(mp_limb_t *zp, const mp_limb_t *xp, mpn_zero(zp + zn, n - zn); /* z += b */ - return mpn_add_1(zp, zp, n, b); + return mpn_sec_add_1(zp, zp, n, b); } /* - * Weak Reduction - */ - -int -mpn_reduce_weak(mp_limb_t *zp, const mp_limb_t *xp, - const mp_limb_t *np, - mp_size_t n, - mp_limb_t hi, - mp_limb_t *scratch) { - /* `n` limbs are required for scratch. */ - mp_limb_t *tp = scratch; - mp_limb_t c = mpn_sub_n(tp, xp, np, n); - - mp_sub(hi, c, hi, c); - - mpn_select(zp, xp, tp, n, c == 0); - - return c == 0; -} - -/* - * Barrett Reduction - */ - -void -mpn_barrett(mp_limb_t *mp, const mp_limb_t *np, - mp_size_t n, - mp_size_t shift, - mp_limb_t *scratch) { - /* Barrett precomputation. - * - * [HANDBOOK] Page 603, Section 14.3.3. - * - * `shift + 1` limbs are required for scratch. - * - * Must have `shift - n + 1` limbs at mp. - */ - mp_limb_t *xp = scratch; - mp_size_t xn = shift + 1; - - CHECK(n > 0); - CHECK(shift >= n * 2); - - /* m = 2^(shift * L) / n */ - mpn_zero(xp, shift); - - xp[shift] = 1; - - mpn_div(xp, xp, xn, np, n); - - CHECK(mpn_strip(xp, xn - n + 1) == shift - n + 1); - - mpn_copyi(mp, xp, shift - n + 1); -} - -void -mpn_reduce(mp_limb_t *zp, const mp_limb_t *xp, - const mp_limb_t *mp, - const mp_limb_t *np, - mp_size_t n, - mp_size_t shift, - mp_limb_t *scratch) { - /* Barrett reduction. - * - * [HANDBOOK] Algorithm 14.42, Page 604, Section 14.3.3. - * - * `1 + shift + mn` limbs are required for scratch. - * - * In other words: `2 * (shift + 1) - n` limbs. - */ - mp_size_t mn = shift - n + 1; - mp_limb_t *qp = scratch; - mp_limb_t *hp = scratch + 1; - - /* h = x * m */ - mpn_mul(hp, xp, shift, mp, mn); - - /* h = h >> (shift * L) */ - hp += shift; - - /* q = x - h * n */ - mpn_mul(qp, hp, mn, np, n); - mpn_sub_n(qp, xp, qp, shift); - - /* q = q - n if q >= n */ - mpn_reduce_weak(zp, qp, np, n, qp[n], hp); - -#ifdef TORSION_VERIFY - ASSERT(mpn_cmp(zp, np, n) < 0); -#endif -} - -/* - * Montgomery Multiplication (logic from golang) - */ - -void -mpn_mont(mp_limb_t *kp, - mp_limb_t *rp, - const mp_limb_t *mp, - mp_size_t n, - mp_limb_t *scratch) { - /* Montgomery precomputation. - * - * [HANDBOOK] Page 600, Section 14.3.2. - * - * `2 * n + 1` limbs are required for scratch. - */ - mp_limb_t *xp = scratch; - mp_size_t xn = n * 2 + 1; - mp_limb_t k, t; - mp_size_t i; - - CHECK(n > 0); - - /* k = -m^-1 mod 2^L */ - k = 2 - mp[0]; - t = mp[0] - 1; - - for (i = 1; i < MP_LIMB_BITS; i <<= 1) { - t *= t; - k *= (t + 1); - } - - kp[0] = -k; - - /* r = 2^(2 * n * L) mod m */ - mpn_zero(xp, n * 2); - - xp[n * 2] = 1; - - mpn_mod(rp, xp, xn, mp, n); -} - -static TORSION_INLINE mp_limb_t -mpn_montmul_inner(const mp_limb_t *xp, - const mp_limb_t *yp, - const mp_limb_t *mp, - mp_size_t n, - mp_limb_t k, - mp_limb_t *scratch) { - /* Montgomery multiplication. - * - * [MONT] Algorithm 4 & 5, Page 5, Section 3. - * - * `2 * n` limbs are required for scratch. - */ - mp_limb_t *tp = scratch; - mp_limb_t c1, c2, c3, cx, cy; - mp_size_t i; - - ASSERT(n > 0); - - c2 = mpn_mul_1(tp, xp, n, yp[0]); - c3 = mpn_addmul_1(tp, mp, n, tp[0] * k); - - mp_add(tp[n], c1, c2, c3); - - for (i = 1; i < n; i++) { - c2 = mpn_addmul_1(tp + i, xp, n, yp[i]); - c3 = mpn_addmul_1(tp + i, mp, n, tp[i] * k); - - mp_add(cx, c2, c1, c2); - mp_add(cy, c3, cx, c3); - - c1 = c2 | c3; - - tp[n + i] = cy; - } - - return c1; -} - -void -mpn_montmul(mp_limb_t *zp, const mp_limb_t *xp, - const mp_limb_t *yp, - const mp_limb_t *mp, - mp_size_t n, - mp_limb_t k, - mp_limb_t *scratch) { - /* Word-by-Word Montgomery Multiplication. - * - * [MONT] Algorithm 4, Page 5, Section 3. - */ - mp_limb_t *tp = scratch; - mp_limb_t c = mpn_montmul_inner(xp, yp, mp, n, k, tp); - - mpn_reduce_weak(zp, tp + n, mp, n, c, tp); - -#ifdef TORSION_VERIFY - ASSERT(mpn_cmp(zp, mp, n) < 0); -#endif -} - -void -mpn_montmul_var(mp_limb_t *zp, const mp_limb_t *xp, - const mp_limb_t *yp, - const mp_limb_t *mp, - mp_size_t n, - mp_limb_t k, - mp_limb_t *scratch) { - /* Word-by-Word Almost Montgomery Multiplication. - * - * [MONT] Algorithm 4, Page 5, Section 3. - */ - mp_limb_t *tp = scratch; - mp_limb_t c = mpn_montmul_inner(xp, yp, mp, n, k, tp); - - if (c != 0) - mpn_sub_n(zp, tp + n, mp, n); - else - mpn_copyi(zp, tp + n, n); -} - -/* - * Division Helpers + * Division Helpers */ static void MP_MSVC_CDECL @@ -2282,7 +2142,7 @@ mp_div_2by1(mp_limb_t *q, mp_limb_t *r, r0 = u0 - q1 * d; - if (r0 > q0) { + if (UNPREDICTABLE(r0 > q0)) { q1 -= 1; r0 += d; } @@ -2297,7 +2157,7 @@ mp_div_2by1(mp_limb_t *q, mp_limb_t *r, #endif /* !MP_HAVE_ASM_X64 */ } -TORSION_UNUSED static TORSION_INLINE mp_limb_t +TORSION_UNUSED static mp_limb_t mp_inv_3by2(mp_limb_t d1, mp_limb_t d0) { /* [DIV] Algorithm 6, Page 6, Section A. * @@ -2534,7 +2394,7 @@ mp_div_3by2(mp_limb_t *q, mp_limb_t *k1, mp_limb_t *k0, */ q1 += 1; - if (r1 >= q0) { + if (UNPREDICTABLE(r1 >= q0)) { q1 -= 1; r0 += d0; r1 += d1 + (r0 < d0); @@ -2553,7 +2413,7 @@ mp_div_3by2(mp_limb_t *q, mp_limb_t *k1, mp_limb_t *k0, #endif /* !MP_HAVE_ASM_X64 */ } -TORSION_UNUSED static mp_limb_t +static mp_limb_t mp_inv_mod(mp_limb_t d) { /* Compute d^-1 mod B. * @@ -3125,7 +2985,7 @@ mpn_divmod_1(mp_limb_t *qp, const mp_limb_t *np, mp_size_t nn, mp_limb_t d) { mp_divisor_t den; mp_limb_t q, r; - if (nn < 0 || d == 0) + if (d == 0) torsion_abort(); /* LCOV_EXCL_LINE */ if (nn == 0) @@ -3208,65 +3068,6 @@ mpn_divexact(mp_limb_t *qp, const mp_limb_t *np, mp_size_t nn, mp_free_vla(rp, dn); } -/* - * Round Division - */ - -void -mpn_divround_1(mp_limb_t *qp, const mp_limb_t *np, mp_size_t nn, mp_limb_t d) { - /* Requires nn + 1 limbs at qp. */ - mp_limb_t r = mpn_divmod_1(qp, np, nn, d); - mp_limb_t h = d >> 1; - - if (r > h || (r == h && (d & 1) == 0)) - qp[nn] = mpn_add_var_1(qp, qp, nn, 1); - else - qp[nn] = 0; -} - -void -mpn_divround(mp_limb_t *qp, const mp_limb_t *np, mp_size_t nn, - const mp_limb_t *dp, mp_size_t dn) { - /* Requires nn - dn + 2 limbs at qp. */ - /* Requires nn >= dn - 1. */ - mp_limb_t *rp, *hp; - mp_size_t qn; - int odd, cmp; - - if (dn == 1) { - mpn_divround_1(qp, np, nn, dp[0]); - return; - } - - if (dn == 0 || dp[dn - 1] == 0 || nn < dn - 1) - torsion_abort(); /* LCOV_EXCL_LINE */ - - rp = mp_alloc_vla(dn); - hp = mp_alloc_vla(dn); - - mpn_rshift(hp, dp, dn, 1); - - odd = dp[0] & 1; - - if (nn < dn) { - mpn_copyi(rp, np, nn); - rp[nn] = 0; - } else { - mpn_divmod(qp, rp, np, nn, dp, dn); - } - - cmp = mpn_cmp(rp, hp, dn); - qn = nn - dn + 1; - - if (cmp > 0 || (cmp == 0 && odd == 0)) - qp[qn] = mpn_add_var_1(qp, qp, qn, 1); - else - qp[qn] = 0; - - mp_free_vla(rp, dn); - mp_free_vla(hp, dn); -} - /* * AND */ @@ -3370,7 +3171,7 @@ mpn_nior_n(mp_limb_t *zp, const mp_limb_t *xp, */ void -mpn_nxor_n(mp_limb_t *zp, const mp_limb_t *xp, +mpn_xnor_n(mp_limb_t *zp, const mp_limb_t *xp, const mp_limb_t *yp, mp_size_t n) { mp_size_t i; @@ -3452,8 +3253,8 @@ mpn_getbit(const mp_limb_t *xp, mp_size_t xn, mp_bits_t pos) { mp_limb_t mpn_getbits(const mp_limb_t *xp, mp_size_t xn, mp_bits_t pos, mp_bits_t width) { mp_size_t index = pos / MP_LIMB_BITS; - mp_limb_t bits, next; mp_bits_t shift, more; + mp_limb_t bits, next; ASSERT(width < MP_LIMB_BITS); @@ -3595,7 +3396,7 @@ mpn_mask(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_bits_t bits) { mp_limb_t mpn_neg(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn) { - mp_limb_t c = 0; + mp_limb_t c = 1; switch (xn & 3) { case 3: @@ -3609,7 +3410,7 @@ mpn_neg(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn) { xn >>= 2; while (xn--) { - /* [z, c] = 0 - x - c = -(x + c) */ + /* [z, c] = ~x + c */ #if defined(mp_neg_1x4) mp_neg_1x4(zp, c, xp); #else @@ -3623,31 +3424,236 @@ mpn_neg(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn) { xp += 4; } - return c; + return c ^ 1; } /* - * Number Theoretic Functions + * Weak Reduction */ -mp_size_t -mpn_gcd(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, - const mp_limb_t *yp, mp_size_t yn, - mp_limb_t *scratch) { - /* Binary GCD algorithm. - * - * [KNUTH] Algorithm B, Page 338, Section 4.5.2. - */ - mp_limb_t *up = &scratch[0]; - mp_limb_t *vp = &scratch[xn]; - mp_size_t un = xn; - mp_size_t vn = yn; - mp_bits_t r, bits; - mp_bits_t s = 0; - mp_size_t zn; - mp_limb_t c; - - if (xn == 0 || xp[xn - 1] == 0) +int +mpn_reduce_weak(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *np, + mp_size_t n, + mp_limb_t hi, + mp_limb_t *scratch) { + /* `n` limbs are required for scratch. */ + mp_limb_t *tp = scratch; + mp_limb_t c = mpn_sub_n(tp, xp, np, n); + + c = (hi < c); /* [, c] = hi - c */ + + mpn_cnd_select(zp, xp, tp, n, c == 0); + + return c == 0; +} + +/* + * Barrett Reduction + */ + +void +mpn_barrett(mp_limb_t *mp, const mp_limb_t *np, + mp_size_t n, + mp_size_t shift, + mp_limb_t *scratch) { + /* Barrett precomputation. + * + * [HANDBOOK] Page 603, Section 14.3.3. + * + * `shift + 1` limbs are required for scratch. + * + * Must have `shift - n + 1` limbs at mp. + */ + mp_limb_t *xp = scratch; + mp_size_t xn = shift + 1; + + CHECK(n > 0); + CHECK(shift >= n * 2); + + /* m = 2^(shift * L) / n */ + mpn_zero(xp, shift); + + xp[shift] = 1; + + mpn_div(xp, xp, xn, np, n); + + CHECK(mpn_strip(xp, xn - n + 1) == shift - n + 1); + + mpn_copyi(mp, xp, shift - n + 1); +} + +void +mpn_reduce(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *mp, + const mp_limb_t *np, + mp_size_t n, + mp_size_t shift, + mp_limb_t *scratch) { + /* Barrett reduction. + * + * [HANDBOOK] Algorithm 14.42, Page 604, Section 14.3.3. + * + * `1 + shift + mn` limbs are required for scratch. + * + * In other words: `2 * (shift + 1) - n` limbs. + */ + mp_size_t mn = shift - n + 1; + mp_limb_t *qp = scratch; + mp_limb_t *hp = scratch + 1; + + /* h = x * m */ + mpn_mul(hp, xp, shift, mp, mn); + + /* h = h >> (shift * L) */ + hp += shift; + + /* q = x - h * n */ + mpn_mul(qp, hp, mn, np, n); + mpn_sub_n(qp, xp, qp, shift); + + /* q = q - n if q >= n */ + mpn_reduce_weak(zp, qp, np, n, qp[n], hp); + +#ifdef TORSION_VERIFY + ASSERT(mpn_cmp(zp, np, n) < 0); +#endif +} + +/* + * Montgomery Multiplication (logic from golang) + */ + +void +mpn_mont(mp_limb_t *kp, + mp_limb_t *rp, + const mp_limb_t *mp, + mp_size_t n, + mp_limb_t *scratch) { + /* Montgomery precomputation. + * + * [HANDBOOK] Page 600, Section 14.3.2. + * + * `2 * n + 1` limbs are required for scratch. + */ + mp_limb_t *xp = scratch; + mp_size_t xn = n * 2 + 1; + + CHECK(n > 0); + + /* k = -m^-1 mod 2^L */ + kp[0] = -mp_inv_mod(mp[0]); + + /* r = 2^(2 * n * L) mod m */ + mpn_zero(xp, n * 2); + + xp[n * 2] = 1; + + mpn_mod(rp, xp, xn, mp, n); +} + +static TORSION_INLINE mp_limb_t +mpn_montmul_inner(const mp_limb_t *xp, + const mp_limb_t *yp, + const mp_limb_t *mp, + mp_size_t n, + mp_limb_t k, + mp_limb_t *scratch) { + /* Montgomery multiplication. + * + * [MONT] Algorithm 4 & 5, Page 5, Section 3. + * + * `2 * n` limbs are required for scratch. + */ + mp_limb_t *tp = scratch; + mp_limb_t c1, c2, c3, cx, cy; + mp_size_t i; + + ASSERT(n > 0); + + c2 = mpn_mul_1(tp, xp, n, yp[0]); + c3 = mpn_addmul_1(tp, mp, n, tp[0] * k); + + mp_add(tp[n], c1, c2, c3); + + for (i = 1; i < n; i++) { + c2 = mpn_addmul_1(tp + i, xp, n, yp[i]); + c3 = mpn_addmul_1(tp + i, mp, n, tp[i] * k); + + mp_add(cx, c2, c1, c2); + mp_add(cy, c3, cx, c3); + + c1 = c2 | c3; + + tp[n + i] = cy; + } + + return c1; +} + +void +mpn_montmul(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *yp, + const mp_limb_t *mp, + mp_size_t n, + mp_limb_t k, + mp_limb_t *scratch) { + /* Word-by-Word Almost Montgomery Multiplication. + * + * [MONT] Algorithm 4, Page 5, Section 3. + */ + mp_limb_t *tp = scratch; + mp_limb_t c = mpn_montmul_inner(xp, yp, mp, n, k, tp); + + if (c != 0) + mpn_sub_n(zp, tp + n, mp, n); + else + mpn_copyi(zp, tp + n, n); +} + +void +mpn_sec_montmul(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *yp, + const mp_limb_t *mp, + mp_size_t n, + mp_limb_t k, + mp_limb_t *scratch) { + /* Word-by-Word Montgomery Multiplication. + * + * [MONT] Algorithm 4, Page 5, Section 3. + */ + mp_limb_t *tp = scratch; + mp_limb_t c = mpn_montmul_inner(xp, yp, mp, n, k, tp); + + mpn_reduce_weak(zp, tp + n, mp, n, c, tp); + +#ifdef TORSION_VERIFY + ASSERT(mpn_cmp(zp, mp, n) < 0); +#endif +} + +/* + * Number Theoretic Functions + */ + +mp_size_t +mpn_gcd(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, + const mp_limb_t *yp, mp_size_t yn, + mp_limb_t *scratch) { + /* Binary GCD algorithm. + * + * [KNUTH] Algorithm B, Page 338, Section 4.5.2. + */ + mp_limb_t *up = &scratch[0]; + mp_limb_t *vp = &scratch[xn]; + mp_size_t un = xn; + mp_size_t vn = yn; + mp_bits_t r, bits; + mp_bits_t s = 0; + mp_size_t zn; + mp_limb_t c; + + if (xn == 0 || xp[xn - 1] == 0) torsion_abort(); /* LCOV_EXCL_LINE */ if (yn == 0 || yp[yn - 1] == 0) @@ -3682,10 +3688,10 @@ mpn_gcd(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, MPN_SHIFT_ZEROES(bits, vp, vn); if (mpn_cmp2(up, un, vp, vn) >= 0) { - mpn_sub_var(up, up, un, vp, vn); + mpn_sub(up, up, un, vp, vn); un = mpn_strip(up, un); } else { - mpn_sub_var(vp, vp, vn, up, un); + mpn_sub(vp, vp, vn, up, un); vn = mpn_strip(vp, vn); } } @@ -3740,7 +3746,7 @@ mpn_gcd_1(const mp_limb_t *xp, mp_size_t xn, mp_limb_t y, mp_limb_t *scratch) { v >>= mp_ctz(v); if (un > 1 || up[0] >= v) { - mpn_sub_var_1(up, up, un, v); + mpn_sub_1(up, up, un, v); un -= (up[un - 1] == 0); } else { v -= up[0]; @@ -3758,12 +3764,12 @@ mpn_invert(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, * * [KNUTH] Exercise 4.5.2.39, Page 646. */ - mp_limb_t *ap = &scratch[0 * (yn + 1)]; - mp_limb_t *bp = &scratch[1 * (yn + 1)]; - mp_limb_t *up = &scratch[2 * (yn + 1)]; - mp_limb_t *vp = &scratch[3 * (yn + 1)]; - mp_size_t an, bn; - mp_bits_t az, bz; + mp_limb_t *up = &scratch[0 * (yn + 1)]; + mp_limb_t *vp = &scratch[1 * (yn + 1)]; + mp_limb_t *ap = &scratch[2 * (yn + 1)]; + mp_limb_t *bp = &scratch[3 * (yn + 1)]; + mp_size_t un, vn; + mp_bits_t uz, vz; if (xn > 0 && xp[xn - 1] == 0) torsion_abort(); /* LCOV_EXCL_LINE */ @@ -3779,52 +3785,52 @@ mpn_invert(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, return 0; } - mpn_copyi(ap, xp, xn); - mpn_copyi(bp, yp, yn); + mpn_copyi(up, xp, xn); + mpn_copyi(vp, yp, yn); - mpn_set_1(up, yn + 1, 1); - mpn_set_1(vp, yn + 1, 0); + mpn_set_1(ap, yn + 1, 1); + mpn_set_1(bp, yn + 1, 0); - an = xn; - bn = yn; + un = xn; + vn = yn; - while (an != 0) { - MPN_SHIFT_ZEROES(az, ap, an); - MPN_SHIFT_ZEROES(bz, bp, bn); + while (un != 0) { + MPN_SHIFT_ZEROES(uz, up, un); + MPN_SHIFT_ZEROES(vz, vp, vn); - while (az--) { - if (up[0] & 1) - up[yn] = mpn_add_n(up, up, yp, yn); + while (uz--) { + if (ap[0] & 1) + ap[yn] = mpn_add_n(ap, ap, yp, yn); - mpn_rshift(up, up, yn + up[yn], 1); + mpn_rshift(ap, ap, yn + ap[yn], 1); } - while (bz--) { - if (vp[0] & 1) - vp[yn] = mpn_add_n(vp, vp, yp, yn); + while (vz--) { + if (bp[0] & 1) + bp[yn] = mpn_add_n(bp, bp, yp, yn); - mpn_rshift(vp, vp, yn + vp[yn], 1); + mpn_rshift(bp, bp, yn + bp[yn], 1); } - if (mpn_cmp2(ap, an, bp, bn) >= 0) { - mpn_sub_var(ap, ap, an, bp, bn); - mpn_sub_mod(up, up, vp, yp, yn); + if (mpn_cmp2(up, un, vp, vn) >= 0) { + mpn_sub(up, up, un, vp, vn); + mpn_sub_mod(ap, ap, bp, yp, yn); - an = mpn_strip(ap, an); + un = mpn_strip(up, un); } else { - mpn_sub_var(bp, bp, bn, ap, an); - mpn_sub_mod(vp, vp, up, yp, yn); + mpn_sub(vp, vp, vn, up, un); + mpn_sub_mod(bp, bp, ap, yp, yn); - bn = mpn_strip(bp, bn); + vn = mpn_strip(vp, vn); } } - if (bn != 1 || bp[0] != 1) { + if (vn != 1 || vp[0] != 1) { mpn_zero(zp, yn); return 0; } - mpn_copyi(zp, vp, yn); + mpn_copyi(zp, bp, yn); return 1; } @@ -3840,6 +3846,39 @@ mpn_invert_n(mp_limb_t *zp, const mp_limb_t *xp, return mpn_invert(zp, xp, xn, yp, yn, scratch); } +int +mpn_sec_invert(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, + const mp_limb_t *mp, mp_size_t mn, + mp_limb_t *scratch) { + mp_limb_t *yp = &scratch[0 * mn]; + mp_limb_t *tp = &scratch[1 * mn]; + mp_size_t yn = mn; + + if (mn == 0 || mp[mn - 1] == 0 || (mp[0] & 1) == 0) + torsion_abort(); /* LCOV_EXCL_LINE */ + + if (mn == 1 && mp[0] == 1) { + mpn_zero(zp, mn); + return 0; + } + + mpn_sub_1(yp, mp, mn, 2); + + yn -= (yp[yn - 1] == 0); + + mpn_sec_powm(zp, xp, xn, yp, yn, mp, mn, tp); + + return mpn_sec_zero_p(zp, mn) ^ 1; +} + +int +mpn_sec_invert_n(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *yp, + mp_size_t n, + mp_limb_t *scratch) { + return mpn_sec_invert(zp, xp, n, yp, n, scratch); +} + int mpn_jacobi(const mp_limb_t *xp, mp_size_t xn, const mp_limb_t *yp, mp_size_t yn, @@ -3848,9 +3887,9 @@ mpn_jacobi(const mp_limb_t *xp, mp_size_t xn, * * [JACOBI] Page 3, Section 3. */ - mp_limb_t *ap = &scratch[0 * yn]; - mp_limb_t *bp = &scratch[1 * yn]; - mp_size_t an, bn; + mp_limb_t *up = &scratch[0 * yn]; + mp_limb_t *vp = &scratch[1 * yn]; + mp_size_t un, vn; mp_bits_t bits; int j = 1; @@ -3863,41 +3902,41 @@ mpn_jacobi(const mp_limb_t *xp, mp_size_t xn, if (xn > yn) torsion_abort(); /* LCOV_EXCL_LINE */ - mpn_copyi(ap, xp, xn); - mpn_copyi(bp, yp, yn); + mpn_copyi(up, xp, xn); + mpn_copyi(vp, yp, yn); - an = xn; - bn = yn; + un = xn; + vn = yn; - while (an != 0) { - MPN_SHIFT_ZEROES(bits, ap, an); + while (un != 0) { + MPN_SHIFT_ZEROES(bits, up, un); if (bits & 1) { - if ((bp[0] & 7) == 3 || (bp[0] & 7) == 5) + if ((vp[0] & 7) == 3 || (vp[0] & 7) == 5) j = -j; } - if (mpn_cmp2(ap, an, bp, bn) < 0) { - MPN_SWAP(ap, an, bp, bn); + if (mpn_cmp2(up, un, vp, vn) < 0) { + MPN_SWAP(up, un, vp, vn); - if ((ap[0] & 3) == 3 && (bp[0] & 3) == 3) + if ((up[0] & 3) == 3 && (vp[0] & 3) == 3) j = -j; } - mpn_sub_var(ap, ap, an, bp, bn); + mpn_sub(up, up, un, vp, vn); - an = mpn_strip(ap, an); + un = mpn_strip(up, un); - if (an > 0) { - mpn_rshift(ap, ap, an, 1); - an -= (ap[an - 1] == 0); + if (un > 0) { + mpn_rshift(up, up, un, 1); + un -= (up[un - 1] == 0); } - if ((bp[0] & 7) == 3 || (bp[0] & 7) == 5) + if ((vp[0] & 7) == 3 || (vp[0] & 7) == 5) j = -j; } - if (bn != 1 || bp[0] != 1) + if (vn != 1 || vp[0] != 1) return 0; return j; @@ -3993,7 +4032,7 @@ mpn_div_powm(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mpn_sqr(sp, rp, mn, tp); mpn_mod_inner(rp, sp, sn, &den); - if (mpn_getbit(yp, yn, i)) { + if (mpn_tstbit(yp, i)) { mpn_mul_n(sp, rp, ap, mn); mpn_mod_inner(rp, sp, sn, &den); } @@ -4028,17 +4067,17 @@ mpn_mont_powm(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mpn_mont(&k, rr, mp, mn, tp); - mpn_montmul_var(ap, ap, rr, mp, mn, k, tp); + mpn_montmul(ap, ap, rr, mp, mn, k, tp); if (yn > 2) { - mpn_montmul_var(rp, ap, ap, mp, mn, k, tp); + mpn_montmul(rp, ap, ap, mp, mn, k, tp); #define WND(i) (&wp[(i) * mn]) mpn_copyi(WND(0), ap, mn); for (i = 1; i < MP_SLIDE_SIZE; i++) - mpn_montmul_var(WND(i), WND(i - 1), rp, mp, mn, k, tp); + mpn_montmul(WND(i), WND(i - 1), rp, mp, mn, k, tp); i = len; @@ -4047,7 +4086,7 @@ mpn_mont_powm(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, bits = mpn_getbits(yp, yn, i - width, width); if (bits < MP_SLIDE_SIZE) { - mpn_montmul_var(rp, rp, rp, mp, mn, k, tp); + mpn_montmul(rp, rp, rp, mp, mn, k, tp); i -= 1; continue; } @@ -4060,9 +4099,9 @@ mpn_mont_powm(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mpn_copyi(rp, WND(bits >> 1), mn); } else { for (j = 0; j < width; j++) - mpn_montmul_var(rp, rp, rp, mp, mn, k, tp); + mpn_montmul(rp, rp, rp, mp, mn, k, tp); - mpn_montmul_var(rp, rp, WND(bits >> 1), mp, mn, k, tp); + mpn_montmul(rp, rp, WND(bits >> 1), mp, mn, k, tp); } #undef WND @@ -4076,14 +4115,14 @@ mpn_mont_powm(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, } for (i -= 1; i >= 0; i--) { - mpn_montmul_var(rp, rp, rp, mp, mn, k, tp); + mpn_montmul(rp, rp, rp, mp, mn, k, tp); - if (mpn_getbit(yp, yn, i)) - mpn_montmul_var(rp, rp, ap, mp, mn, k, tp); + if (mpn_tstbit(yp, i)) + mpn_montmul(rp, rp, ap, mp, mn, k, tp); } mpn_set_1(rr, mn, 1); - mpn_montmul_var(rp, rp, rr, mp, mn, k, tp); + mpn_montmul(rp, rp, rr, mp, mn, k, tp); if (mpn_cmp(rp, mp, mn) >= 0) { mpn_sub_n(rp, rp, mp, mn); @@ -4166,11 +4205,11 @@ mpn_sec_powm(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, #define WND(i) (&wp[(i) * mn]) mpn_set_1(WND(0), mn, 1); - mpn_montmul(WND(0), WND(0), rr, mp, mn, k, tp); - mpn_montmul(WND(1), rp, rr, mp, mn, k, tp); + mpn_sec_montmul(WND(0), WND(0), rr, mp, mn, k, tp); + mpn_sec_montmul(WND(1), rp, rr, mp, mn, k, tp); for (i = 2; i < MP_FIXED_SIZE; i++) - mpn_montmul(WND(i), WND(i - 1), WND(1), mp, mn, k, tp); + mpn_sec_montmul(WND(i), WND(i - 1), WND(1), mp, mn, k, tp); steps = ((yn * MP_LIMB_BITS) + MP_FIXED_WIDTH - 1) / MP_FIXED_WIDTH; @@ -4181,49 +4220,115 @@ mpn_sec_powm(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, b = mpn_getbits(yp, yn, i * MP_FIXED_WIDTH, MP_FIXED_WIDTH); for (j = 0; j < MP_FIXED_SIZE; j++) - mpn_select(sp, sp, WND(j), mn, j == b); + mpn_cnd_select(sp, sp, WND(j), mn, j == b); if (i == steps - 1) { mpn_copyi(rp, sp, mn); } else { for (j = 0; j < MP_FIXED_WIDTH; j++) - mpn_montmul(rp, rp, rp, mp, mn, k, tp); + mpn_sec_montmul(rp, rp, rp, mp, mn, k, tp); - mpn_montmul(rp, rp, sp, mp, mn, k, tp); + mpn_sec_montmul(rp, rp, sp, mp, mn, k, tp); } } #undef WND mpn_set_1(rr, mn, 1); - mpn_montmul(zp, rp, rr, mp, mn, k, tp); + mpn_sec_montmul(zp, rp, rr, mp, mn, k, tp); } /* - * Helpers + * Primes */ -mp_size_t -mpn_strip(const mp_limb_t *xp, mp_size_t xn) { - while (xn > 0 && xp[xn - 1] == 0) - xn -= 1; +/* First 172 primes (2-1021). */ +static const mp_limb_t mp_primes[] = { +#if MP_LIMB_BITS == 32 + MP_LIMB_C(0xa08a28ac), MP_LIMB_C(0x28208a20), + MP_LIMB_C(0x02088288), MP_LIMB_C(0x800228a2), + MP_LIMB_C(0x20a00a08), MP_LIMB_C(0x80282088), + MP_LIMB_C(0x800800a2), MP_LIMB_C(0x08028228), + MP_LIMB_C(0x0a20a082), MP_LIMB_C(0x22880020), + MP_LIMB_C(0x28020800), MP_LIMB_C(0x88208082), + MP_LIMB_C(0x02022020), MP_LIMB_C(0x08828028), + MP_LIMB_C(0x8008a202), MP_LIMB_C(0x20880880), + MP_LIMB_C(0x20000a00), MP_LIMB_C(0x0a082008), + MP_LIMB_C(0x82820802), MP_LIMB_C(0x00800a20), + MP_LIMB_C(0x0028208a), MP_LIMB_C(0x20080822), + MP_LIMB_C(0x20808020), MP_LIMB_C(0x02208088), + MP_LIMB_C(0x20080022), MP_LIMB_C(0x28a00a00), + MP_LIMB_C(0x8a200080), MP_LIMB_C(0x008a2000), + MP_LIMB_C(0x00808800), MP_LIMB_C(0x02082202), + MP_LIMB_C(0x80820880), MP_LIMB_C(0x28220020) +#else + MP_LIMB_C(0x28208a20a08a28ac), + MP_LIMB_C(0x800228a202088288), + MP_LIMB_C(0x8028208820a00a08), + MP_LIMB_C(0x08028228800800a2), + MP_LIMB_C(0x228800200a20a082), + MP_LIMB_C(0x8820808228020800), + MP_LIMB_C(0x0882802802022020), + MP_LIMB_C(0x208808808008a202), + MP_LIMB_C(0x0a08200820000a00), + MP_LIMB_C(0x00800a2082820802), + MP_LIMB_C(0x200808220028208a), + MP_LIMB_C(0x0220808820808020), + MP_LIMB_C(0x28a00a0020080022), + MP_LIMB_C(0x008a20008a200080), + MP_LIMB_C(0x0208220200808800), + MP_LIMB_C(0x2822002080820880) +#endif +}; - return xn; -} +static mp_size_t +mpn_sieve_size(mp_limb_t n) { + mp_limb_t zn; -int -mpn_odd_p(const mp_limb_t *xp, mp_size_t xn) { - if (xn == 0) - return 0; + CHECK(n < MP_LOW_MASK * MP_LOW_MASK); + CHECK(n <= MP_LIMB_MAX - MP_LIMB_BITS); + CHECK(n <= MP_BITS_MAX); + + /* ((n + 1) + (L - 1)) / L */ + zn = (n + MP_LIMB_BITS) / MP_LIMB_BITS; - return xp[0] & 1; + CHECK(zn <= MP_SIZE_MAX); + + return zn; } -int -mpn_even_p(const mp_limb_t *xp, mp_size_t xn) { - return !mpn_odd_p(xp, xn); +static void +mpn_sieve(mp_limb_t *zp, mp_limb_t n) { + /* Sieve of Eratosthenes. */ + mp_limb_t zn = (n + MP_LIMB_BITS) / MP_LIMB_BITS; + mp_bits_t lo = (n + 1) % MP_LIMB_BITS; + mp_limb_t i, p; + + if (n < 1024) { + mpn_copyi(zp, mp_primes, zn); + return; + } + + for (i = 0; i < zn; i++) + zp[i] = MP_LIMB_MAX; + + for (p = 2; p * p <= n; p++) { + if (mpn_tstbit(zp, p)) { + for (i = p * p; i <= n; i += p) + mpn_clrbit(zp, i); + } + } + + zp[0] &= ~MP_LIMB_C(3); + + if (lo != 0) + zp[zn - 1] &= MP_MASK(lo); } +/* + * Helpers + */ + mp_bits_t mpn_ctz(const mp_limb_t *xp, mp_size_t xn) { mp_size_t i; @@ -4255,19 +4360,40 @@ mpn_bytelen(const mp_limb_t *xp, mp_size_t xn) { size_t mpn_sizeinbase(const mp_limb_t *xp, mp_size_t xn, int base) { - if (base >= 2 && (base & (base - 1)) == 0) { - mp_bits_t len = mpn_bitlen(xp, xn); - mp_bits_t den; + size_t len = 0; - if (len == 0) - return 1; + if (base < 2) + torsion_abort(); /* LCOV_EXCL_LINE */ + + xn = mpn_strip(xp, xn); - den = mp_bitlen(base - 1); + if (xn == 0) + return 1; + + if ((base & (base - 1)) == 0) { + mp_bits_t bits = xn * MP_LIMB_BITS - mp_clz(xp[xn - 1]); + mp_bits_t width = mp_bitlen(base - 1); + + len = (bits + width - 1) / width; + } else { + mp_limb_t *tp = mp_alloc_vla(xn); + mp_size_t tn = xn; + mp_divisor_t den; + + mpn_copyi(tp, xp, xn); + + mpn_divmod_init_1(&den, base); - return (len + den - 1) / den; + do { + mpn_divmod_inner_1(tp, tp, tn, &den); + tn -= (tp[tn - 1] == 0); + len += 1; + } while (tn != 0); + + mp_free_vla(tp, xn); } - return mpn_get_str(NULL, xp, xn, base); + return len; } /* @@ -4275,32 +4401,101 @@ mpn_sizeinbase(const mp_limb_t *xp, mp_size_t xn, int base) { */ void -mpn_select(mp_limb_t *zp, const mp_limb_t *xp, - const mp_limb_t *yp, - mp_size_t n, - int flag) { - mp_limb_t cond = (flag != 0); - mp_limb_t mask0 = mp_limb_barrier(cond - 1); - mp_limb_t mask1 = mp_limb_barrier(~mask0); +mpn_cnd_select(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *yp, + mp_size_t n, + mp_limb_t cnd) { + mp_limb_t m = -mp_limb_barrier(cnd != 0); mp_size_t i; for (i = 0; i < n; i++) - zp[i] = (xp[i] & mask0) | (yp[i] & mask1); + zp[i] = (xp[i] & ~m) | (yp[i] & m); } void -mpn_select_zero(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t n, int flag) { - mp_limb_t cond = (flag != 0); - mp_limb_t mask = mp_limb_barrier(cond - 1); +mpn_cnd_swap(mp_limb_t *xp, mp_limb_t *yp, mp_size_t n, mp_limb_t cnd) { + mp_limb_t m = -mp_limb_barrier(cnd != 0); + mp_limb_t w; mp_size_t i; - for (i = 0; i < n; i++) - zp[i] = xp[i] & mask; + for (i = 0; i < n; i++) { + w = (xp[i] ^ yp[i]) & m; + + xp[i] ^= w; + yp[i] ^= w; + } +} + +mp_limb_t +mpn_cnd_add_n(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *yp, + mp_size_t n, + mp_limb_t cnd) { + mp_limb_t m = -mp_limb_barrier(cnd != 0); + mp_limb_t c = 0; + mp_limb_t y; + mp_size_t i; + + for (i = 0; i < n; i++) { + y = yp[i] & m; + + mp_add_1(zp[i], c, xp[i], y); + } + + return c; +} + +mp_limb_t +mpn_cnd_sub_n(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *yp, + mp_size_t n, + mp_limb_t cnd) { + mp_limb_t m = -mp_limb_barrier(cnd != 0); + mp_limb_t c = 0; + mp_limb_t y; + mp_size_t i; + + for (i = 0; i < n; i++) { + y = yp[i] & m; + + mp_sub_1(zp[i], c, xp[i], y); + } + + return c; +} + +mp_limb_t +mpn_cnd_neg(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t cnd) { + mp_limb_t m = -mp_limb_barrier(cnd != 0); + mp_limb_t c = 1 & m; + mp_limb_t z; + mp_size_t i; + + for (i = 0; i < xn; i++) { + /* [z, c] = ~x + c */ + z = (xp[i] ^ m) + c; + c = (z < c); + zp[i] = z; + } + + return (c ^ 1) & m; +} + +void +mpn_sec_tabselect(mp_limb_t *zp, + const mp_limb_t *tp, + mp_size_t n, + mp_size_t nents, + mp_size_t which) { + mp_size_t i; + + for (i = 0; i < nents; i++) + mpn_cnd_select(zp, zp, tp + i * n, n, i == which); } int mpn_sec_zero_p(const mp_limb_t *xp, mp_size_t xn) { - /* Compute (x == y) in constant time. */ + /* Compute (x == 0) in constant time. */ mp_limb_t w = 0; mp_size_t i; @@ -4400,28 +4595,50 @@ mpn_sec_cmp(const mp_limb_t *xp, const mp_limb_t *yp, mp_size_t n) { void mpn_import(mp_limb_t *zp, mp_size_t zn, - const unsigned char *raw, size_t len, + const unsigned char *xp, size_t xn, int endian) { - mp_size_t size = mp_size_cast(len); - mp_size_t i, j, k; + mp_size_t i = 0; + mp_limb_t z; CHECK(endian == 1 || endian == -1); if (endian == 1) { - k = size - 1; + xp += xn; - for (i = 0; i < zn && k >= 0; i++) { - zp[i] = 0; - for (j = 0; j < MP_LIMB_BYTES && k >= 0; j++) - zp[i] |= (mp_limb_t)raw[k--] << (j * 8); + while (i < zn && xn >= MP_LIMB_BYTES) { + xp -= MP_LIMB_BYTES; + xn -= MP_LIMB_BYTES; + zp[i++] = mp_import_be(xp); + } + + if (i < zn && xn > 0) { + xp -= xn; + z = 0; + + do { + z <<= 8; + z |= *xp++; + } while (--xn); + + zp[i++] = z; } } else { - k = 0; + while (i < zn && xn >= MP_LIMB_BYTES) { + zp[i++] = mp_import_le(xp); + xp += MP_LIMB_BYTES; + xn -= MP_LIMB_BYTES; + } - for (i = 0; i < zn && k < size; i++) { - zp[i] = 0; - for (j = 0; j < MP_LIMB_BYTES && k < size; j++) - zp[i] |= (mp_limb_t)raw[k++] << (j * 8); + if (i < zn && xn > 0) { + xp += xn; + z = 0; + + do { + z <<= 8; + z |= *--xp; + } while (--xn); + + zp[i++] = z; } } @@ -4434,34 +4651,52 @@ mpn_import(mp_limb_t *zp, mp_size_t zn, */ void -mpn_export(unsigned char *raw, size_t len, +mpn_export(unsigned char *zp, size_t zn, const mp_limb_t *xp, mp_size_t xn, int endian) { - mp_size_t size = mp_size_cast(len); - mp_size_t i, j, k; + mp_size_t i = 0; + mp_limb_t x; CHECK(endian == 1 || endian == -1); if (endian == 1) { - k = size - 1; + zp += zn; + + while (i < xn && zn >= MP_LIMB_BYTES) { + zp -= MP_LIMB_BYTES; + zn -= MP_LIMB_BYTES; + mp_export_be(zp, xp[i++]); + } + + if (i < xn && zn > 0) { + x = xp[i]; - for (i = 0; i < xn && k >= 0; i++) { - for (j = 0; j < MP_LIMB_BYTES && k >= 0; j++) - raw[k--] = (xp[i] >> (j * 8)) & 0xff; + do { + *--zp = x & 0xff; + x >>= 8; + } while (--zn); } - while (k >= 0) - raw[k--] = 0; + while (zn--) + *--zp = 0; } else { - k = 0; + while (i < xn && zn >= MP_LIMB_BYTES) { + mp_export_le(zp, xp[i++]); + zp += MP_LIMB_BYTES; + zn -= MP_LIMB_BYTES; + } + + if (i < xn && zn > 0) { + x = xp[i]; - for (i = 0; i < xn && k < size; i++) { - for (j = 0; j < MP_LIMB_BYTES && k < size; j++) - raw[k++] = (xp[i] >> (j * 8)) & 0xff; + do { + *zp++ = x & 0xff; + x >>= 8; + } while (--zn); } - while (k < size) - raw[k++] = 0; + while (zn--) + *zp++ = 0; } } @@ -4564,45 +4799,24 @@ mpn_set_str(mp_limb_t *zp, mp_size_t zn, const char *str, int base) { ch = table[ch & 0xff]; - if (ch >= base) + if (UNLIKELY(ch >= base)) goto fail; - if (shift > 0) { - if (n > 0) { - c = mpn_lshift(zp, zp, n, shift); - - if (c != 0) { - if (n == zn) - goto fail; - - zp[n++] = c; - } - - zp[0] |= ch; - } else if (ch != 0) { - if (n == zn) - goto fail; - - zp[n++] = ch; - } + if (n == 0) { + c = ch; + } else if (shift > 0) { + c = mpn_lshift(zp, zp, n, shift); + zp[0] |= ch; } else { c = mpn_mul_1(zp, zp, n, base); + c += mpn_add_1(zp, zp, n, ch); + } - if (c != 0) { - if (n == zn) - goto fail; - - zp[n++] = c; - } - - c = mpn_add_var_1(zp, zp, n, ch); - - if (c != 0) { - if (n == zn) - goto fail; + if (c != 0) { + if (UNLIKELY(n == zn)) + goto fail; - zp[n++] = c; - } + zp[n++] = c; } } @@ -4615,248 +4829,146 @@ mpn_set_str(mp_limb_t *zp, mp_size_t zn, const char *str, int base) { } /* - * String Export - */ - -size_t -mpn_get_str(char *str, const mp_limb_t *xp, mp_size_t xn, int base) { - const char *charset; - mp_bits_t shift = 0; - mp_divisor_t den; - size_t len = 0; - size_t i, j, k; - mp_limb_t *tp; - mp_size_t tn; - int ch; - - CHECK(base >= 2 && base <= 62); - - xn = mpn_strip(xp, xn); - - if (xn == 0) { - if (str != NULL) { - str[0] = '0'; - str[1] = '\0'; - } - return 1; - } - - tp = mp_alloc_vla(xn); - tn = xn; - - mpn_copyi(tp, xp, xn); - - if ((base & (base - 1)) == 0) - shift = mp_bitlen(base - 1); - else - mpn_divmod_init_1(&den, base); - - if (base <= 36) { - charset = "0123456789abcdefghijklmnopqrstuvwxyz"; - } else { - charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; - } - - do { - if (shift > 0) - ch = mpn_rshift(tp, tp, tn, shift); - else - ch = mpn_divmod_inner_1(tp, tp, tn, &den); - - tn -= (tp[tn - 1] == 0); - - if (str != NULL) - str[len] = charset[ch]; - - len += 1; - } while (tn != 0); - - mp_free_vla(tp, xn); - - if (str != NULL) { - i = 0; - j = len - 1; - k = len >> 1; - - while (k--) { - ch = str[i]; - str[i++] = str[j]; - str[j--] = ch; - } - - str[len] = '\0'; - } - - return len; -} - -/* - * STDIO - */ - -void -mpn_print(const mp_limb_t *xp, mp_size_t xn, int base, mp_puts_f *mp_puts) { - size_t size = mpn_sizeinbase(xp, xn, base); - char *str = mp_alloc_vls(size + 1); - - mpn_get_str(str, xp, xn, base); - - mp_puts(str); - mp_free_vls(str, size + 1); -} - -/* - * RNG - */ - -void -mpn_random(mp_limb_t *zp, mp_size_t zn, mp_rng_f *rng, void *arg) { - rng(zp, zn * sizeof(mp_limb_t), arg); -} - -/* - * MPV Interface - */ - -/* - * Addition - */ - -static TORSION_INLINE mp_size_t -mpv_add_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y) { - zp[xn] = mpn_add_var_1(zp, xp, xn, y); - return xn + (zp[xn] != 0); -} - -static TORSION_INLINE mp_size_t -mpv_add(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, - const mp_limb_t *yp, mp_size_t yn) { - mp_size_t zn = MP_MAX(xn, yn); - - if (xn >= yn) - zp[zn] = mpn_add_var(zp, xp, xn, yp, yn); - else - zp[zn] = mpn_add_var(zp, yp, yn, xp, xn); - - return zn + (zp[zn] != 0); -} - -/* - * Subtraction + * String Export */ -static TORSION_INLINE mp_size_t -mpv_sub_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y) { - CHECK(mpn_sub_var_1(zp, xp, xn, y) == 0); +size_t +mpn_get_str(char *str, const mp_limb_t *xp, mp_size_t xn, int base) { + const char *charset; + size_t len = 0; + int ch; - if (xn == 0) - return 0; + if (base < 2 || base > 62) + torsion_abort(); /* LCOV_EXCL_LINE */ - return xn - (zp[xn - 1] == 0); -} + xn = mpn_strip(xp, xn); -static TORSION_INLINE mp_size_t -mpv_sub(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, - const mp_limb_t *yp, mp_size_t yn) { - CHECK(mpn_sub_var(zp, xp, xn, yp, yn) == 0); - return mpn_strip(zp, xn); -} + if (xn == 0) { + str[0] = '0'; + str[1] = '\0'; + return 1; + } -/* - * Multiplication - */ + if (base <= 36) { + charset = "0123456789abcdefghijklmnopqrstuvwxyz"; + } else { + charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + } -static TORSION_INLINE mp_size_t -mpv_mul_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y) { - ASSERT(xn != 0 && y != 0); + if (base == 2 || base == 4 || base == 16) { + mp_bits_t shift = mp_bitlen(base - 1); + mp_bits_t digits = MP_LIMB_BITS / shift; + mp_limb_t mask = base - 1; + mp_size_t i; + mp_bits_t j; + mp_limb_t x; - zp[xn] = mpn_mul_1(zp, xp, xn, y); + for (i = 0; i < xn - 1; i++) { + x = xp[i]; - return xn + (zp[xn] != 0); -} + for (j = 0; j < digits; j++) { + str[len++] = charset[x & mask]; + x >>= shift; + } + } -static TORSION_INLINE mp_size_t -mpv_mul(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, - const mp_limb_t *yp, mp_size_t yn) { - mp_size_t zn = xn + yn; + x = xp[xn - 1]; - ASSERT(xn != 0 && yn != 0); + do { + str[len++] = charset[x & mask]; + x >>= shift; + } while (x != 0); + } else if ((base & (base - 1)) == 0) { + mp_bits_t bits = xn * MP_LIMB_BITS - mp_clz(xp[xn - 1]); + mp_bits_t width = mp_bitlen(base - 1); + mp_bits_t pos = 0; - if (xn >= yn) - mpn_mul(zp, xp, xn, yp, yn); - else - mpn_mul(zp, yp, yn, xp, xn); + do { + ch = mpn_getbits(xp, xn, pos, width); + str[len++] = charset[ch]; + pos += width; + } while (pos < bits); + } else { + mp_limb_t *tp = mp_alloc_vla(xn); + mp_size_t tn = xn; + mp_divisor_t den; - return zn - (zp[zn - 1] == 0); -} + mpn_copyi(tp, xp, xn); -static TORSION_INLINE mp_size_t -mpv_sqr_1(mp_limb_t *zp, mp_limb_t x) { - ASSERT(x != 0); + mpn_divmod_init_1(&den, base); - mp_sqr(zp[1], zp[0], x); + do { + ch = mpn_divmod_inner_1(tp, tp, tn, &den); + tn -= (tp[tn - 1] == 0); + str[len++] = charset[ch]; + } while (tn != 0); - return 2 - (zp[1] == 0); -} + mp_free_vla(tp, xn); + } -static TORSION_INLINE mp_size_t -mpv_sqr(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t *scratch) { - mp_size_t zn = xn * 2; + { + size_t i = 0; + size_t j = len - 1; + size_t k = len >> 1; - ASSERT(xn != 0); + while (k--) { + ch = str[i]; + str[i++] = str[j]; + str[j--] = ch; + } + } - mpn_sqr(zp, xp, xn, scratch); + str[len] = '\0'; - return zn - (zp[zn - 1] == 0); + return len; } /* - * Left Shift + * STDIO */ -static TORSION_INLINE mp_size_t -mpv_lshift(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_bits_t bits) { - mp_size_t s = bits / MP_LIMB_BITS; - mp_bits_t r = bits % MP_LIMB_BITS; - mp_size_t zn = xn + s; - - if (xn == 0) - return 0; - - if (r != 0) { - zp[zn] = mpn_lshift(zp + s, xp, xn, r); - zn += (zp[zn] != 0); - } else if (s != 0 || zp != xp) { - mpn_copyd(zp + s, xp, xn); - } +void +mpn_print(const mp_limb_t *xp, mp_size_t xn, int base, mp_puts_f *mp_puts) { + size_t size = mpn_sizeinbase(xp, xn, base); + char *str = mp_alloc_vls(size + 1); - mpn_zero(zp, s); + mpn_get_str(str, xp, xn, base); - return zn; + mp_puts(str); + mp_free_vls(str, size + 1); } /* - * Right Shift + * RNG */ -static TORSION_INLINE mp_size_t -mpv_rshift(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_bits_t bits) { - mp_size_t s = bits / MP_LIMB_BITS; - mp_bits_t r = bits % MP_LIMB_BITS; - mp_size_t zn = xn - s; +void +mpn_random(mp_limb_t *zp, mp_size_t zn, mp_rng_f *rng, void *arg) { + rng(zp, zn * sizeof(mp_limb_t), arg); +} - if (zn <= 0) - return 0; +void +mpn_randomm(mp_limb_t *zp, + const mp_limb_t *xp, mp_size_t xn, + mp_rng_f *rng, void *arg) { + mp_size_t n = mpn_strip(xp, xn); + mp_bits_t s; - if (r != 0) { - mpn_rshift(zp, xp + s, zn, r); - zn -= (zp[zn - 1] == 0); - } else if (s != 0 || zp != xp) { - mpn_copyi(zp, xp + s, zn); + if (zp == xp) + torsion_abort(); /* LCOV_EXCL_LINE */ + + if (n > 0) { + s = mp_clz(xp[n - 1]); + + do { + mpn_random(zp, n, rng, arg); + + zp[n - 1] >>= s; + } while (mpn_cmp(zp, xp, n) >= 0); } - return zn; + mpn_zero(zp + n, xn - n); } /* @@ -4954,7 +5066,7 @@ mpz_cleanse(mpz_t z) { * Internal */ -static void +static mp_limb_t * mpz_grow(mpz_t z, mp_size_t n) { ASSERT(z->alloc > 0); @@ -4962,6 +5074,8 @@ mpz_grow(mpz_t z, mp_size_t n) { z->limbs = mp_realloc_limbs(z->limbs, n); z->alloc = n; } + + return z->limbs; } static mp_size_t @@ -4980,10 +5094,9 @@ void mpz_set(mpz_t z, const mpz_t x) { if (z != x) { mp_size_t xn = MP_ABS(x->size); + mp_limb_t *zp = mpz_grow(z, xn); - mpz_grow(z, xn); - - mpn_copyi(z->limbs, x->limbs, xn); + mpn_copyi(zp, x->limbs, xn); z->size = x->size; } @@ -4996,39 +5109,52 @@ mpz_roset(mpz_t z, const mpz_t x) { z->size = x->size; } -void +static void +mpz_roset_n(mpz_t z, const mp_limb_t *xp, mp_size_t xs) { + z->limbs = (mp_limb_t *)xp; + z->alloc = 0; + z->size = xs; +} + +const struct mpz_s * mpz_roinit_n(mpz_t z, const mp_limb_t *xp, mp_size_t xs) { mp_size_t zn = mpn_strip(xp, MP_ABS(xs)); z->limbs = (mp_limb_t *)xp; z->alloc = 0; z->size = xs < 0 ? -zn : zn; + + return z; } void mpz_set_ui(mpz_t z, mp_limb_t x) { - if (x == 0) { - z->size = 0; - } else { - mpz_grow(z, 1); - - z->limbs[0] = x; - z->size = 1; - } + z->limbs[0] = x; + z->size = (x != 0); } void mpz_set_si(mpz_t z, mp_long_t x) { - if (x == 0) { - z->size = 0; - } else { - mpz_grow(z, 1); + mp_size_t xn = (x != 0); - z->limbs[0] = mp_limb_cast(x); - z->size = x < 0 ? -1 : 1; - } + z->limbs[0] = mp_limb_cast(x); + z->size = x < 0 ? -xn : xn; } +#define mpz_roinit_ui(z, x) do { \ + (z)->limbs = &(x); \ + (z)->alloc = 0; \ + (z)->size = ((x) != 0); \ +} while (0) + +#define mpz_roinit_si(z, x) \ + mp_limb_t _t = mp_limb_cast(x); \ + mp_size_t _n = (_t != 0); \ + \ + (z)->limbs = &_t; \ + (z)->alloc = 0; \ + (z)->size = (x) < 0 ? -_n : _n + /* * Conversion */ @@ -5106,44 +5232,90 @@ mpz_cmpabs_ui(const mpz_t x, mp_limb_t y) { int mpz_cmpabs_si(const mpz_t x, mp_long_t y) { - return mpn_cmp_1(x->limbs, MP_ABS(x->size), mp_limb_cast(y)); + return mpz_cmpabs_ui(x, mp_limb_cast(y)); } /* - * Addition + * Arithmetic Helpers */ -void -mpz_add(mpz_t z, const mpz_t x, const mpz_t y) { - mp_size_t sign = x->size ^ y->size; +static mp_size_t +mpz_addabs(mpz_t z, const mpz_t x, const mpz_t y) { + mp_size_t xn = MP_ABS(x->size); + mp_size_t yn = MP_ABS(y->size); + mp_limb_t *zp; + + if (xn < yn) + MPZ_CSWAP(x, xn, y, yn); + + zp = mpz_grow(z, xn + 1); + + zp[xn] = mpn_add(zp, x->limbs, xn, y->limbs, yn); + + return xn + (zp[xn] != 0); +} + +static mp_size_t +mpz_addabs_ui(mpz_t z, const mpz_t x, mp_limb_t y) { + mp_size_t xn = MP_ABS(x->size); + mp_limb_t *zp = mpz_grow(z, xn + 1); + + zp[xn] = mpn_add_1(zp, x->limbs, xn, y); + + return xn + (zp[xn] != 0); +} + +static mp_size_t +mpz_subabs(mpz_t z, const mpz_t x, const mpz_t y) { mp_size_t xn = MP_ABS(x->size); mp_size_t yn = MP_ABS(y->size); - mp_size_t zn = MP_MAX(xn, yn) + (sign >= 0); + mp_limb_t *zp = mpz_grow(z, xn); + + ASSERT(mpn_sub(zp, x->limbs, xn, y->limbs, yn) == 0); + + return mpn_strip(zp, xn); +} + +static mp_size_t +mpz_subabs_ui(mpz_t z, const mpz_t x, mp_limb_t y) { + mp_size_t xn = MP_ABS(x->size); + mp_limb_t *zp = mpz_grow(z, xn); + + ASSERT(mpn_sub_1(zp, x->limbs, xn, y) == 0); + + if (UNLIKELY(xn == 0)) + return 0; + + return xn - (zp[xn - 1] == 0); +} + +/* + * Addition + */ - mpz_grow(z, zn); +void +mpz_add(mpz_t z, const mpz_t x, const mpz_t y) { + mp_size_t zn; - if (sign >= 0) { + if ((x->size ^ y->size) >= 0) { /* x + y == x + y */ /* (-x) + (-y) == -(x + y) */ - zn = mpv_add(z->limbs, x->limbs, xn, y->limbs, yn); + zn = mpz_addabs(z, x, y); } else { - int cmp = mpn_cmp2(x->limbs, xn, y->limbs, yn); + int cmp = mpz_cmpabs(x, y); if (cmp == 0) { /* x + (-x) == 0 */ /* (-x) + x == 0 */ - z->size = 0; - return; - } - - if (cmp < 0) { + zn = 0; + } else if (cmp < 0) { /* x + (-y) == -(y - x) */ /* (-x) + y == y - x */ - zn = -mpv_sub(z->limbs, y->limbs, yn, x->limbs, xn); + zn = -mpz_subabs(z, y, x); } else { /* x + (-y) == x - y */ /* (-x) + y == -(x - y) */ - zn = mpv_sub(z->limbs, x->limbs, xn, y->limbs, yn); + zn = mpz_subabs(z, x, y); } } @@ -5152,22 +5324,19 @@ mpz_add(mpz_t z, const mpz_t x, const mpz_t y) { void mpz_add_ui(mpz_t z, const mpz_t x, mp_limb_t y) { - mp_size_t xn = MP_ABS(x->size); - mp_size_t zn = MP_MAX(xn, 1) + (x->size >= 0); - - mpz_grow(z, zn); + mp_size_t zn; if (x->size >= 0) { /* x + y == x + y */ - zn = mpv_add_1(z->limbs, x->limbs, xn, y); + zn = mpz_addabs_ui(z, x, y); } else { - if (xn == 1 && x->limbs[0] < y) { + if (mpz_cmpabs_ui(x, y) < 0) { /* (-x) + y == y - x */ z->limbs[0] = y - x->limbs[0]; zn = 1; } else { /* (-x) + y == -(x - y) */ - zn = -mpv_sub_1(z->limbs, x->limbs, xn, y); + zn = -mpz_subabs_ui(z, x, y); } } @@ -5191,35 +5360,27 @@ mpz_add_si(mpz_t z, const mpz_t x, mp_long_t y) { void mpz_sub(mpz_t z, const mpz_t x, const mpz_t y) { - mp_size_t sign = x->size ^ y->size; - mp_size_t xn = MP_ABS(x->size); - mp_size_t yn = MP_ABS(y->size); - mp_size_t zn = MP_MAX(xn, yn) + (sign < 0); - - mpz_grow(z, zn); + mp_size_t zn; - if (sign < 0) { + if ((x->size ^ y->size) < 0) { /* x - (-y) == x + y */ /* (-x) - y == -(x + y) */ - zn = mpv_add(z->limbs, x->limbs, xn, y->limbs, yn); + zn = mpz_addabs(z, x, y); } else { - int cmp = mpn_cmp2(x->limbs, xn, y->limbs, yn); + int cmp = mpz_cmpabs(x, y); if (cmp == 0) { /* x - x == 0 */ /* (-x) - (-x) == 0 */ - z->size = 0; - return; - } - - if (cmp < 0) { + zn = 0; + } else if (cmp < 0) { /* x - y == -(y - x) */ /* (-x) - (-y) == y - x */ - zn = -mpv_sub(z->limbs, y->limbs, yn, x->limbs, xn); + zn = -mpz_subabs(z, y, x); } else { /* x - y == x - y */ /* (-x) - (-y) == -(x - y) */ - zn = mpv_sub(z->limbs, x->limbs, xn, y->limbs, yn); + zn = mpz_subabs(z, x, y); } } @@ -5228,26 +5389,23 @@ mpz_sub(mpz_t z, const mpz_t x, const mpz_t y) { void mpz_sub_ui(mpz_t z, const mpz_t x, mp_limb_t y) { - mp_size_t xn = MP_ABS(x->size); - mp_size_t zn = MP_MAX(xn, 1) + (x->size < 0); - - mpz_grow(z, zn); + mp_size_t zn; if (x->size < 0) { /* (-x) - y == -(x + y) */ - zn = -mpv_add_1(z->limbs, x->limbs, xn, y); + zn = -mpz_addabs_ui(z, x, y); } else { - if (xn == 0) { + if (x->size == 0) { /* 0 - y == -(y) */ z->limbs[0] = y; zn = -(y != 0); - } else if (xn == 1 && x->limbs[0] < y) { + } else if (mpz_cmpabs_ui(x, y) < 0) { /* x - y == -(y - x) */ z->limbs[0] = y - x->limbs[0]; zn = -1; } else { /* x - y == x - y */ - zn = mpv_sub_1(z->limbs, x->limbs, xn, y); + zn = mpz_subabs_ui(z, x, y); } } @@ -5267,47 +5425,16 @@ mpz_sub_si(mpz_t z, const mpz_t x, mp_long_t y) { void mpz_ui_sub(mpz_t z, mp_limb_t x, const mpz_t y) { - mp_size_t yn = MP_ABS(y->size); - mp_size_t zn = MP_MAX(1, yn) + (y->size < 0); - - mpz_grow(z, zn); - - if (y->size < 0) { - /* x - (-y) == y + x */ - zn = mpv_add_1(z->limbs, y->limbs, yn, x); - } else { - if (yn == 0) { - /* x - 0 == x */ - z->limbs[0] = x; - zn = (x != 0); - } else if (yn == 1 && x > y->limbs[0]) { - /* x - y == x - y */ - z->limbs[0] = x - y->limbs[0]; - zn = 1; - } else { - /* x - y == -(y - x) */ - zn = -mpv_sub_1(z->limbs, y->limbs, yn, x); - } - } - - z->size = zn; + /* x - y == -(y - x) */ + mpz_sub_ui(z, y, x); + mpz_neg(z, z); } void mpz_si_sub(mpz_t z, mp_long_t x, const mpz_t y) { - if (x < 0) { - if (y->size < 0) { - /* (-x) - (-y) == y - x */ - mpz_neg(z, y); - mpz_sub_ui(z, z, mp_limb_cast(x)); - } else { - /* (-x) - y == -(y + x) */ - mpz_add_ui(z, y, mp_limb_cast(x)); - mpz_neg(z, z); - } - } else { - mpz_ui_sub(z, x, y); - } + /* x - y == -(y - x) */ + mpz_sub_si(z, y, x); + mpz_neg(z, z); } /* @@ -5316,8 +5443,9 @@ mpz_si_sub(mpz_t z, mp_long_t x, const mpz_t y) { void mpz_mul(mpz_t z, const mpz_t x, const mpz_t y) { - mp_size_t xn, yn, zn, tn; - mp_limb_t *tp; + const mp_limb_t *xp, *yp; + mp_size_t xn, yn, zn; + mp_limb_t *zp, *tp; if (x == y) { mpz_sqr(z, x); @@ -5333,30 +5461,35 @@ mpz_mul(mpz_t z, const mpz_t x, const mpz_t y) { yn = MP_ABS(y->size); zn = xn + yn; - mpz_grow(z, zn); + if (xn < yn) + MPZ_CSWAP(x, xn, y, yn); - if (xn == 1) { - zn = mpv_mul_1(z->limbs, y->limbs, yn, x->limbs[0]); - } else if (yn == 1) { - zn = mpv_mul_1(z->limbs, x->limbs, xn, y->limbs[0]); - } else if (z == x || z == y) { - tn = zn; - tp = mp_alloc_vla(tn); - zn = mpv_mul(tp, x->limbs, xn, y->limbs, yn); + zp = mpz_grow(z, zn); + xp = x->limbs; + yp = y->limbs; - mpn_copyi(z->limbs, tp, zn); + if (yn == 1) { + zp[xn] = mpn_mul_1(zp, xp, xn, yp[0]); + } else if (zp == xp || zp == yp) { + tp = mp_alloc_vla(zn); - mp_free_vla(tp, tn); + mpn_mul(tp, xp, xn, yp, yn); + mpn_copyi(zp, tp, zn); + + mp_free_vla(tp, zn); } else { - zn = mpv_mul(z->limbs, x->limbs, xn, y->limbs, yn); + mpn_mul(zp, xp, xn, yp, yn); } + zn -= (zp[zn - 1] == 0); + z->size = (x->size ^ y->size) < 0 ? -zn : zn; } void mpz_mul_ui(mpz_t z, const mpz_t x, mp_limb_t y) { mp_size_t xn, zn; + mp_limb_t *zp; if (x->size == 0 || y == 0) { z->size = 0; @@ -5365,10 +5498,11 @@ mpz_mul_ui(mpz_t z, const mpz_t x, mp_limb_t y) { xn = MP_ABS(x->size); zn = xn + 1; + zp = mpz_grow(z, zn); - mpz_grow(z, zn); + zp[xn] = mpn_mul_1(zp, x->limbs, xn, y); - zn = mpv_mul_1(z->limbs, x->limbs, xn, y); + zn -= (zp[zn - 1] == 0); z->size = x->size < 0 ? -zn : zn; } @@ -5384,7 +5518,8 @@ mpz_mul_si(mpz_t z, const mpz_t x, mp_long_t y) { void mpz_sqr(mpz_t z, const mpz_t x) { mp_size_t xn, zn, tn; - mp_limb_t *tp; + const mp_limb_t *xp; + mp_limb_t *zp, *tp; if (x->size == 0) { z->size = 0; @@ -5394,28 +5529,31 @@ mpz_sqr(mpz_t z, const mpz_t x) { xn = MP_ABS(x->size); zn = xn * 2; - mpz_grow(z, zn); + zp = mpz_grow(z, zn); + xp = x->limbs; if (xn == 1) { - zn = mpv_sqr_1(z->limbs, x->limbs[0]); - } else if (z == x) { + mp_sqr(zp[1], zp[0], xp[0]); + } else if (zp == xp) { tn = zn * 2; tp = mp_alloc_vla(tn); - zn = mpv_sqr(tp, x->limbs, xn, tp + zn); - mpn_copyi(z->limbs, tp, zn); + mpn_sqr(tp, xp, xn, tp + zn); + mpn_copyi(zp, tp, zn); mp_free_vla(tp, tn); } else if (zn <= mp_alloca_max) { - tn = zn; - tp = mp_alloc_vla(tn); - zn = mpv_sqr(z->limbs, x->limbs, xn, tp); + tp = mp_alloc_vla(zn); - mp_free_vla(tp, tn); + mpn_sqr(zp, xp, xn, tp); + + mp_free_vla(tp, zn); } else { - zn = mpv_mul(z->limbs, x->limbs, xn, x->limbs, xn); + mpn_mul(zp, xp, xn, xp, xn); } + zn -= (zp[zn - 1] == 0); + z->size = zn; } @@ -5539,15 +5677,11 @@ mpz_quorem(mpz_t q, mpz_t r, const mpz_t n, const mpz_t d) { return; } - if (q != NULL) { - mpz_grow(q, qn); - qp = q->limbs; - } + if (q != NULL) + qp = mpz_grow(q, qn); - if (r != NULL) { - mpz_grow(r, rn); - rp = r->limbs; - } + if (r != NULL) + rp = mpz_grow(r, rn); mpn_divmod(qp, rp, n->limbs, nn, d->limbs, dn); @@ -5595,10 +5729,8 @@ mpz_quo_ui(mpz_t q, const mpz_t n, mp_limb_t d) { return n->limbs[0]; } - if (q != NULL) { - mpz_grow(q, nn); - qp = q->limbs; - } + if (q != NULL) + qp = mpz_grow(q, nn); r = mpn_divmod_1(qp, n->limbs, nn, d); @@ -5774,17 +5906,18 @@ mpz_divexact(mpz_t q, const mpz_t n, const mpz_t d) { mp_size_t nn = MP_ABS(n->size); mp_size_t dn = MP_ABS(d->size); mp_size_t qn = nn - dn + 1; + mp_limb_t *qp; if (nn < dn) { q->size = 0; return; } - mpz_grow(q, qn); + qp = mpz_grow(q, qn); - mpn_divexact(q->limbs, n->limbs, nn, d->limbs, dn); + mpn_divexact(qp, n->limbs, nn, d->limbs, dn); - qn -= (q->limbs[qn - 1] == 0); + qn -= (qp[qn - 1] == 0); q->size = (n->size ^ d->size) < 0 ? -qn : qn; } @@ -5793,6 +5926,7 @@ void mpz_divexact_ui(mpz_t q, const mpz_t n, mp_limb_t d) { mp_size_t nn = MP_ABS(n->size); mp_size_t qn = nn; + mp_limb_t *qp; if (d == 0) torsion_abort(); /* LCOV_EXCL_LINE */ @@ -5802,11 +5936,11 @@ mpz_divexact_ui(mpz_t q, const mpz_t n, mp_limb_t d) { return; } - mpz_grow(q, qn); + qp = mpz_grow(q, qn); - mpn_divexact_1(q->limbs, n->limbs, nn, d); + mpn_divexact_1(qp, n->limbs, nn, d); - qn -= (q->limbs[qn - 1] == 0); + qn -= (qp[qn - 1] == 0); q->size = n->size < 0 ? -qn : qn; } @@ -5825,51 +5959,35 @@ mpz_divexact_si(mpz_t q, const mpz_t n, mp_long_t d) { void mpz_divround(mpz_t q, const mpz_t n, const mpz_t d) { - mp_size_t nn = MP_ABS(n->size); - mp_size_t dn = MP_ABS(d->size); - mp_size_t qn = nn - dn + 2; - - if (dn == 0) - torsion_abort(); /* LCOV_EXCL_LINE */ - - if (nn == 0 || nn < dn - 1) { - q->size = 0; - return; - } - - mpz_grow(q, qn); - - mpn_divround(q->limbs, n->limbs, nn, d->limbs, dn); - - qn -= (q->limbs[qn - 1] == 0); - - if (qn > 0) - qn -= (q->limbs[qn - 1] == 0); - - q->size = (n->size ^ d->size) < 0 ? -qn : qn; -} + /* Computes q = (n +- (d / 2)) / d. */ + mpz_t t; -void -mpz_divround_ui(mpz_t q, const mpz_t n, mp_limb_t d) { - mp_size_t nn = MP_ABS(n->size); - mp_size_t qn = nn + 1; + mpz_init_vla(t, mpz_add_size(n, d)); - if (d == 0) - torsion_abort(); /* LCOV_EXCL_LINE */ + mpz_quo_2exp(t, d, 1); - if (nn == 0) { - q->size = 0; - return; - } + if ((n->size ^ d->size) < 0) + mpz_sub(t, n, t); + else + mpz_add(t, n, t); - mpz_grow(q, qn); + mpz_quo(q, t, d); - mpn_divround_1(q->limbs, n->limbs, nn, d); + mpz_clear_vla(t); +} - qn -= (q->limbs[qn - 1] == 0); - qn -= (q->limbs[qn - 1] == 0); +void +mpz_divround_ui(mpz_t q, const mpz_t n, mp_limb_t d) { + mp_size_t s = n->size; + mp_limb_t r = mpz_quo_ui(q, n, d); + mp_limb_t h = d >> 1; - q->size = n->size < 0 ? -qn : qn; + if (r > h || (r == h && (d & 1) == 0)) { + if (s < 0) + mpz_sub_ui(q, q, 1); + else + mpz_add_ui(q, q, 1); + } } void @@ -6165,7 +6283,8 @@ mpz_root(mpz_t z, const mpz_t x, mp_limb_t k) { int mpz_perfect_power_p(const mpz_t x) { mp_limb_t n = mpz_bitlen(x); - mp_limb_t *sieve; + mp_limb_t *sp; + mp_size_t sn; mp_limb_t p; int ret = 1; @@ -6176,10 +6295,13 @@ mpz_perfect_power_p(const mpz_t x) { return 1; /* Test prime exponents in [3,ceil(log2(x+1))]. */ - sieve = mp_eratosthenes(n); + sn = mpn_sieve_size(n); + sp = mp_alloc_vla(sn); + + mpn_sieve(sp, n); for (p = 3; p <= n; p += 2) { - if (mpn_tstbit(sieve, p)) { + if (mpn_tstbit(sp, p)) { if (mpz_root(NULL, x, p)) goto done; } @@ -6187,7 +6309,7 @@ mpz_perfect_power_p(const mpz_t x) { ret = 0; done: - mp_free_limbs(sieve); + mp_free_vla(sp, sn); return ret; } @@ -6281,16 +6403,21 @@ void mpz_and(mpz_t z, const mpz_t x, const mpz_t y) { mp_size_t xn = MP_ABS(x->size); mp_size_t yn = MP_ABS(y->size); - mp_size_t zn = MP_MAX(xn, yn); + const mp_limb_t *xp, *yp; mp_limb_t cx, cy, cz; mp_limb_t fx, fy; mp_limb_t zx, zy; - mp_size_t i; + mp_size_t i, zn; + mp_limb_t *zp; if (xn < yn) MPZ_CSWAP(x, xn, y, yn); - mpz_grow(z, zn + 1); + zn = xn; + zp = mpz_grow(z, zn + 1); + + xp = x->limbs; + yp = y->limbs; if ((x->size & y->size) < 0) { /* (-x) & (-y) == ~(x-1) & ~(y-1) @@ -6302,24 +6429,23 @@ mpz_and(mpz_t z, const mpz_t x, const mpz_t y) { cz = 1; for (i = 0; i < yn; i++) { - mp_sub(zx, cx, x->limbs[i], cx); - mp_sub(zy, cy, y->limbs[i], cy); + mp_sub(zx, cx, xp[i], cx); + mp_sub(zy, cy, yp[i], cy); zx |= zy; - mp_add(z->limbs[i], cz, zx, cz); + mp_add(zp[i], cz, zx, cz); } for (i = yn; i < xn; i++) { - mp_sub(zx, cx, x->limbs[i], cx); - mp_add(z->limbs[i], cz, zx, cz); + mp_sub(zx, cx, xp[i], cx); + mp_add(zp[i], cz, zx, cz); } - z->limbs[zn++] = cz; - } else { + zp[zn++] = cz; + } else if ((x->size | y->size) < 0) { /* x & (-y) == x & ~(y-1) * (-x) & y == y & ~(x-1) - * x & y == x & y */ cx = (x->size < 0); cy = (y->size < 0); @@ -6328,20 +6454,24 @@ mpz_and(mpz_t z, const mpz_t x, const mpz_t y) { fy = -cy; for (i = 0; i < yn; i++) { - mp_sub(zx, cx, x->limbs[i], cx); - mp_sub(zy, cy, y->limbs[i], cy); + mp_sub(zx, cx, xp[i], cx); + mp_sub(zy, cy, yp[i], cy); - z->limbs[i] = (zx ^ fx) & (zy ^ fy); + zp[i] = (zx ^ fx) & (zy ^ fy); } for (i = yn; i < xn; i++) { - mp_sub(zx, cx, x->limbs[i], cx); + mp_sub(zx, cx, xp[i], cx); - z->limbs[i] = (zx ^ fx) & fy; + zp[i] = (zx ^ fx) & fy; } + } else { + /* x & y == x & y */ + mpn_and_n(zp, xp, yp, yn); + zn = yn; } - zn = mpn_strip(z->limbs, zn); + zn = mpn_strip(zp, zn); z->size = (x->size & y->size) < 0 ? -zn : zn; } @@ -6361,14 +6491,13 @@ mpz_and_ui(const mpz_t x, mp_limb_t y) { void mpz_and_si(mpz_t z, const mpz_t x, mp_long_t y) { - mp_limb_t v = mp_limb_cast(y); mpz_t t; if (y < 0) { - mpz_roinit_n(t, &v, -1); + mpz_roinit_si(t, y); mpz_and(z, x, t); } else { - mpz_set_ui(z, mpz_and_ui(x, v)); + mpz_set_ui(z, mpz_and_ui(x, y)); } } @@ -6380,16 +6509,21 @@ void mpz_ior(mpz_t z, const mpz_t x, const mpz_t y) { mp_size_t xn = MP_ABS(x->size); mp_size_t yn = MP_ABS(y->size); - mp_size_t zn = MP_MAX(xn, yn); + const mp_limb_t *xp, *yp; mp_limb_t cx, cy, cz; mp_limb_t fx, fy; mp_limb_t zx, zy; - mp_size_t i; + mp_size_t i, zn; + mp_limb_t *zp; if (xn < yn) MPZ_CSWAP(x, xn, y, yn); - mpz_grow(z, zn + 1); + zn = xn; + zp = mpz_grow(z, zn + 1); + + xp = x->limbs; + yp = y->limbs; if ((x->size | y->size) < 0) { /* (-x) | (-y) == ~(x-1) | ~(y-1) @@ -6415,33 +6549,30 @@ mpz_ior(mpz_t z, const mpz_t x, const mpz_t y) { fy &= -(cx ^ cy); for (i = 0; i < yn; i++) { - mp_sub(zx, cx, x->limbs[i], cx); - mp_sub(zy, cy, y->limbs[i], cy); + mp_sub(zx, cx, xp[i], cx); + mp_sub(zy, cy, yp[i], cy); zx = (zx ^ fx) & (zy ^ fy); - mp_add(z->limbs[i], cz, zx, cz); + mp_add(zp[i], cz, zx, cz); } for (i = yn; i < xn; i++) { - mp_sub(zx, cx, x->limbs[i], cx); + mp_sub(zx, cx, xp[i], cx); zx = (zx ^ fx) & fy; - mp_add(z->limbs[i], cz, zx, cz); + mp_add(zp[i], cz, zx, cz); } - z->limbs[zn++] = cz; + zp[zn++] = cz; } else { /* x | y == x | y */ - for (i = 0; i < yn; i++) - z->limbs[i] = x->limbs[i] | y->limbs[i]; - - for (i = yn; i < xn; i++) - z->limbs[i] = x->limbs[i]; + mpn_ior_n(zp, xp, yp, yn); + mpn_copyi(zp + yn, xp + yn, xn - yn); } - zn = mpn_strip(z->limbs, zn); + zn = mpn_strip(zp, zn); z->size = (x->size | y->size) < 0 ? -zn : zn; } @@ -6451,7 +6582,7 @@ mpz_ior_ui(mpz_t z, const mpz_t x, mp_limb_t y) { mpz_t t; if (x->size < 0) { - mpz_roinit_n(t, &y, 1); + mpz_roinit_ui(t, y); mpz_ior(z, x, t); } else if (x->size == 0) { mpz_set_ui(z, y); @@ -6464,10 +6595,10 @@ mpz_ior_ui(mpz_t z, const mpz_t x, mp_limb_t y) { void mpz_ior_si(mpz_t z, const mpz_t x, mp_long_t y) { - mp_limb_t v = mp_limb_cast(y); - mp_limb_t r; - if (y < 0) { + mp_limb_t v = mp_limb_cast(y); + mp_limb_t r; + if (x->size < 0) { /* (-x) | (-y) == ~(x-1) | ~(y-1) * == ~((x-1) & (y-1)) @@ -6488,7 +6619,7 @@ mpz_ior_si(mpz_t z, const mpz_t x, mp_long_t y) { mpz_set_ui(z, r); mpz_neg(z, z); } else { - mpz_ior_ui(z, x, v); + mpz_ior_ui(z, x, y); } } @@ -6500,50 +6631,59 @@ void mpz_xor(mpz_t z, const mpz_t x, const mpz_t y) { mp_size_t xn = MP_ABS(x->size); mp_size_t yn = MP_ABS(y->size); - mp_size_t zn = MP_MAX(xn, yn); + const mp_limb_t *xp, *yp; mp_limb_t cx, cy, cz; mp_limb_t zx, zy; - mp_size_t i; + mp_size_t i, zn; + mp_limb_t *zp; if (xn < yn) MPZ_CSWAP(x, xn, y, yn); - mpz_grow(z, zn + 1); + zn = xn; + zp = mpz_grow(z, zn + 1); - /* (-x) ^ (-y) == ~(x-1) ^ ~(y-1) - * == (x-1) ^ (y-1) - * - * x ^ (-y) == x ^ ~(y-1) - * == ~(x ^ (y-1)) - * == -((x ^ (y-1)) + 1) - * - * (-x) ^ y == y ^ ~(x-1) - * == ~(y ^ (x-1)) - * == -((y ^ (x-1)) + 1) - * - * x ^ y == x ^ y - */ - cx = (x->size < 0); - cy = (y->size < 0); - cz = cx ^ cy; + xp = x->limbs; + yp = y->limbs; + + if ((x->size | y->size) < 0) { + /* (-x) ^ (-y) == ~(x-1) ^ ~(y-1) + * == (x-1) ^ (y-1) + * + * x ^ (-y) == x ^ ~(y-1) + * == ~(x ^ (y-1)) + * == -((x ^ (y-1)) + 1) + * + * (-x) ^ y == y ^ ~(x-1) + * == ~(y ^ (x-1)) + * == -((y ^ (x-1)) + 1) + */ + cx = (x->size < 0); + cy = (y->size < 0); + cz = cx ^ cy; - for (i = 0; i < yn; i++) { - mp_sub(zx, cx, x->limbs[i], cx); - mp_sub(zy, cy, y->limbs[i], cy); + for (i = 0; i < yn; i++) { + mp_sub(zx, cx, xp[i], cx); + mp_sub(zy, cy, yp[i], cy); - zx ^= zy; + zx ^= zy; - mp_add(z->limbs[i], cz, zx, cz); - } + mp_add(zp[i], cz, zx, cz); + } - for (i = yn; i < xn; i++) { - mp_sub(zx, cx, x->limbs[i], cx); - mp_add(z->limbs[i], cz, zx, cz); - } + for (i = yn; i < xn; i++) { + mp_sub(zx, cx, xp[i], cx); + mp_add(zp[i], cz, zx, cz); + } - z->limbs[zn++] = cz; + zp[zn++] = cz; + } else { + /* x ^ y == x ^ y */ + mpn_xor_n(zp, xp, yp, yn); + mpn_copyi(zp + yn, xp + yn, xn - yn); + } - zn = mpn_strip(z->limbs, zn); + zn = mpn_strip(zp, zn); z->size = (x->size ^ y->size) < 0 ? -zn : zn; } @@ -6553,7 +6693,7 @@ mpz_xor_ui(mpz_t z, const mpz_t x, mp_limb_t y) { mpz_t t; if (x->size < 0) { - mpz_roinit_n(t, &y, 1); + mpz_roinit_ui(t, y); mpz_xor(z, x, t); } else if (x->size == 0) { mpz_set_ui(z, y); @@ -6567,14 +6707,13 @@ mpz_xor_ui(mpz_t z, const mpz_t x, mp_limb_t y) { void mpz_xor_si(mpz_t z, const mpz_t x, mp_long_t y) { - mp_limb_t v = mp_limb_cast(y); mpz_t t; if (y < 0) { - mpz_roinit_n(t, &v, -1); + mpz_roinit_si(t, y); mpz_xor(z, x, t); } else { - mpz_xor_ui(z, x, v); + mpz_xor_ui(z, x, y); } } @@ -6601,7 +6740,10 @@ mpz_com(mpz_t z, const mpz_t x) { void mpz_mul_2exp(mpz_t z, const mpz_t x, mp_bits_t bits) { - mp_size_t xn, zn; + const mp_limb_t *xp; + mp_size_t xn, zn, s; + mp_limb_t *zp; + mp_bits_t r; if (x->size == 0) { z->size = 0; @@ -6613,12 +6755,23 @@ mpz_mul_2exp(mpz_t z, const mpz_t x, mp_bits_t bits) { return; } + s = bits / MP_LIMB_BITS; + r = bits % MP_LIMB_BITS; + xn = MP_ABS(x->size); - zn = xn + (bits + MP_LIMB_BITS - 1) / MP_LIMB_BITS; + zn = xn + s; - mpz_grow(z, zn); + zp = mpz_grow(z, zn + (r != 0)); + xp = x->limbs; + + if (r != 0) { + zp[zn] = mpn_lshift(zp + s, xp, xn, r); + zn += (zp[zn] != 0); + } else if (s != 0 || zp != xp) { + mpn_copyd(zp + s, xp, xn); + } - zn = mpv_lshift(z->limbs, x->limbs, xn, bits); + mpn_zero(zp, s); z->size = x->size < 0 ? -zn : zn; } @@ -6629,7 +6782,10 @@ mpz_mul_2exp(mpz_t z, const mpz_t x, mp_bits_t bits) { void mpz_quo_2exp(mpz_t z, const mpz_t x, mp_bits_t bits) { - mp_size_t xn, zn; + const mp_limb_t *xp; + mp_size_t xn, zn, s; + mp_limb_t *zp; + mp_bits_t r; if (x->size == 0) { z->size = 0; @@ -6641,30 +6797,65 @@ mpz_quo_2exp(mpz_t z, const mpz_t x, mp_bits_t bits) { return; } + s = bits / MP_LIMB_BITS; + r = bits % MP_LIMB_BITS; + xn = MP_ABS(x->size); - zn = xn; + zn = xn - s; + + if (zn <= 0) { + z->size = 0; + return; + } - mpz_grow(z, zn); + zp = mpz_grow(z, zn); + xp = x->limbs; - zn = mpv_rshift(z->limbs, x->limbs, xn, bits); + if (r != 0) { + mpn_rshift(zp, xp + s, zn, r); + zn -= (zp[zn - 1] == 0); + } else if (s != 0 || zp != xp) { + mpn_copyi(zp, xp + s, zn); + } z->size = x->size < 0 ? -zn : zn; } void mpz_rem_2exp(mpz_t z, const mpz_t x, mp_bits_t bits) { - mp_size_t xn = MP_ABS(x->size); - mp_size_t zn = xn; + const mp_limb_t *xp; + mp_size_t xn, zn; + mp_limb_t *zp; + mp_bits_t lo; + + if (x->size == 0 || bits == 0) { + z->size = 0; + return; + } - mpz_grow(z, zn); + xn = MP_ABS(x->size); + zn = (bits + MP_LIMB_BITS - 1) / MP_LIMB_BITS; + lo = bits % MP_LIMB_BITS; /* (-x) mod y == -(x & (y-1)) * * x mod y == x & (y-1) */ - mpn_mask(z->limbs, x->limbs, xn, bits); + if (zn > xn) { + zn = xn; + lo = 0; + } + + zp = mpz_grow(z, zn); + xp = x->limbs; + + if (zp != xp) + mpn_copyi(zp, xp, zn); + + if (lo != 0) + zp[zn - 1] &= MP_MASK(lo); - zn = mpn_strip(z->limbs, zn); + zn = mpn_strip(zp, zn); z->size = x->size < 0 ? -zn : zn; } @@ -6693,38 +6884,53 @@ mpz_div_2exp(mpz_t z, const mpz_t x, mp_bits_t bits) { void mpz_mod_2exp(mpz_t z, const mpz_t x, mp_bits_t bits) { - mp_size_t zn = (bits + MP_LIMB_BITS - 1) / MP_LIMB_BITS; - mp_size_t xn = MP_ABS(x->size); - mp_size_t mn = MP_MIN(xn, zn); - mp_limb_t cx, fx, zx; + const mp_limb_t *xp; + mp_size_t xn, zn; + mp_limb_t *zp; mp_bits_t lo; - mp_size_t i; - mpz_grow(z, zn); + if (x->size == 0 || bits == 0) { + z->size = 0; + return; + } + + xn = MP_ABS(x->size); + zn = (bits + MP_LIMB_BITS - 1) / MP_LIMB_BITS; + lo = bits % MP_LIMB_BITS; - /* (-x) mod y == (-x) & (y-1) - * == (y-1) & ~(x-1) - * - * x mod y == x & (y-1) - */ - cx = (x->size < 0); - fx = -cx; + if (x->size < 0) { + /* (-x) mod y == (-x) & (y-1) + * == (y-1) & ~(x-1) + */ + zp = mpz_grow(z, zn); + xp = x->limbs; - for (i = 0; i < mn; i++) { - mp_sub(zx, cx, x->limbs[i], cx); + if (zn > xn) { + mpn_sub_1(zp, xp, xn, 1); + mpn_zero(zp + xn, zn - xn); + } else { + mpn_sub_1(zp, xp, zn, 1); + } - z->limbs[i] = zx ^ fx; - } + mpn_com(zp, zp, zn); + } else { + /* x mod y == x & (y-1) */ + if (zn > xn) { + zn = xn; + lo = 0; + } - for (i = xn; i < zn; i++) - z->limbs[i] = fx; + zp = mpz_grow(z, zn); + xp = x->limbs; - lo = bits % MP_LIMB_BITS; + if (zp != xp) + mpn_copyi(zp, xp, zn); + } if (lo != 0) - z->limbs[zn - 1] &= MP_MASK(lo); + zp[zn - 1] &= MP_MASK(lo); - z->size = mpn_strip(z->limbs, zn); + z->size = mpn_strip(zp, zn); } /* @@ -6752,17 +6958,18 @@ mpz_setbit_abs(mpz_t z, mp_bits_t pos) { mp_size_t s = pos / MP_LIMB_BITS; mp_bits_t r = pos % MP_LIMB_BITS; mp_size_t zn = MP_ABS(z->size); + mp_limb_t *zp = z->limbs; if (zn < s + 1) { - mpz_grow(z, s + 1); + zp = mpz_grow(z, s + 1); while (zn < s + 1) - z->limbs[zn++] = 0; + zp[zn++] = 0; z->size = z->size < 0 ? -zn : zn; } - z->limbs[s] |= MP_LIMB_C(1) << r; + zp[s] |= MP_LIMB_C(1) << r; } static void @@ -6770,11 +6977,12 @@ mpz_clrbit_abs(mpz_t z, mp_bits_t pos) { mp_size_t s = pos / MP_LIMB_BITS; mp_bits_t r = pos % MP_LIMB_BITS; mp_size_t zn = MP_ABS(z->size); + mp_limb_t *zp = z->limbs; if (s < zn) { - z->limbs[s] &= ~(MP_LIMB_C(1) << r); + zp[s] &= ~(MP_LIMB_C(1) << r); - zn = mpn_strip(z->limbs, zn); + zn = mpn_strip(zp, zn); z->size = z->size < 0 ? -zn : zn; } @@ -6844,37 +7052,43 @@ mpz_popcount(const mpz_t x) { mp_bits_t mpz_hamdist(const mpz_t x, const mpz_t y) { - mp_size_t xn = MP_ABS(x->size); - mp_size_t yn = MP_ABS(y->size); + const mp_limb_t *xp, *yp; + mp_size_t i, xn, yn; mp_bits_t cnt = 0; mp_limb_t cx, cy; - mp_limb_t fx, fy; mp_limb_t zx, zy; - mp_size_t i; if ((x->size ^ y->size) < 0) return MP_BITS_MAX; + xn = MP_ABS(x->size); + yn = MP_ABS(y->size); + if (xn < yn) MPZ_CSWAP(x, xn, y, yn); - cx = (x->size < 0); - cy = (y->size < 0); + xp = x->limbs; + yp = y->limbs; - fx = -cx; - fy = -cy; + if (x->size < 0) { + cx = 1; + cy = 1; - for (i = 0; i < yn; i++) { - mp_sub(zx, cx, x->limbs[i], cx); - mp_sub(zy, cy, y->limbs[i], cy); + for (i = 0; i < yn; i++) { + mp_sub(zx, cx, xp[i], cx); + mp_sub(zy, cy, yp[i], cy); - cnt += mp_popcount((zx ^ fx) ^ (zy ^ fy)); - } + cnt += mp_popcount(zx ^ zy); + } - for (i = yn; i < xn; i++) { - mp_sub(zx, cx, x->limbs[i], cx); + for (i = yn; i < xn; i++) { + mp_sub(zx, cx, xp[i], cx); - cnt += mp_popcount((zx ^ fx) ^ fy); + cnt += mp_popcount(zx); + } + } else { + cnt += mpn_hamdist(xp, yp, yn); + cnt += mpn_popcount(xp + yn, xn - yn); } return cnt; @@ -6903,7 +7117,7 @@ mpz_neg(mpz_t z, const mpz_t x) { void mpz_gcd(mpz_t z, const mpz_t x, const mpz_t y) { mp_size_t xn, yn, zn, itch; - mp_limb_t *scratch; + mp_limb_t *zp, *scratch; if (x->size == 0) { mpz_abs(z, y); @@ -6922,15 +7136,14 @@ mpz_gcd(mpz_t z, const mpz_t x, const mpz_t y) { MPZ_CSWAP(x, xn, y, yn); zn = yn; + zp = mpz_grow(z, zn); itch = MPN_GCD_ITCH(xn, yn); scratch = mp_alloc_vla(itch); - mpz_grow(z, zn); - - zn = mpn_gcd(z->limbs, x->limbs, xn, - y->limbs, yn, - scratch); + zn = mpn_gcd(zp, x->limbs, xn, + y->limbs, yn, + scratch); mp_free_vla(scratch, itch); @@ -7138,17 +7351,16 @@ static int mpz_invert_inner(mpz_t z, const mpz_t x, const mpz_t y) { mp_size_t xn = MP_ABS(x->size); mp_size_t yn = MP_ABS(y->size); + mp_limb_t *zp = mpz_grow(z, yn); mp_size_t itch = MPN_INVERT_ITCH(yn); mp_limb_t *scratch = mp_alloc_vla(itch); int ret; - mpz_grow(z, yn); + ret = mpn_invert(zp, x->limbs, xn, + y->limbs, yn, + scratch); - ret = mpn_invert(z->limbs, x->limbs, xn, - y->limbs, yn, - scratch); - - z->size = mpn_strip(z->limbs, yn); + z->size = mpn_strip(zp, yn); mp_free_vla(scratch, itch); @@ -7255,7 +7467,7 @@ int mpz_kronecker(const mpz_t x, const mpz_t y) { static const int table[8] = {0, 1, 0, -1, 0, -1, 0, 1}; mp_bits_t bits; - mpz_t v; + mpz_t t; int k; if (x->size == 0) @@ -7269,15 +7481,19 @@ mpz_kronecker(const mpz_t x, const mpz_t y) { bits = mpz_ctz(y); - mpz_init_vla(v, MP_ABS(y->size)); - mpz_quo_2exp(v, y, bits); + if (bits > 0) { + mpz_init_vla(t, MP_ABS(y->size)); + mpz_quo_2exp(t, y, bits); - k = mpz_jacobi(x, v); + k = mpz_jacobi(x, t); - if (bits & 1) - k *= table[x->limbs[0] & 7]; + if (bits & 1) + k *= table[x->limbs[0] & 7]; - mpz_clear_vla(v); + mpz_clear_vla(t); + } else { + k = mpz_jacobi(x, y); + } return k; } @@ -7286,17 +7502,16 @@ int mpz_kronecker_ui(const mpz_t x, mp_limb_t y) { mpz_t t; - mpz_roinit_n(t, &y, 1); + mpz_roinit_ui(t, y); return mpz_kronecker(x, t); } int mpz_kronecker_si(const mpz_t x, mp_long_t y) { - mp_limb_t v = mp_limb_cast(y); mpz_t t; - mpz_roinit_n(t, &v, y < 0 ? -1 : 1); + mpz_roinit_si(t, y); return mpz_kronecker(x, t); } @@ -7305,17 +7520,16 @@ int mpz_ui_kronecker(mp_limb_t x, const mpz_t y) { mpz_t t; - mpz_roinit_n(t, &x, 1); + mpz_roinit_ui(t, x); return mpz_kronecker(t, y); } int mpz_si_kronecker(mp_long_t x, const mpz_t y) { - mp_limb_t u = mp_limb_cast(x); mpz_t t; - mpz_roinit_n(t, &u, x < 0 ? -1 : 1); + mpz_roinit_si(t, x); return mpz_kronecker(t, y); } @@ -7325,17 +7539,16 @@ mpz_powm_inner(mpz_t z, const mpz_t x, const mpz_t y, const mpz_t m) { mp_size_t xn = MP_ABS(x->size); mp_size_t yn = MP_ABS(y->size); mp_size_t mn = MP_ABS(m->size); + mp_limb_t *zp = mpz_grow(z, mn); mp_size_t itch = MPN_POWM_ITCH(yn, mn); mp_limb_t *scratch = mp_alloc_limbs(itch); - mpz_grow(z, mn); + mpn_powm(zp, x->limbs, xn, + y->limbs, yn, + m->limbs, mn, + scratch); - mpn_powm(z->limbs, x->limbs, xn, - y->limbs, yn, - m->limbs, mn, - scratch); - - z->size = mpn_strip(z->limbs, mn); + z->size = mpn_strip(zp, mn); mp_free_limbs(scratch); } @@ -7367,10 +7580,10 @@ mpz_powm(mpz_t z, const mpz_t x, const mpz_t y, const mpz_t m) { void mpz_powm_ui(mpz_t z, const mpz_t x, mp_limb_t y, const mpz_t m) { - mpz_t v; + mpz_t t; - mpz_roinit_n(v, &y, 1); - mpz_powm(z, x, v, m); + mpz_roinit_ui(t, y); + mpz_powm(z, x, t, m); } static void @@ -7378,17 +7591,16 @@ mpz_powm_sec_inner(mpz_t z, const mpz_t x, const mpz_t y, const mpz_t m) { mp_size_t xn = MP_ABS(x->size); mp_size_t yn = MP_ABS(y->size); mp_size_t mn = MP_ABS(m->size); + mp_limb_t *zp = mpz_grow(z, mn); mp_size_t itch = MPN_SEC_POWM_ITCH(mn); mp_limb_t *scratch = mp_alloc_limbs(itch); - mpz_grow(z, mn); + mpn_sec_powm(zp, x->limbs, xn, + y->limbs, yn, + m->limbs, mn, + scratch); - mpn_sec_powm(z->limbs, x->limbs, xn, - y->limbs, yn, - m->limbs, mn, - scratch); - - z->size = mpn_strip(z->limbs, mn); + z->size = mpn_strip(zp, mn); mp_free_limbs(scratch); } @@ -7706,15 +7918,44 @@ mpz_sqrtpq(mpz_t z, const mpz_t x, const mpz_t p, const mpz_t q) { mp_bits_t mpz_remove(mpz_t z, const mpz_t x, const mpz_t y) { - mp_bits_t cnt = 0; - mpz_t q, r, n; + mp_size_t xn = MP_ABS(x->size); + mp_size_t yn = MP_ABS(y->size); + mp_bits_t c = 0; + mp_bits_t b, s; + mpz_t n, q, r; + mp_limb_t w; - if (y->size == 0) + if (yn == 0) torsion_abort(); /* LCOV_EXCL_LINE */ - mpz_init(q); - mpz_init(r); - mpz_init(n); + w = y->limbs[0]; + + if (xn == 0 || (yn == 1 && w == 1)) { + if (z != NULL) + mpz_set(z, x); + + return 0; + } + + if (yn == 1 && (w & (w - 1)) == 0) { + b = mp_bitlen(w - 1); + c = mpz_ctz(x) / b; + + if (z != NULL) { + s = (y->size < 0); + + mpz_quo_2exp(z, x, c * b); + + if (c & s) + mpz_neg(z, z); + } + + return c; + } + + mpz_init_vla(n, xn); + mpz_init_vla(q, xn); + mpz_init_vla(r, yn); mpz_set(n, x); @@ -7726,17 +7967,17 @@ mpz_remove(mpz_t z, const mpz_t x, const mpz_t y) { mpz_swap(n, q); - cnt += 1; + c += 1; } if (z != NULL) - mpz_swap(z, n); + mpz_set(z, n); - mpz_clear(q); - mpz_clear(r); - mpz_clear(n); + mpz_clear_vla(n); + mpz_clear_vla(q); + mpz_clear_vla(r); - return cnt; + return c; } void @@ -7751,20 +7992,26 @@ mpz_2fac_ui(mpz_t z, mp_limb_t n) { void mpz_mfac_uiui(mpz_t z, mp_limb_t n, mp_limb_t m) { - mp_limb_t i; + if (n == 0) { + mpz_set_ui(z, 1); + return; + } - CHECK(m != 0); - CHECK(n <= MP_LIMB_MAX - m); + mpz_set_ui(z, n); - mpz_set_ui(z, 1); + if (m == 0) + return; - for (i = 1; i <= n; i += m) - mpz_mul_ui(z, z, i); + while (n > m) { + n -= m; + mpz_mul_ui(z, z, n); + } } void mpz_primorial_ui(mpz_t z, mp_limb_t n) { - mp_limb_t *sieve; + mp_limb_t *sp; + mp_size_t sn; mp_limb_t p; if (n < 2) { @@ -7772,16 +8019,19 @@ mpz_primorial_ui(mpz_t z, mp_limb_t n) { return; } - sieve = mp_eratosthenes(n); + sn = mpn_sieve_size(n); + sp = mp_alloc_vla(sn); + + mpn_sieve(sp, n); mpz_set_ui(z, 2); for (p = 3; p <= n; p += 2) { - if (mpn_tstbit(sieve, p)) + if (mpn_tstbit(sp, p)) mpz_mul_ui(z, z, p); } - mp_free_limbs(sieve); + mp_free_vla(sp, sn); } void @@ -7853,57 +8103,122 @@ mpz_bin_uiui(mpz_t z, mp_limb_t n, mp_limb_t k) { } } -static void -mpz_fibonacci(mpz_t z, mpz_t p, mp_limb_t n, mp_limb_t f0, mp_limb_t f1) { - mpz_t a, b, c; - mp_limb_t i; +void +mpz_bin_siui(mpz_t z, mp_long_t n, mp_limb_t k) { + if (n < 0) { + /* bin(-n, k) = (-1)^k * bin(n + k - 1, k) */ + mp_limb_t m = mp_limb_cast(n); + mpz_t t; + + if (UNLIKELY(m + k < k)) { + mpz_roset_n(t, &m, -1); + mpz_bin_ui(z, t, k); + } else { + mpz_bin_uiui(z, m + k - 1, k); + + if (k & 1) + mpz_neg(z, z); + } + } else { + mpz_bin_uiui(z, n, k); + } +} + +void +mpz_fib_ui(mpz_t fn, mp_limb_t n) { + mpz_fib2_ui(fn, NULL, n); +} + +void +mpz_fib2_ui(mpz_t fn, mpz_t fn1, mp_limb_t n) { + mpz_t a, b, c, d, t; + mp_bits_t i; + + if (n == 0) { + if (fn1 != NULL) + fn1->size = 0; + + fn->size = 0; + + return; + } mpz_init(a); mpz_init(b); mpz_init(c); + mpz_init(d); + mpz_init(t); - if (n == 0) { - mpz_set_ui(a, 0); - mpz_set_ui(b, f0); - } else { - mpz_set_ui(a, f0); - mpz_set_ui(b, f1); - } + mpz_set_ui(a, 0); + mpz_set_ui(b, 1); - for (i = 1; i < n; i++) { - mpz_add(c, a, b); - mpz_swap(a, b); - mpz_swap(b, c); + n -= 1; + + for (i = mp_bitlen(n) - 1; i >= 0; i--) { + mpz_add(t, b, b); + mpz_sub(t, t, a); + mpz_mul(c, a, t); + + mpz_sqr(d, a); + mpz_sqr(t, b); + mpz_add(d, d, t); + + if ((n >> i) & 1) { + mpz_add(b, c, d); + mpz_swap(a, d); + } else { + mpz_swap(a, c); + mpz_swap(b, d); + } } - if (p != NULL) - mpz_swap(p, a); + if (fn1 != NULL) + mpz_swap(fn1, a); - mpz_swap(z, b); + mpz_swap(fn, b); mpz_clear(a); mpz_clear(b); mpz_clear(c); + mpz_clear(d); + mpz_clear(t); } void -mpz_fib_ui(mpz_t z, mp_limb_t n) { - mpz_fibonacci(z, NULL, n, 0, 1); +mpz_lucnum_ui(mpz_t ln, mp_limb_t n) { + mpz_lucnum2_ui(ln, NULL, n); } void -mpz_fib2_ui(mpz_t z, mpz_t p, mp_limb_t n) { - mpz_fibonacci(z, p, n, 0, 1); -} +mpz_lucnum2_ui(mpz_t ln, mpz_t ln1, mp_limb_t n) { + mpz_t fn, fn1; -void -mpz_lucnum_ui(mpz_t z, mp_limb_t n) { - mpz_fibonacci(z, NULL, n, 2, 1); -} + if (n == 0) { + if (ln1 != NULL) + ln1->size = 0; -void -mpz_lucnum2_ui(mpz_t z, mpz_t p, mp_limb_t n) { - mpz_fibonacci(z, p, n, 2, 1); + mpz_set_ui(ln, 2); + + return; + } + + mpz_init(fn); + mpz_init(fn1); + + mpz_fib2_ui(fn, fn1, n); + + if (ln1 != NULL) { + /* L[n-1] = 2*F[n] - F[n-1] */ + mpz_add(ln1, fn, fn); + mpz_sub(ln1, ln1, fn1); + } + + /* L[n] = F[n] + 2*F[n-1] */ + mpz_add(ln, fn1, fn1); + mpz_add(ln, ln, fn); + + mpz_clear(fn); + mpz_clear(fn1); } /* @@ -8204,25 +8519,21 @@ mpz_probab_prime_p(const mpz_t x, int rounds, mp_rng_f *rng, void *arg) { * * [BPSW] "Bibliography". */ - /* First 18 primes in a mask (2-61). */ - static const mp_limb_t primes_lo = MP_LIMB_C(0xa08a28ac); - static const mp_limb_t primes_hi = MP_LIMB_C(0x28208a20); mp_limb_t ra, rb; + /* No negatives. */ if (x->size <= 0) return 0; - if (x->size == 1) { - if (x->limbs[0] < 32) - return (primes_lo >> x->limbs[0]) & 1; - - if (x->limbs[0] < 64) - return (primes_hi >> (x->limbs[0] - 32)) & 1; - } + /* Check small primes list. */ + if (x->size == 1 && x->limbs[0] < 1024) + return mpn_tstbit(mp_primes, x->limbs[0]); + /* No even numbers. */ if ((x->limbs[0] & 1) == 0) return 0; + /* Trial division. */ mpz_mod_primorial(&ra, &rb, x); if (ra % 3 == 0 @@ -8243,9 +8554,11 @@ mpz_probab_prime_p(const mpz_t x, int rounds, mp_rng_f *rng, void *arg) { return 0; } + /* Miller-Rabin primality test. */ if (!mpz_mr_prime_p(x, rounds + 1, 1, rng, arg)) return 0; + /* Lucas primality test. */ if (!mpz_lucas_prime_p(x, 0)) return 0; @@ -8318,12 +8631,7 @@ mpz_nextprime(mpz_t z, const mpz_t x, mp_rng_f *rng, void *arg) { return; } - mpz_set(z, x); - - if (mpz_even_p(z)) - mpz_add_ui(z, z, 1); - else - mpz_add_ui(z, z, 2); + mpz_add_ui(z, x, 1 + mpz_odd_p(x)); while (!mpz_probab_prime_p(z, 20, rng, arg)) mpz_add_ui(z, z, 2); @@ -8450,7 +8758,7 @@ _mpz_realloc(mpz_t z, mp_size_t n) { mpz_grow(z, n); } - return NULL; + return z->limbs; } void @@ -8470,7 +8778,7 @@ mpz_getlimbn(const mpz_t x, mp_size_t n) { return x->limbs[n]; } -mp_size_t +size_t mpz_size(const mpz_t x) { return MP_ABS(x->size); } @@ -8492,8 +8800,7 @@ mpz_limbs_write(mpz_t z, mp_size_t n) { mp_limb_t * mpz_limbs_modify(mpz_t z, mp_size_t n) { - mpz_grow(z, n); - return z->limbs; + return mpz_grow(z, n); } void @@ -8510,17 +8817,18 @@ mpz_limbs_finish(mpz_t z, mp_size_t n) { void mpz_import(mpz_t z, const unsigned char *raw, size_t size, int endian) { mp_size_t zn = mp_size_cast((size + MP_LIMB_BYTES - 1) / MP_LIMB_BYTES); + mp_limb_t *zp; if (zn == 0) { z->size = 0; return; } - mpz_grow(z, zn); + zp = mpz_grow(z, zn); - mpn_import(z->limbs, zn, raw, size, endian); + mpn_import(zp, zn, raw, size, endian); - z->size = mpn_strip(z->limbs, zn); + z->size = mpn_strip(zp, zn); } /* @@ -8539,6 +8847,7 @@ mpz_export(unsigned char *raw, const mpz_t x, size_t size, int endian) { int mpz_set_str(mpz_t z, const char *str, int base) { + mp_limb_t *zp; mp_size_t zn; int neg = 0; @@ -8583,15 +8892,14 @@ mpz_set_str(mpz_t z, const char *str, int base) { } zn = mp_str_limbs(str, base); + zp = mpz_grow(z, zn); - mpz_grow(z, zn); - - if (!mpn_set_str(z->limbs, zn, str, base)) { + if (!mpn_set_str(zp, zn, str, base)) { z->size = 0; return 0; } - zn = mpn_strip(z->limbs, zn); + zn = mpn_strip(zp, zn); z->size = neg ? -zn : zn; @@ -8636,33 +8944,38 @@ void mpz_urandomb(mpz_t z, mp_bits_t bits, mp_rng_f *rng, void *arg) { mp_size_t zn = (bits + MP_LIMB_BITS - 1) / MP_LIMB_BITS; mp_bits_t lo = bits % MP_LIMB_BITS; + mp_limb_t *zp = mpz_grow(z, zn); - mpz_grow(z, zn); - - mpn_random(z->limbs, zn, rng, arg); + mpn_random(zp, zn, rng, arg); if (lo != 0) - z->limbs[zn - 1] &= MP_MASK(lo); + zp[zn - 1] &= MP_MASK(lo); - z->size = mpn_strip(z->limbs, zn); + z->size = mpn_strip(zp, zn); } void mpz_urandomm(mpz_t z, const mpz_t x, mp_rng_f *rng, void *arg) { - mp_bits_t bits = mpz_bitlen(x); - - CHECK(z != x); + mp_size_t xn, zn; + mp_limb_t *zp; - if (bits > 0) { - do { - mpz_urandomb(z, bits, rng, arg); - } while (mpz_cmpabs(z, x) >= 0); + if (z == x) + torsion_abort(); /* LCOV_EXCL_LINE */ - if (x->size < 0) - mpz_neg(z, z); - } else { + if (x->size == 0) { z->size = 0; + return; } + + xn = MP_ABS(x->size); + zn = xn; + zp = mpz_grow(z, zn); + + mpn_randomm(zp, x->limbs, xn, rng, arg); + + zn = mpn_strip(zp, zn); + + z->size = x->size < 0 ? -zn : zn; } /* @@ -8677,6 +8990,7 @@ test_mpi_internal(mp_rng_f *rng, void *arg) { (void)rng; (void)arg; } + void bench_mpi_internal(mp_start_f *start, mp_end_f *end, mp_rng_f *rng, void *arg) { (void)start; diff --git a/node_modules/bcrypto/deps/torsion/src/mpi.h b/node_modules/bcrypto/deps/torsion/src/mpi.h index 9762d679a..b483bd89d 100644 --- a/node_modules/bcrypto/deps/torsion/src/mpi.h +++ b/node_modules/bcrypto/deps/torsion/src/mpi.h @@ -6,8 +6,8 @@ * A from-scratch reimplementation of GMP. */ -#ifndef _TORSION_MPI_H -#define _TORSION_MPI_H +#ifndef TORSION_MPI_H +#define TORSION_MPI_H #include #include @@ -18,259 +18,264 @@ * Symbol Aliases */ -#define mp_alloc_limbs __torsion_mp_alloc_limbs -#define mp_realloc_limbs __torsion_mp_realloc_limbs -#define mp_free_limbs __torsion_mp_free_limbs -#define mpn_zero __torsion_mpn_zero -#define mpn_cleanse __torsion_mpn_cleanse -#define mpn_set_1 __torsion_mpn_set_1 -#define mpn_copyi __torsion_mpn_copyi -#define mpn_copyd __torsion_mpn_copyd -#define mpn_zero_p __torsion_mpn_zero_p -#define mpn_cmp __torsion_mpn_cmp -#define mpn_add_1 __torsion_mpn_add_1 -#define mpn_add_n __torsion_mpn_add_n -#define mpn_add __torsion_mpn_add -#define mpn_sub_1 __torsion_mpn_sub_1 -#define mpn_sub_n __torsion_mpn_sub_n -#define mpn_sub __torsion_mpn_sub -#define mpn_mul_1 __torsion_mpn_mul_1 -#define mpn_addmul_1 __torsion_mpn_addmul_1 -#define mpn_submul_1 __torsion_mpn_submul_1 -#define mpn_mul_n __torsion_mpn_mul_n -#define mpn_mul __torsion_mpn_mul -#define mpn_sqr __torsion_mpn_sqr -#define mpn_mulshift __torsion_mpn_mulshift -#define mpn_reduce_weak __torsion_mpn_reduce_weak -#define mpn_barrett __torsion_mpn_barrett -#define mpn_reduce __torsion_mpn_reduce -#define mpn_mont __torsion_mpn_mont -#define mpn_montmul __torsion_mpn_montmul -#define mpn_montmul_var __torsion_mpn_montmul_var -#define mpn_divmod_1 __torsion_mpn_divmod_1 -#define mpn_div_1 __torsion_mpn_div_1 -#define mpn_mod_1 __torsion_mpn_mod_1 -#define mpn_divmod __torsion_mpn_divmod -#define mpn_div __torsion_mpn_div -#define mpn_mod __torsion_mpn_mod -#define mpn_divexact_1 __torsion_mpn_divexact_1 -#define mpn_divexact __torsion_mpn_divexact -#define mpn_divround_1 __torsion_mpn_divround_1 -#define mpn_divround __torsion_mpn_divround -#define mpn_and_n __torsion_mpn_and_n -#define mpn_ior_n __torsion_mpn_ior_n -#define mpn_xor_n __torsion_mpn_xor_n -#define mpn_andn_n __torsion_mpn_andn_n -#define mpn_iorn_n __torsion_mpn_iorn_n -#define mpn_nand_n __torsion_mpn_nand_n -#define mpn_nior_n __torsion_mpn_nior_n -#define mpn_nxor_n __torsion_mpn_nxor_n -#define mpn_com __torsion_mpn_com -#define mpn_lshift __torsion_mpn_lshift -#define mpn_rshift __torsion_mpn_rshift -#define mpn_getbit __torsion_mpn_getbit -#define mpn_getbits __torsion_mpn_getbits -#define mpn_tstbit __torsion_mpn_tstbit -#define mpn_setbit __torsion_mpn_setbit -#define mpn_clrbit __torsion_mpn_clrbit -#define mpn_combit __torsion_mpn_combit -#define mpn_scan0 __torsion_mpn_scan0 -#define mpn_scan1 __torsion_mpn_scan1 -#define mpn_popcount __torsion_mpn_popcount -#define mpn_hamdist __torsion_mpn_hamdist -#define mpn_mask __torsion_mask -#define mpn_neg __torsion_mpn_neg -#define mpn_gcd __torsion_mpn_gcd -#define mpn_gcd_1 __torsion_mpn_gcd_1 -#define mpn_invert __torsion_mpn_invert -#define mpn_invert_n __torsion_mpn_invert_n -#define mpn_jacobi __torsion_mpn_jacobi -#define mpn_jacobi_n __torsion_mpn_jacobi_n -#define mpn_powm __torsion_mpn_powm -#define mpn_sec_powm __torsion_mpn_sec_powm -#define mpn_strip __torsion_mpn_strip -#define mpn_odd_p __torsion_mpn_odd_p -#define mpn_even_p __torsion_mpn_even_p -#define mpn_ctz __torsion_mpn_ctz -#define mpn_bitlen __torsion_mpn_bitlen -#define mpn_bytelen __torsion_mpn_bytelen -#define mpn_sizeinbase __torsion_mpn_sizeinbase -#define mpn_select __torsion_mpn_select -#define mpn_select_zero __torsion_mpn_select_zero -#define mpn_sec_zero_p __torsion_mpn_sec_zero_p -#define mpn_sec_equal_p __torsion_mpn_sec_equal_p -#define mpn_sec_lt_p __torsion_mpn_sec_lt_p -#define mpn_sec_lte_p __torsion_mpn_sec_lte_p -#define mpn_sec_gt_p __torsion_mpn_sec_gt_p -#define mpn_sec_gte_p __torsion_mpn_sec_gte_p -#define mpn_sec_cmp __torsion_mpn_sec_cmp -#define mpn_import __torsion_mpn_import -#define mpn_export __torsion_mpn_export -#define mpn_set_str __torsion_mpn_set_str -#define mpn_get_str __torsion_mpn_get_str -#define mpn_print __torsion_mpn_print -#define mpn_random __torsion_mpn_random -#define mpz_init __torsion_mpz_init -#define mpz_init2 __torsion_mpz_init2 -#define mpz_init_set __torsion_mpz_init_set -#define mpz_init_set_ui __torsion_mpz_init_set_ui -#define mpz_init_set_si __torsion_mpz_init_set_si -#define mpz_init_set_str __torsion_mpz_init_set_str -#define mpz_clear __torsion_mpz_clear -#define mpz_cleanse __torsion_mpz_cleanse -#define mpz_set __torsion_mpz_set -#define mpz_roset __torsion_mpz_roset -#define mpz_roinit_n __torsion_mpz_roinit_n -#define mpz_set_ui __torsion_mpz_set_ui -#define mpz_set_si __torsion_mpz_set_si -#define mpz_get_ui __torsion_mpz_get_ui -#define mpz_get_si __torsion_mpz_get_si -#define mpz_sgn __torsion_mpz_sgn -#define mpz_cmp __torsion_mpz_cmp -#define mpz_cmp_ui __torsion_mpz_cmp_ui -#define mpz_cmp_si __torsion_mpz_cmp_si -#define mpz_cmpabs __torsion_mpz_cmpabs -#define mpz_cmpabs_ui __torsion_mpz_cmpabs_ui -#define mpz_cmpabs_si __torsion_mpz_cmpabs_si -#define mpz_add __torsion_mpz_add -#define mpz_add_ui __torsion_mpz_add_ui -#define mpz_add_si __torsion_mpz_add_si -#define mpz_sub __torsion_mpz_sub -#define mpz_sub_ui __torsion_mpz_sub_ui -#define mpz_sub_si __torsion_mpz_sub_si -#define mpz_ui_sub __torsion_mpz_ui_sub -#define mpz_si_sub __torsion_mpz_si_sub -#define mpz_mul __torsion_mpz_mul -#define mpz_mul_ui __torsion_mpz_mul_ui -#define mpz_mul_si __torsion_mpz_mul_si -#define mpz_sqr __torsion_mpz_sqr -#define mpz_addmul __torsion_mpz_addmul -#define mpz_addmul_ui __torsion_mpz_addmul_ui -#define mpz_addmul_si __torsion_mpz_addmul_si -#define mpz_submul __torsion_mpz_submul -#define mpz_submul_ui __torsion_mpz_submul_ui -#define mpz_submul_si __torsion_mpz_submul_si -#define mpz_mulshift __torsion_mpz_mulshift -#define mpz_quorem __torsion_mpz_quorem -#define mpz_quo __torsion_mpz_quo -#define mpz_rem __torsion_mpz_rem -#define mpz_quo_ui __torsion_mpz_quo_ui -#define mpz_rem_ui __torsion_mpz_rem_ui -#define mpz_quo_si __torsion_mpz_quo_si -#define mpz_rem_si __torsion_mpz_rem_si -#define mpz_divmod __torsion_mpz_divmod -#define mpz_div __torsion_mpz_div -#define mpz_mod __torsion_mpz_mod -#define mpz_div_ui __torsion_mpz_div_ui -#define mpz_mod_ui __torsion_mpz_mod_ui -#define mpz_div_si __torsion_mpz_div_si -#define mpz_mod_si __torsion_mpz_mod_si -#define mpz_divexact __torsion_mpz_divexact -#define mpz_divexact_ui __torsion_mpz_divexact_ui -#define mpz_divexact_si __torsion_mpz_divexact_si -#define mpz_divround __torsion_mpz_divround -#define mpz_divround_ui __torsion_mpz_divround_ui -#define mpz_divround_si __torsion_mpz_divround_si -#define mpz_divisible_p __torsion_mpz_divisible_p -#define mpz_divisible_ui_p __torsion_mpz_divisible_ui_p -#define mpz_divisible_2exp_p __torsion_mpz_divisible_2exp_p -#define mpz_congruent_p __torsion_mpz_congruent_p -#define mpz_congruent_ui_p __torsion_mpz_congruent_ui_p -#define mpz_congruent_2exp_p __torsion_mpz_congruent_2exp_p -#define mpz_pow_ui __torsion_mpz_pow_ui -#define mpz_ui_pow_ui __torsion_mpz_ui_pow_ui -#define mpz_rootrem __torsion_mpz_rootrem -#define mpz_root __torsion_mpz_root -#define mpz_perfect_power_p __torsion_mpz_perfect_power_p -#define mpz_sqrtrem __torsion_mpz_sqrtrem -#define mpz_sqrt __torsion_mpz_sqrt -#define mpz_perfect_square_p __torsion_mpz_perfect_square_p -#define mpz_and __torsion_mpz_and -#define mpz_and_ui __torsion_mpz_and_ui -#define mpz_and_si __torsion_mpz_and_si -#define mpz_ior __torsion_mpz_ior -#define mpz_ior_ui __torsion_mpz_ior_ui -#define mpz_ior_si __torsion_mpz_ior_si -#define mpz_xor __torsion_mpz_xor -#define mpz_xor_ui __torsion_mpz_xor_ui -#define mpz_xor_si __torsion_mpz_xor_si -#define mpz_com __torsion_mpz_com -#define mpz_mul_2exp __torsion_mpz_mul_2exp -#define mpz_quo_2exp __torsion_mpz_quo_2exp -#define mpz_rem_2exp __torsion_mpz_rem_2exp -#define mpz_div_2exp __torsion_mpz_div_2exp -#define mpz_mod_2exp __torsion_mpz_mod_2exp -#define mpz_tstbit __torsion_mpz_tstbit -#define mpz_setbit __torsion_mpz_setbit -#define mpz_clrbit __torsion_mpz_clrbit -#define mpz_combit __torsion_mpz_combit -#define mpz_scan0 __torsion_mpz_scan0 -#define mpz_scan1 __torsion_mpz_scan1 -#define mpz_popcount __torsion_mpz_popcount -#define mpz_hamdist __torsion_mpz_hamdist -#define mpz_abs __torsion_mpz_abs -#define mpz_neg __torsion_mpz_neg -#define mpz_gcd __torsion_mpz_gcd -#define mpz_gcd_ui __torsion_mpz_gcd_ui -#define mpz_lcm __torsion_mpz_lcm -#define mpz_lcm_ui __torsion_mpz_lcm_ui -#define mpz_gcdext __torsion_mpz_gcdext -#define mpz_invert __torsion_mpz_invert -#define mpz_legendre __torsion_mpz_legendre -#define mpz_jacobi __torsion_mpz_jacobi -#define mpz_kronecker __torsion_mpz_kronecker -#define mpz_kronecker_ui __torsion_mpz_kronecker_ui -#define mpz_kronecker_si __torsion_mpz_kronecker_si -#define mpz_ui_kronecker __torsion_mpz_ui_kronecker -#define mpz_si_kronecker __torsion_mpz_si_kronecker -#define mpz_powm __torsion_mpz_powm -#define mpz_powm_ui __torsion_mpz_powm_ui -#define mpz_powm_sec __torsion_mpz_powm_sec -#define mpz_sqrtm __torsion_mpz_sqrtm -#define mpz_sqrtpq __torsion_mpz_sqrtpq -#define mpz_remove __torsion_mpz_remove -#define mpz_fac_ui __torsion_mpz_fac_ui -#define mpz_2fac_ui __torsion_mpz_2fac_ui -#define mpz_mfac_uiui __torsion_mpz_mfac_uiui -#define mpz_primorial_ui __torsion_mpz_primorial_ui -#define mpz_bin_ui __torsion_mpz_bin_ui -#define mpz_bin_uiui __torsion_mpz_bin_uiui -#define mpz_fib_ui __torsion_mpz_fib_ui -#define mpz_fib2_ui __torsion_mpz_fib2_ui -#define mpz_lucnum_ui __torsion_mpz_lucnum_ui -#define mpz_lucnum2_ui __torsion_mpz_lucnum2_ui -#define mpz_mr_prime_p __torsion_mpz_mr_prime_p -#define mpz_lucas_prime_p __torsion_mpz_lucas_prime_p -#define mpz_probab_prime_p __torsion_mpz_probab_prime_p -#define mpz_randprime __torsion_mpz_randprime -#define mpz_nextprime __torsion_mpz_nextprime -#define mpz_findprime __torsion_mpz_findprime -#define mpz_fits_ui_p __torsion_mpz_fits_ui_p -#define mpz_fits_si_p __torsion_mpz_fits_si_p -#define mpz_odd_p __torsion_mpz_odd_p -#define mpz_even_p __torsion_mpz_even_p -#define mpz_ctz __torsion_mpz_ctz -#define mpz_bitlen __torsion_mpz_bitlen -#define mpz_bytelen __torsion_mpz_bytelen -#define mpz_sizeinbase __torsion_mpz_sizeinbase -#define mpz_swap __torsion_mpz_swap -#define _mpz_realloc __torsion__mpz_realloc -#define mpz_realloc2 __torsion_mpz_realloc2 -#define mpz_getlimbn __torsion_mpz_getlimbn -#define mpz_size __torsion_mpz_size -#define mpz_limbs_read __torsion_mpz_limbs_read -#define mpz_limbs_write __torsion_mpz_limbs_write -#define mpz_limbs_modify __torsion_mpz_limbs_modify -#define mpz_limbs_finish __torsion_mpz_limbs_finish -#define mpz_import __torsion_mpz_import -#define mpz_export __torsion_mpz_export -#define mpz_set_str __torsion_mpz_set_str -#define mpz_get_str __torsion_mpz_get_str -#define mpz_print __torsion_mpz_print -#define mpz_urandomb __torsion_mpz_urandomb -#define mpz_urandomm __torsion_mpz_urandomm -#define test_mpi_internal __torsion_test_mpi_internal -#define bench_mpi_internal __torsion_bench_mpi_internal +#define mp_bits_per_limb torsion__mp_bits_per_limb +#define mpn_zero torsion__mpn_zero +#define mpn_cleanse torsion__mpn_cleanse +#define mpn_set_1 torsion__mpn_set_1 +#define mpn_copyi torsion__mpn_copyi +#define mpn_copyd torsion__mpn_copyd +#define mpn_zero_p torsion__mpn_zero_p +#define mpn_cmp torsion__mpn_cmp +#define mpn_add_1 torsion__mpn_add_1 +#define mpn_add_n torsion__mpn_add_n +#define mpn_add torsion__mpn_add +#define mpn_sec_add_1 torsion__mpn_sec_add_1 +#define mpn_sec_add torsion__mpn_sec_add +#define mpn_sub_1 torsion__mpn_sub_1 +#define mpn_sub_n torsion__mpn_sub_n +#define mpn_sub torsion__mpn_sub +#define mpn_sec_sub_1 torsion__mpn_sec_sub_1 +#define mpn_sec_sub torsion__mpn_sec_sub +#define mpn_mul_1 torsion__mpn_mul_1 +#define mpn_addmul_1 torsion__mpn_addmul_1 +#define mpn_submul_1 torsion__mpn_submul_1 +#define mpn_mul_n torsion__mpn_mul_n +#define mpn_mul torsion__mpn_mul +#define mpn_sqr torsion__mpn_sqr +#define mpn_mulshift torsion__mpn_mulshift +#define mpn_divmod_1 torsion__mpn_divmod_1 +#define mpn_div_1 torsion__mpn_div_1 +#define mpn_mod_1 torsion__mpn_mod_1 +#define mpn_divmod torsion__mpn_divmod +#define mpn_div torsion__mpn_div +#define mpn_mod torsion__mpn_mod +#define mpn_divexact_1 torsion__mpn_divexact_1 +#define mpn_divexact torsion__mpn_divexact +#define mpn_and_n torsion__mpn_and_n +#define mpn_ior_n torsion__mpn_ior_n +#define mpn_xor_n torsion__mpn_xor_n +#define mpn_andn_n torsion__mpn_andn_n +#define mpn_iorn_n torsion__mpn_iorn_n +#define mpn_nand_n torsion__mpn_nand_n +#define mpn_nior_n torsion__mpn_nior_n +#define mpn_xnor_n torsion__mpn_xnor_n +#define mpn_com torsion__mpn_com +#define mpn_lshift torsion__mpn_lshift +#define mpn_rshift torsion__mpn_rshift +#define mpn_getbit torsion__mpn_getbit +#define mpn_getbits torsion__mpn_getbits +#define mpn_tstbit torsion__mpn_tstbit +#define mpn_setbit torsion__mpn_setbit +#define mpn_clrbit torsion__mpn_clrbit +#define mpn_combit torsion__mpn_combit +#define mpn_scan0 torsion__mpn_scan0 +#define mpn_scan1 torsion__mpn_scan1 +#define mpn_popcount torsion__mpn_popcount +#define mpn_hamdist torsion__mpn_hamdist +#define mpn_mask torsion__mask +#define mpn_neg torsion__mpn_neg +#define mpn_reduce_weak torsion__mpn_reduce_weak +#define mpn_barrett torsion__mpn_barrett +#define mpn_reduce torsion__mpn_reduce +#define mpn_mont torsion__mpn_mont +#define mpn_montmul torsion__mpn_montmul +#define mpn_sec_montmul torsion__mpn_sec_montmul +#define mpn_gcd torsion__mpn_gcd +#define mpn_gcd_1 torsion__mpn_gcd_1 +#define mpn_invert torsion__mpn_invert +#define mpn_invert_n torsion__mpn_invert_n +#define mpn_sec_invert torsion__mpn_sec_invert +#define mpn_sec_invert_n torsion__mpn_sec_invert_n +#define mpn_jacobi torsion__mpn_jacobi +#define mpn_jacobi_n torsion__mpn_jacobi_n +#define mpn_powm torsion__mpn_powm +#define mpn_sec_powm torsion__mpn_sec_powm +#define mpn_ctz torsion__mpn_ctz +#define mpn_bitlen torsion__mpn_bitlen +#define mpn_bytelen torsion__mpn_bytelen +#define mpn_sizeinbase torsion__mpn_sizeinbase +#define mpn_cnd_select torsion__mpn_cnd_select +#define mpn_cnd_swap torsion__mpn_cnd_swap +#define mpn_cnd_add_n torsion__mpn_cnd_add_n +#define mpn_cnd_sub_n torsion__mpn_cnd_sub_n +#define mpn_cnd_neg torsion__mpn_cnd_neg +#define mpn_sec_tabselect torsion__mpn_sec_tabselect +#define mpn_sec_zero_p torsion__mpn_sec_zero_p +#define mpn_sec_equal_p torsion__mpn_sec_equal_p +#define mpn_sec_lt_p torsion__mpn_sec_lt_p +#define mpn_sec_lte_p torsion__mpn_sec_lte_p +#define mpn_sec_gt_p torsion__mpn_sec_gt_p +#define mpn_sec_gte_p torsion__mpn_sec_gte_p +#define mpn_sec_cmp torsion__mpn_sec_cmp +#define mpn_import torsion__mpn_import +#define mpn_export torsion__mpn_export +#define mpn_set_str torsion__mpn_set_str +#define mpn_get_str torsion__mpn_get_str +#define mpn_print torsion__mpn_print +#define mpn_random torsion__mpn_random +#define mpn_randomm torsion__mpn_randomm +#define mpz_init torsion__mpz_init +#define mpz_init2 torsion__mpz_init2 +#define mpz_init_set torsion__mpz_init_set +#define mpz_init_set_ui torsion__mpz_init_set_ui +#define mpz_init_set_si torsion__mpz_init_set_si +#define mpz_init_set_str torsion__mpz_init_set_str +#define mpz_clear torsion__mpz_clear +#define mpz_cleanse torsion__mpz_cleanse +#define mpz_set torsion__mpz_set +#define mpz_roset torsion__mpz_roset +#define mpz_roinit_n torsion__mpz_roinit_n +#define mpz_set_ui torsion__mpz_set_ui +#define mpz_set_si torsion__mpz_set_si +#define mpz_get_ui torsion__mpz_get_ui +#define mpz_get_si torsion__mpz_get_si +#define mpz_sgn torsion__mpz_sgn +#define mpz_cmp torsion__mpz_cmp +#define mpz_cmp_ui torsion__mpz_cmp_ui +#define mpz_cmp_si torsion__mpz_cmp_si +#define mpz_cmpabs torsion__mpz_cmpabs +#define mpz_cmpabs_ui torsion__mpz_cmpabs_ui +#define mpz_cmpabs_si torsion__mpz_cmpabs_si +#define mpz_add torsion__mpz_add +#define mpz_add_ui torsion__mpz_add_ui +#define mpz_add_si torsion__mpz_add_si +#define mpz_sub torsion__mpz_sub +#define mpz_sub_ui torsion__mpz_sub_ui +#define mpz_sub_si torsion__mpz_sub_si +#define mpz_ui_sub torsion__mpz_ui_sub +#define mpz_si_sub torsion__mpz_si_sub +#define mpz_mul torsion__mpz_mul +#define mpz_mul_ui torsion__mpz_mul_ui +#define mpz_mul_si torsion__mpz_mul_si +#define mpz_sqr torsion__mpz_sqr +#define mpz_addmul torsion__mpz_addmul +#define mpz_addmul_ui torsion__mpz_addmul_ui +#define mpz_addmul_si torsion__mpz_addmul_si +#define mpz_submul torsion__mpz_submul +#define mpz_submul_ui torsion__mpz_submul_ui +#define mpz_submul_si torsion__mpz_submul_si +#define mpz_mulshift torsion__mpz_mulshift +#define mpz_quorem torsion__mpz_quorem +#define mpz_quo torsion__mpz_quo +#define mpz_rem torsion__mpz_rem +#define mpz_quo_ui torsion__mpz_quo_ui +#define mpz_rem_ui torsion__mpz_rem_ui +#define mpz_quo_si torsion__mpz_quo_si +#define mpz_rem_si torsion__mpz_rem_si +#define mpz_divmod torsion__mpz_divmod +#define mpz_div torsion__mpz_div +#define mpz_mod torsion__mpz_mod +#define mpz_div_ui torsion__mpz_div_ui +#define mpz_mod_ui torsion__mpz_mod_ui +#define mpz_div_si torsion__mpz_div_si +#define mpz_mod_si torsion__mpz_mod_si +#define mpz_divexact torsion__mpz_divexact +#define mpz_divexact_ui torsion__mpz_divexact_ui +#define mpz_divexact_si torsion__mpz_divexact_si +#define mpz_divround torsion__mpz_divround +#define mpz_divround_ui torsion__mpz_divround_ui +#define mpz_divround_si torsion__mpz_divround_si +#define mpz_divisible_p torsion__mpz_divisible_p +#define mpz_divisible_ui_p torsion__mpz_divisible_ui_p +#define mpz_divisible_2exp_p torsion__mpz_divisible_2exp_p +#define mpz_congruent_p torsion__mpz_congruent_p +#define mpz_congruent_ui_p torsion__mpz_congruent_ui_p +#define mpz_congruent_2exp_p torsion__mpz_congruent_2exp_p +#define mpz_pow_ui torsion__mpz_pow_ui +#define mpz_ui_pow_ui torsion__mpz_ui_pow_ui +#define mpz_rootrem torsion__mpz_rootrem +#define mpz_root torsion__mpz_root +#define mpz_perfect_power_p torsion__mpz_perfect_power_p +#define mpz_sqrtrem torsion__mpz_sqrtrem +#define mpz_sqrt torsion__mpz_sqrt +#define mpz_perfect_square_p torsion__mpz_perfect_square_p +#define mpz_and torsion__mpz_and +#define mpz_and_ui torsion__mpz_and_ui +#define mpz_and_si torsion__mpz_and_si +#define mpz_ior torsion__mpz_ior +#define mpz_ior_ui torsion__mpz_ior_ui +#define mpz_ior_si torsion__mpz_ior_si +#define mpz_xor torsion__mpz_xor +#define mpz_xor_ui torsion__mpz_xor_ui +#define mpz_xor_si torsion__mpz_xor_si +#define mpz_com torsion__mpz_com +#define mpz_mul_2exp torsion__mpz_mul_2exp +#define mpz_quo_2exp torsion__mpz_quo_2exp +#define mpz_rem_2exp torsion__mpz_rem_2exp +#define mpz_div_2exp torsion__mpz_div_2exp +#define mpz_mod_2exp torsion__mpz_mod_2exp +#define mpz_tstbit torsion__mpz_tstbit +#define mpz_setbit torsion__mpz_setbit +#define mpz_clrbit torsion__mpz_clrbit +#define mpz_combit torsion__mpz_combit +#define mpz_scan0 torsion__mpz_scan0 +#define mpz_scan1 torsion__mpz_scan1 +#define mpz_popcount torsion__mpz_popcount +#define mpz_hamdist torsion__mpz_hamdist +#define mpz_abs torsion__mpz_abs +#define mpz_neg torsion__mpz_neg +#define mpz_gcd torsion__mpz_gcd +#define mpz_gcd_ui torsion__mpz_gcd_ui +#define mpz_lcm torsion__mpz_lcm +#define mpz_lcm_ui torsion__mpz_lcm_ui +#define mpz_gcdext torsion__mpz_gcdext +#define mpz_invert torsion__mpz_invert +#define mpz_legendre torsion__mpz_legendre +#define mpz_jacobi torsion__mpz_jacobi +#define mpz_kronecker torsion__mpz_kronecker +#define mpz_kronecker_ui torsion__mpz_kronecker_ui +#define mpz_kronecker_si torsion__mpz_kronecker_si +#define mpz_ui_kronecker torsion__mpz_ui_kronecker +#define mpz_si_kronecker torsion__mpz_si_kronecker +#define mpz_powm torsion__mpz_powm +#define mpz_powm_ui torsion__mpz_powm_ui +#define mpz_powm_sec torsion__mpz_powm_sec +#define mpz_sqrtm torsion__mpz_sqrtm +#define mpz_sqrtpq torsion__mpz_sqrtpq +#define mpz_remove torsion__mpz_remove +#define mpz_fac_ui torsion__mpz_fac_ui +#define mpz_2fac_ui torsion__mpz_2fac_ui +#define mpz_mfac_uiui torsion__mpz_mfac_uiui +#define mpz_primorial_ui torsion__mpz_primorial_ui +#define mpz_bin_ui torsion__mpz_bin_ui +#define mpz_bin_uiui torsion__mpz_bin_uiui +#define mpz_bin_siui torsion__mpz_bin_siui +#define mpz_fib_ui torsion__mpz_fib_ui +#define mpz_fib2_ui torsion__mpz_fib2_ui +#define mpz_lucnum_ui torsion__mpz_lucnum_ui +#define mpz_lucnum2_ui torsion__mpz_lucnum2_ui +#define mpz_mr_prime_p torsion__mpz_mr_prime_p +#define mpz_lucas_prime_p torsion__mpz_lucas_prime_p +#define mpz_probab_prime_p torsion__mpz_probab_prime_p +#define mpz_randprime torsion__mpz_randprime +#define mpz_nextprime torsion__mpz_nextprime +#define mpz_findprime torsion__mpz_findprime +#define mpz_fits_ui_p torsion__mpz_fits_ui_p +#define mpz_fits_si_p torsion__mpz_fits_si_p +#define mpz_odd_p torsion__mpz_odd_p +#define mpz_even_p torsion__mpz_even_p +#define mpz_ctz torsion__mpz_ctz +#define mpz_bitlen torsion__mpz_bitlen +#define mpz_bytelen torsion__mpz_bytelen +#define mpz_sizeinbase torsion__mpz_sizeinbase +#define mpz_swap torsion__mpz_swap +#define _mpz_realloc torsion__mpz_realloc +#define mpz_realloc2 torsion__mpz_realloc2 +#define mpz_getlimbn torsion__mpz_getlimbn +#define mpz_size torsion__mpz_size +#define mpz_limbs_read torsion__mpz_limbs_read +#define mpz_limbs_write torsion__mpz_limbs_write +#define mpz_limbs_modify torsion__mpz_limbs_modify +#define mpz_limbs_finish torsion__mpz_limbs_finish +#define mpz_import torsion__mpz_import +#define mpz_export torsion__mpz_export +#define mpz_set_str torsion__mpz_set_str +#define mpz_get_str torsion__mpz_get_str +#define mpz_print torsion__mpz_print +#define mpz_urandomb torsion__mpz_urandomb +#define mpz_urandomm torsion__mpz_urandomm +#define test_mpi_internal torsion__test_mpi_internal +#define bench_mpi_internal torsion__bench_mpi_internal /* * Types @@ -307,6 +312,7 @@ typedef int32_t mp_long_t; typedef long mp_size_t; typedef long mp_bits_t; +typedef mp_bits_t mp_bitcnt_t; /* compat */ #define MP_SIZE_C(x) x ## L #define MP_SIZE_MIN LONG_MIN @@ -315,8 +321,6 @@ typedef long mp_bits_t; #define MP_BITS_MIN LONG_MIN #define MP_BITS_MAX LONG_MAX -typedef mp_bits_t mp_bitcnt_t; /* compat */ - #define MP_LIMB_HI (MP_LIMB_C(1) << (MP_LIMB_BITS - 1)) #define MP_MASK(bits) ((MP_LIMB_C(1) << (bits)) - 1) #define MP_LOW_BITS (MP_LIMB_BITS / 2) @@ -330,6 +334,21 @@ struct mpz_s { typedef struct mpz_s mpz_t[1]; +/* Note: these types aren't strictly documented, + * but they are sometimes referenced in the docs[1], + * and they are no doubt used by programmers as + * they have been mentioned on the mailing list + * a number of times[2][3]. + * + * [1] https://gmplib.org/manual/Integer-Special-Functions + * [2] https://gmplib.org/list-archives/gmp-discuss/2011-February/004493.html + * [3] https://gmplib.org/list-archives/gmp-discuss/2009-May/003769.html + */ +typedef mp_limb_t *mp_ptr; +typedef const mp_limb_t *mp_srcptr; +typedef struct mpz_s *mpz_ptr; +typedef const struct mpz_s *mpz_srcptr; + typedef int mp_puts_f(const char *s); typedef void mp_rng_f(void *out, size_t size, void *arg); typedef void mp_start_f(uint64_t *start, const char *name); @@ -358,6 +377,7 @@ typedef void mp_end_f(uint64_t *start, uint64_t ops); #define MPN_GCD_ITCH(xn, yn) ((xn) + (yn)) #define MPN_GCD_1_ITCH(xn) (xn) #define MPN_INVERT_ITCH(n) (4 * ((n) + 1)) +#define MPN_SEC_INVERT_ITCH(n) ((n) + MPN_SEC_POWM_ITCH(n)) #define MPN_JACOBI_ITCH(n) (2 * (n)) #define MPN_SLIDE_ITCH(yn, mn) ((yn) > 2 ? (MP_SLIDE_SIZE * (mn)) : 0) #define MPN_POWM_ITCH(yn, mn) (6 * (mn) + MPN_SLIDE_ITCH(yn, mn)) @@ -373,17 +393,11 @@ typedef void mp_end_f(uint64_t *start, uint64_t ops); #define MPZ_ROINIT_N(xp, xs) {{(mp_limb_t *)(xp), 0, (xs)}} /* - * Allocation + * Globals */ -mp_limb_t * -mp_alloc_limbs(mp_size_t size); - -mp_limb_t * -mp_realloc_limbs(mp_limb_t *ptr, mp_size_t size); - -void -mp_free_limbs(mp_limb_t *ptr); +/* https://gmplib.org/manual/Useful-Macros-and-Constants */ +extern const int mp_bits_per_limb; /* * MPN Interface @@ -442,6 +456,17 @@ mp_limb_t mpn_add(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, const mp_limb_t *yp, mp_size_t yn); +/* + * Secure Addition + */ + +mp_limb_t +mpn_sec_add_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y); + +mp_limb_t +mpn_sec_add(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, + const mp_limb_t *yp, mp_size_t yn); + /* * Subtraction */ @@ -458,6 +483,17 @@ mp_limb_t mpn_sub(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, const mp_limb_t *yp, mp_size_t yn); +/* + * Secure Subtraction + */ + +mp_limb_t +mpn_sec_sub_1(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t y); + +mp_limb_t +mpn_sec_sub(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, + const mp_limb_t *yp, mp_size_t yn); + /* * Multiplication */ @@ -494,62 +530,6 @@ mpn_mulshift(mp_limb_t *zp, const mp_limb_t *xp, mp_bits_t bits, mp_limb_t *scratch); -/* - * Weak Reduction - */ - -int -mpn_reduce_weak(mp_limb_t *zp, const mp_limb_t *xp, - const mp_limb_t *np, - mp_size_t n, - mp_limb_t hi, - mp_limb_t *scratch); - -/* - * Barrett Reduction - */ - -void -mpn_barrett(mp_limb_t *mp, const mp_limb_t *np, - mp_size_t n, - mp_size_t shift, - mp_limb_t *scratch); - -void -mpn_reduce(mp_limb_t *zp, const mp_limb_t *xp, - const mp_limb_t *mp, - const mp_limb_t *np, - mp_size_t n, - mp_size_t shift, - mp_limb_t *scratch); - -/* - * Montgomery Multiplication - */ - -void -mpn_mont(mp_limb_t *kp, - mp_limb_t *rp, - const mp_limb_t *mp, - mp_size_t n, - mp_limb_t *scratch); - -void -mpn_montmul(mp_limb_t *zp, const mp_limb_t *xp, - const mp_limb_t *yp, - const mp_limb_t *mp, - mp_size_t n, - mp_limb_t k, - mp_limb_t *scratch); - -void -mpn_montmul_var(mp_limb_t *zp, const mp_limb_t *xp, - const mp_limb_t *yp, - const mp_limb_t *mp, - mp_size_t n, - mp_limb_t k, - mp_limb_t *scratch); - /* * Division */ @@ -587,17 +567,6 @@ void mpn_divexact(mp_limb_t *qp, const mp_limb_t *np, mp_size_t nn, const mp_limb_t *dp, mp_size_t dn); -/* - * Round Division - */ - -void -mpn_divround_1(mp_limb_t *qp, const mp_limb_t *np, mp_size_t nn, mp_limb_t d); - -void -mpn_divround(mp_limb_t *qp, const mp_limb_t *np, mp_size_t nn, - const mp_limb_t *dp, mp_size_t dn); - /* * AND */ @@ -666,7 +635,7 @@ mpn_nior_n(mp_limb_t *zp, const mp_limb_t *xp, */ void -mpn_nxor_n(mp_limb_t *zp, const mp_limb_t *xp, +mpn_xnor_n(mp_limb_t *zp, const mp_limb_t *xp, const mp_limb_t *yp, mp_size_t n); @@ -735,6 +704,62 @@ mpn_mask(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_bits_t bits); mp_limb_t mpn_neg(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn); +/* + * Weak Reduction + */ + +int +mpn_reduce_weak(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *np, + mp_size_t n, + mp_limb_t hi, + mp_limb_t *scratch); + +/* + * Barrett Reduction + */ + +void +mpn_barrett(mp_limb_t *mp, const mp_limb_t *np, + mp_size_t n, + mp_size_t shift, + mp_limb_t *scratch); + +void +mpn_reduce(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *mp, + const mp_limb_t *np, + mp_size_t n, + mp_size_t shift, + mp_limb_t *scratch); + +/* + * Montgomery Multiplication + */ + +void +mpn_mont(mp_limb_t *kp, + mp_limb_t *rp, + const mp_limb_t *mp, + mp_size_t n, + mp_limb_t *scratch); + +void +mpn_montmul(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *yp, + const mp_limb_t *mp, + mp_size_t n, + mp_limb_t k, + mp_limb_t *scratch); + +void +mpn_sec_montmul(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *yp, + const mp_limb_t *mp, + mp_size_t n, + mp_limb_t k, + mp_limb_t *scratch); + /* * Number Theoretic Functions */ @@ -758,6 +783,17 @@ mpn_invert_n(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t n, mp_limb_t *scratch); +int +mpn_sec_invert(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, + const mp_limb_t *mp, mp_size_t mn, + mp_limb_t *scratch); + +int +mpn_sec_invert_n(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *yp, + mp_size_t n, + mp_limb_t *scratch); + int mpn_jacobi(const mp_limb_t *xp, mp_size_t xn, const mp_limb_t *yp, mp_size_t yn, @@ -785,15 +821,6 @@ mpn_sec_powm(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, * Helpers */ -mp_size_t -mpn_strip(const mp_limb_t *xp, mp_size_t xn); - -int -mpn_odd_p(const mp_limb_t *xp, mp_size_t xn); - -int -mpn_even_p(const mp_limb_t *xp, mp_size_t xn); - mp_bits_t mpn_ctz(const mp_limb_t *xp, mp_size_t xn); @@ -811,13 +838,35 @@ mpn_sizeinbase(const mp_limb_t *xp, mp_size_t xn, int base); */ void -mpn_select(mp_limb_t *zp, const mp_limb_t *xp, - const mp_limb_t *yp, - mp_size_t n, - int flag); +mpn_cnd_select(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *yp, + mp_size_t n, + mp_limb_t cnd); void -mpn_select_zero(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t n, int flag); +mpn_cnd_swap(mp_limb_t *xp, mp_limb_t *yp, mp_size_t n, mp_limb_t cnd); + +mp_limb_t +mpn_cnd_add_n(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *yp, + mp_size_t n, + mp_limb_t cnd); + +mp_limb_t +mpn_cnd_sub_n(mp_limb_t *zp, const mp_limb_t *xp, + const mp_limb_t *yp, + mp_size_t n, + mp_limb_t cnd); + +mp_limb_t +mpn_cnd_neg(mp_limb_t *zp, const mp_limb_t *xp, mp_size_t xn, mp_limb_t cnd); + +void +mpn_sec_tabselect(mp_limb_t *zp, + const mp_limb_t *tp, + mp_size_t n, + mp_size_t nents, + mp_size_t which); int mpn_sec_zero_p(const mp_limb_t *xp, mp_size_t xn); @@ -846,7 +895,7 @@ mpn_sec_cmp(const mp_limb_t *xp, const mp_limb_t *yp, mp_size_t n); void mpn_import(mp_limb_t *zp, mp_size_t zn, - const unsigned char *raw, size_t len, + const unsigned char *xp, size_t xn, int endian); /* @@ -854,7 +903,7 @@ mpn_import(mp_limb_t *zp, mp_size_t zn, */ void -mpn_export(unsigned char *raw, size_t len, +mpn_export(unsigned char *zp, size_t zn, const mp_limb_t *xp, mp_size_t xn, int endian); @@ -886,6 +935,11 @@ mpn_print(const mp_limb_t *xp, mp_size_t xn, int base, mp_puts_f *mp_puts); void mpn_random(mp_limb_t *zp, mp_size_t zn, mp_rng_f *rng, void *arg); +void +mpn_randomm(mp_limb_t *zp, + const mp_limb_t *xp, mp_size_t xn, + mp_rng_f *rng, void *arg); + /* * MPZ Interface */ @@ -932,7 +986,7 @@ mpz_set(mpz_t z, const mpz_t x); void mpz_roset(mpz_t z, const mpz_t x); -void +const struct mpz_s * mpz_roinit_n(mpz_t z, const mp_limb_t *xp, mp_size_t xs); void @@ -1378,16 +1432,19 @@ void mpz_bin_uiui(mpz_t z, mp_limb_t n, mp_limb_t k); void -mpz_fib_ui(mpz_t z, mp_limb_t n); +mpz_bin_siui(mpz_t z, mp_long_t n, mp_limb_t k); + +void +mpz_fib_ui(mpz_t fn, mp_limb_t n); void -mpz_fib2_ui(mpz_t z, mpz_t p, mp_limb_t n); +mpz_fib2_ui(mpz_t fn, mpz_t fn1, mp_limb_t n); void -mpz_lucnum_ui(mpz_t z, mp_limb_t n); +mpz_lucnum_ui(mpz_t ln, mp_limb_t n); void -mpz_lucnum2_ui(mpz_t z, mpz_t p, mp_limb_t n); +mpz_lucnum2_ui(mpz_t ln, mpz_t ln1, mp_limb_t n); /* * Primality Testing @@ -1455,7 +1512,7 @@ mpz_realloc2(mpz_t z, mp_bits_t bits); mp_limb_t mpz_getlimbn(const mpz_t x, mp_size_t n); -mp_size_t +size_t mpz_size(const mpz_t x); const mp_limb_t * @@ -1529,4 +1586,4 @@ test_mpi_internal(mp_rng_f *rng, void *arg); TORSION_EXTERN void bench_mpi_internal(mp_start_f *start, mp_end_f *end, mp_rng_f *rng, void *arg); -#endif /* _TORSION_MPI_H */ +#endif /* TORSION_MPI_H */ diff --git a/node_modules/bcrypto/deps/torsion/src/rand.c b/node_modules/bcrypto/deps/torsion/src/rand.c index fc9f215b8..bd665f3ea 100644 --- a/node_modules/bcrypto/deps/torsion/src/rand.c +++ b/node_modules/bcrypto/deps/torsion/src/rand.c @@ -72,10 +72,10 @@ sha512_update_tsc(sha512_t *hash) { */ typedef struct rng_s { - uint64_t key[4]; + uint32_t key[8]; uint64_t zero; uint64_t nonce; - uint32_t pool[16]; + uint32_t pool[128]; size_t pos; int rdrand; } rng_t; @@ -133,33 +133,49 @@ rng_init(rng_t *rng) { /* Cache the rdrand check. */ rng->rdrand = torsion_has_rdrand(); - torsion_cleanse(seed, sizeof(seed)); - torsion_cleanse(&hash, sizeof(hash)); + torsion_memzero(seed, sizeof(seed)); + torsion_memzero(&hash, sizeof(hash)); return 1; } static void -rng_generate(rng_t *rng, void *dst, size_t size) { - unsigned char *key = (unsigned char *)rng->key; - unsigned char *nonce = (unsigned char *)&rng->nonce; +rng_crypt(const rng_t *rng, void *data, size_t size) { chacha20_t ctx; + chacha20_init(&ctx, (const unsigned char *)rng->key, 32, + (const unsigned char *)&rng->nonce, 8, + rng->zero); + + chacha20_crypt(&ctx, (unsigned char *)data, + (const unsigned char *)data, + size); + + torsion_memzero(&ctx, sizeof(ctx)); +} + +static void +rng_read(const rng_t *rng, void *dst, size_t size) { if (size > 0) memset(dst, 0, size); + rng_crypt(rng, dst, size); +} + +static void +rng_generate(rng_t *rng, void *dst, size_t size) { /* Read the keystream. */ - chacha20_init(&ctx, key, 32, nonce, 8, rng->zero); - chacha20_crypt(&ctx, dst, dst, size); + rng_read(rng, dst, size); /* Mix in some user entropy. */ - rng->key[0] ^= size; + rng->key[0] ^= (uint32_t)size; + rng->key[1] ^= (uint32_t)((uint64_t)size >> 32); /* Mix in some hardware entropy. We sacrifice only 32 bits here, lest RDRAND is backdoored. See: https://pastebin.com/A07q3nL3 */ if (rng->rdrand) - rng->key[3] ^= (uint32_t)torsion_rdrand(); + rng->key[7] ^= (uint32_t)torsion_rdrand(); /* Re-key immediately. */ rng->nonce++; @@ -171,21 +187,38 @@ rng_generate(rng_t *rng, void *dst, size_t size) { there's probably not really a difference in terms of security, as the outputs in both scenarios are dependent on the key. */ - chacha20_init(&ctx, key, 32, nonce, 8, rng->zero); - chacha20_crypt(&ctx, key, key, 32); - - /* Cleanse the chacha state. */ - torsion_cleanse(&ctx, sizeof(ctx)); + rng_crypt(rng, rng->key, 32); } static uint32_t rng_random(rng_t *rng) { - if ((rng->pos & 15) == 0) { - rng_generate(rng, rng->pool, 64); - rng->pos = 0; + uint32_t x; + size_t i; + + if (rng->pos == 0) { + /* Read the keystream. */ + rng_read(rng, rng->pool, 512); + + /* Mix in some hardware entropy. */ + if (rng->rdrand) + rng->key[7] ^= (uint32_t)torsion_rdrand(); + + /* Re-key every 512 bytes. */ + for (i = 0; i < 8; i++) + rng->key[i] ^= rng->pool[120 + i]; + + for (i = 0; i < 8; i++) + rng->pool[120 + i] = 0; + + rng->nonce++; + rng->pos = 120; } - return rng->pool[rng->pos++]; + x = rng->pool[--rng->pos]; + + rng->pool[rng->pos] = 0; + + return x; } static uint32_t @@ -264,7 +297,14 @@ rng_global_init(void) { int torsion_getentropy(void *dst, size_t size) { - return torsion_sysrand(dst, size); + if (!torsion_sysrand(dst, size)) { + if (size > 0) + memset(dst, 0, size); + + return 0; + } + + return 1; } int @@ -272,7 +312,11 @@ torsion_getrandom(void *dst, size_t size) { rng_global_lock(); if (!rng_global_init()) { + if (size > 0) + memset(dst, 0, size); + rng_global_unlock(); + return 0; } @@ -287,6 +331,7 @@ torsion_random(uint32_t *num) { rng_global_lock(); if (!rng_global_init()) { + *num = 0; rng_global_unlock(); return 0; } @@ -303,6 +348,7 @@ torsion_uniform(uint32_t *num, uint32_t max) { rng_global_lock(); if (!rng_global_init()) { + *num = 0; rng_global_unlock(); return 0; } @@ -321,11 +367,11 @@ torsion_uniform(uint32_t *num, uint32_t max) { int torsion_threadsafety(void) { #if defined(TORSION_HAVE_TLS) - return TORSION_THREAD_SAFETY_TLS; + return TORSION_THREADSAFETY_TLS; #elif defined(TORSION_HAVE_PTHREAD) - return TORSION_THREAD_SAFETY_MUTEX; + return TORSION_THREADSAFETY_MUTEX; #else - return TORSION_THREAD_SAFETY_NONE; + return TORSION_THREADSAFETY_NONE; #endif } diff --git a/node_modules/bcrypto/deps/torsion/src/rsa.c b/node_modules/bcrypto/deps/torsion/src/rsa.c index be5fc3875..7f9dce19d 100644 --- a/node_modules/bcrypto/deps/torsion/src/rsa.c +++ b/node_modules/bcrypto/deps/torsion/src/rsa.c @@ -26,6 +26,7 @@ #include #include #include "asn1.h" +#include "bio.h" #include "internal.h" #include "mpi.h" @@ -33,7 +34,12 @@ * Constants */ -static const unsigned char digest_info[32][24] = { +static const unsigned char digest_info[33][24] = { + { /* NONE */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, { /* BLAKE2B160 */ 0x15, 0x30, 0x27, 0x30, 0x0f, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x8d, 0x3a, 0x0c, 0x02, @@ -407,7 +413,9 @@ rsa_priv_export_dumb(unsigned char *out, size_t *out_len, const rsa_priv_t *k) { } static int -rsa_priv_generate(rsa_priv_t *k, int bits, uint64_t exp, +rsa_priv_generate(rsa_priv_t *k, + mp_bits_t bits, + uint64_t exp, const unsigned char *entropy) { /* [RFC8017] Page 9, Section 3.2. * [FIPS186] Page 51, Appendix B.3.1 @@ -429,6 +437,9 @@ rsa_priv_generate(rsa_priv_t *k, int bits, uint64_t exp, * [1] https://crypto.stackexchange.com/a/29595 */ mpz_t pm1, qm1, phi, lam, tmp; +#if MP_LIMB_BITS == 32 + mp_limb_t *limbs; +#endif drbg_t rng; if (bits < RSA_MIN_MOD_BITS @@ -447,9 +458,16 @@ rsa_priv_generate(rsa_priv_t *k, int bits, uint64_t exp, mpz_init(lam); mpz_init(tmp); - mpz_set_ui(k->e, exp >> 32); - mpz_mul_2exp(k->e, k->e, 32); - mpz_ior_ui(k->e, k->e, exp & UINT32_MAX); +#if MP_LIMB_BITS == 64 + mpz_set_ui(k->e, exp); +#else + limbs = mpz_limbs_write(k->e, 2); + + limbs[0] = (mp_limb_t)(exp >> 0); + limbs[1] = (mp_limb_t)(exp >> 32); + + mpz_limbs_finish(k->e, 2); +#endif for (;;) { mpz_randprime(k->p, (bits >> 1) + (bits & 1), drbg_rng, &rng); @@ -499,7 +517,7 @@ rsa_priv_generate(rsa_priv_t *k, int bits, uint64_t exp, break; } - torsion_cleanse(&rng, sizeof(rng)); + torsion_memzero(&rng, sizeof(rng)); mpz_cleanse(pm1); mpz_cleanse(qm1); @@ -776,9 +794,10 @@ rsa_priv_set_ned(rsa_priv_t *out, */ mpz_t f, nm1, nm3, g, a, b, c, p, q; size_t entropy_len = ENTROPY_SIZE; - int i, j, s; + mp_bits_t j, s; int ret = 0; drbg_t rng; + int i; mpz_init(f); mpz_init(nm1); @@ -865,12 +884,12 @@ rsa_priv_set_ned(rsa_priv_t *out, if (mpz_cmp(c, nm1) == 0) break; - mpz_set(b, c); + mpz_swap(b, c); } } done: - torsion_cleanse(&rng, sizeof(rng)); + torsion_memzero(&rng, sizeof(rng)); mpz_cleanse(f); mpz_cleanse(nm1); mpz_cleanse(nm3); @@ -1064,7 +1083,7 @@ rsa_pub_export_dumb(unsigned char *out, size_t *out_len, const rsa_pub_t *k) { static int rsa_pub_verify(const rsa_pub_t *k) { - int bits = mpz_bitlen(k->n); + mp_bits_t bits = mpz_bitlen(k->n); if (mpz_sgn(k->n) < 0) return 0; @@ -1095,8 +1114,8 @@ rsa_pub_encrypt(const rsa_pub_t *k, /* [RFC8017] Page 13, Section 5.1.1. * Page 16, Section 5.2.2. */ - mpz_t m; int ret = 0; + mpz_t m; mpz_init(m); @@ -1122,7 +1141,8 @@ static int rsa_pub_veil(const rsa_pub_t *k, unsigned char *out, const unsigned char *msg, - size_t msg_len, int bits, + size_t msg_len, + mp_bits_t bits, const unsigned char *entropy) { mpz_t vmax, rmax, c, v, r; int ret = 0; @@ -1175,7 +1195,7 @@ rsa_pub_veil(const rsa_pub_t *k, mpz_export(out, v, (bits + 7) / 8, 1); ret = 1; fail: - torsion_cleanse(&rng, sizeof(rng)); + torsion_memzero(&rng, sizeof(rng)); mpz_cleanse(vmax); mpz_cleanse(rmax); mpz_cleanse(c); @@ -1189,7 +1209,7 @@ rsa_pub_unveil(const rsa_pub_t *k, unsigned char *out, const unsigned char *msg, size_t msg_len, - int bits) { + mp_bits_t bits) { int ret = 0; mpz_t v; @@ -1214,16 +1234,10 @@ rsa_pub_unveil(const rsa_pub_t *k, */ static int -get_digest_info(const unsigned char **data, size_t *len, int type) { +get_digest_info(const unsigned char **data, size_t *len, hash_id_t type) { const unsigned char *info; - if (type == -1) { - *data = NULL; - *len = 0; - return 1; - } - - if (type < 0 || (size_t)type > ARRAY_SIZE(digest_info)) + if (type < 0 || (size_t)type >= ARRAY_SIZE(digest_info)) return 0; info = digest_info[type]; @@ -1239,7 +1253,7 @@ get_digest_info(const unsigned char **data, size_t *len, int type) { */ static void -mgf1xor(int type, +mgf1xor(hash_id_t type, unsigned char *out, size_t out_len, const unsigned char *seed, @@ -1268,18 +1282,13 @@ mgf1xor(int type, while (i < out_len && j < hash_size) out[i++] ^= digest[j++]; - j = 4; - - while (j--) { - if (++ctr[j] != 0x00) - break; - } + increment_be_var(ctr, 4); } - torsion_cleanse(ctr, sizeof(ctr)); - torsion_cleanse(digest, sizeof(digest)); - torsion_cleanse(&cache, sizeof(cache)); - torsion_cleanse(&hash, sizeof(hash)); + torsion_memzero(ctr, sizeof(ctr)); + torsion_memzero(digest, sizeof(digest)); + torsion_memzero(&cache, sizeof(cache)); + torsion_memzero(&hash, sizeof(hash)); } /* @@ -1289,10 +1298,10 @@ mgf1xor(int type, static int pss_encode(unsigned char *out, size_t *out_len, - int type, + hash_id_t type, const unsigned char *msg, size_t msg_len, - int embits, + mp_bits_t embits, const unsigned char *salt, size_t salt_len) { /* [RFC8017] Page 42, Section 9.1.1. */ @@ -1343,11 +1352,11 @@ pss_encode(unsigned char *out, } static int -pss_verify(int type, +pss_verify(hash_id_t type, const unsigned char *msg, size_t msg_len, unsigned char *em, - int embits, + mp_bits_t embits, size_t salt_len) { /* [RFC8017] Page 44, Section 9.1.2. */ size_t hlen = hash_output_size(type); @@ -1448,7 +1457,7 @@ rsa_privkey_generate(unsigned char *out, unsigned int rsa_privkey_bits(const unsigned char *key, size_t key_len) { - unsigned int bits = 0; + mp_bits_t bits = 0; rsa_priv_t k; rsa_priv_init(&k); @@ -1571,7 +1580,7 @@ rsa_pubkey_create(unsigned char *out, unsigned int rsa_pubkey_bits(const unsigned char *key, size_t key_len) { - unsigned int bits = 0; + mp_bits_t bits = 0; rsa_pub_t k; rsa_pub_init(&k); @@ -1656,7 +1665,7 @@ rsa_pubkey_export(unsigned char *out, int rsa_sign(unsigned char *out, size_t *out_len, - int type, + hash_id_t type, const unsigned char *msg, size_t msg_len, const unsigned char *key, @@ -1677,7 +1686,7 @@ rsa_sign(unsigned char *out, if (!get_digest_info(&prefix, &prefix_len, type)) goto fail; - if (type == -1) + if (type == HASH_NONE) hlen = msg_len; if (msg_len != hlen) @@ -1721,7 +1730,7 @@ rsa_sign(unsigned char *out, } int -rsa_verify(int type, +rsa_verify(hash_id_t type, const unsigned char *msg, size_t msg_len, const unsigned char *sig, @@ -1745,7 +1754,7 @@ rsa_verify(int type, if (!get_digest_info(&prefix, &prefix_len, type)) goto fail; - if (type == -1) + if (type == HASH_NONE) hlen = msg_len; if (msg_len != hlen) @@ -1766,7 +1775,7 @@ rsa_verify(int type, if (klen < tlen + 11) goto fail; - em = malloc(klen); + em = (unsigned char *)malloc(klen); if (em == NULL) goto fail; @@ -1807,8 +1816,8 @@ rsa_encrypt(unsigned char *out, size_t i, mlen, plen; size_t klen = 0; rsa_pub_t k; - drbg_t rng; int ret = 0; + drbg_t rng; drbg_init(&rng, HASH_SHA256, entropy, ENTROPY_SIZE); @@ -1854,8 +1863,8 @@ rsa_encrypt(unsigned char *out, ret = 1; fail: rsa_pub_clear(&k); - torsion_cleanse(&rng, sizeof(rng)); - if (ret == 0) torsion_cleanse(out, klen); + torsion_memzero(&rng, sizeof(rng)); + if (ret == 0) torsion_memzero(out, klen); return ret; } @@ -1919,14 +1928,14 @@ rsa_decrypt(unsigned char *out, ret = 1; fail: rsa_priv_clear(&k); - if (ret == 0) torsion_cleanse(out, klen); + if (ret == 0) torsion_memzero(out, klen); return ret; } int rsa_sign_pss(unsigned char *out, size_t *out_len, - int type, + hash_id_t type, const unsigned char *msg, size_t msg_len, const unsigned char *key, @@ -1938,11 +1947,11 @@ rsa_sign_pss(unsigned char *out, unsigned char *salt = NULL; unsigned char *em = out; size_t klen = 0; + mp_bits_t bits; size_t emlen; rsa_priv_t k; - drbg_t rng; int ret = 0; - int bits; + drbg_t rng; rsa_priv_init(&k); @@ -1975,7 +1984,7 @@ rsa_sign_pss(unsigned char *out, goto fail; if (salt_len > 0) { - salt = malloc(salt_len); + salt = (unsigned char *)malloc(salt_len); if (salt == NULL) goto fail; @@ -1998,14 +2007,14 @@ rsa_sign_pss(unsigned char *out, ret = 1; fail: rsa_priv_clear(&k); - torsion_cleanse(&rng, sizeof(rng)); + torsion_memzero(&rng, sizeof(rng)); if (salt != NULL) free(salt); - if (ret == 0) torsion_cleanse(out, klen); + if (ret == 0) torsion_memzero(out, klen); return ret; } int -rsa_verify_pss(int type, +rsa_verify_pss(hash_id_t type, const unsigned char *msg, size_t msg_len, const unsigned char *sig, @@ -2017,9 +2026,9 @@ rsa_verify_pss(int type, size_t hlen = hash_output_size(type); unsigned char *em = NULL; size_t klen = 0; + mp_bits_t bits; rsa_pub_t k; int ret = 0; - int bits; rsa_pub_init(&k); @@ -2049,7 +2058,7 @@ rsa_verify_pss(int type, if (salt_len > klen) goto fail; - em = malloc(klen); + em = (unsigned char *)malloc(klen); if (em == NULL) goto fail; @@ -2084,7 +2093,7 @@ rsa_verify_pss(int type, int rsa_encrypt_oaep(unsigned char *out, size_t *out_len, - int type, + hash_id_t type, const unsigned char *msg, size_t msg_len, const unsigned char *key, @@ -2102,8 +2111,8 @@ rsa_encrypt_oaep(unsigned char *out, size_t slen, dlen; rsa_pub_t k; hash_t hash; - drbg_t rng; int ret = 0; + drbg_t rng; rsa_pub_init(&k); @@ -2157,16 +2166,16 @@ rsa_encrypt_oaep(unsigned char *out, ret = 1; fail: rsa_pub_clear(&k); - torsion_cleanse(&rng, sizeof(drbg_t)); - torsion_cleanse(&hash, sizeof(hash_t)); - if (ret == 0) torsion_cleanse(out, klen); + torsion_memzero(&rng, sizeof(drbg_t)); + torsion_memzero(&hash, sizeof(hash_t)); + if (ret == 0) torsion_memzero(out, klen); return ret; } int rsa_decrypt_oaep(unsigned char *out, size_t *out_len, - int type, + hash_id_t type, const unsigned char *msg, size_t msg_len, const unsigned char *key, @@ -2251,8 +2260,8 @@ rsa_decrypt_oaep(unsigned char *out, ret = 1; fail: rsa_priv_clear(&k); - torsion_cleanse(&hash, sizeof(hash)); - if (ret == 0) torsion_cleanse(out, klen); + torsion_memzero(&hash, sizeof(hash)); + if (ret == 0) torsion_memzero(out, klen); return ret; } @@ -2266,8 +2275,8 @@ rsa_veil(unsigned char *out, size_t key_len, const unsigned char *entropy) { rsa_pub_t k; - drbg_t rng; int ret = 0; + drbg_t rng; rsa_pub_init(&k); @@ -2289,7 +2298,7 @@ rsa_veil(unsigned char *out, *out_len = (bits + 7) / 8; ret = 1; fail: - torsion_cleanse(&rng, sizeof(rng)); + torsion_memzero(&rng, sizeof(rng)); rsa_pub_clear(&k); return ret; } diff --git a/node_modules/bcrypto/deps/torsion/src/stream.c b/node_modules/bcrypto/deps/torsion/src/stream.c index bf44200af..d099b08a4 100644 --- a/node_modules/bcrypto/deps/torsion/src/stream.c +++ b/node_modules/bcrypto/deps/torsion/src/stream.c @@ -24,11 +24,17 @@ * https://github.com/golang/go/blob/master/src/crypto/rc4/rc4.go */ +#define swap(x, y) do { \ + uint8_t _x = (x); \ + (x) = (y); \ + (y) = _x; \ +} while (0) + void arc4_init(arc4_t *ctx, const unsigned char *key, size_t key_len) { - size_t k = key_len; uint8_t *s = ctx->s; - uint8_t j, si; + size_t k = key_len; + uint8_t j = 0; size_t i; CHECK(k >= 1 && k <= 256); @@ -36,15 +42,10 @@ arc4_init(arc4_t *ctx, const unsigned char *key, size_t key_len) { for (i = 0; i < 256; i++) s[i] = i; - j = 0; - for (i = 0; i < 256; i++) { - j += s[i] + key[i % k]; - j &= 0xff; + j = (j + s[i] + key[i % k]) & 0xff; - si = s[i]; - s[i] = s[j]; - s[j] = si; + swap(s[i], s[j]); } ctx->i = 0; @@ -59,26 +60,23 @@ arc4_crypt(arc4_t *ctx, uint8_t *s = ctx->s; uint8_t i = ctx->i; uint8_t j = ctx->j; - uint8_t x, y; size_t k; for (k = 0; k < len; k++) { i = (i + 1) & 0xff; - x = s[i]; + j = (j + s[i]) & 0xff; - j = (j + x) & 0xff; - y = s[j]; + swap(s[i], s[j]); - s[i] = y; - s[j] = x; - - dst[k] = src[k] ^ s[(x + y) & 0xff]; + dst[k] = src[k] ^ s[(s[i] + s[j]) & 0xff]; } ctx->i = i; ctx->j = j; } +#undef swap + /* * ChaCha20 * @@ -148,12 +146,11 @@ chacha20_init(chacha20_t *ctx, ctx->pos = 0; - torsion_cleanse(tmp, sizeof(tmp)); + torsion_memzero(tmp, sizeof(tmp)); } static void chacha20_block(chacha20_t *ctx, uint32_t *stream) { - uint64_t c; int i; for (i = 0; i < 16; i++) @@ -178,28 +175,50 @@ chacha20_block(chacha20_t *ctx, uint32_t *stream) { stream[i] = torsion_bswap32(stream[i]); } - c = (uint64_t)ctx->state[12] + 1; - - ctx->state[12] = c; - ctx->state[13] += (uint32_t)(c >> 32); + ctx->state[12] += 1; + ctx->state[13] += (ctx->state[12] < 1); } void chacha20_crypt(chacha20_t *ctx, - unsigned char *out, - const unsigned char *data, + unsigned char *dst, + const unsigned char *src, size_t len) { unsigned char *bytes = (unsigned char *)ctx->stream; - size_t i; + size_t pos = ctx->pos; + size_t want = 64 - pos; - for (i = 0; i < len; i++) { - if ((ctx->pos & 63) == 0) { + if (len >= want) { + if (pos > 0) { + torsion_memxor3(dst, src, bytes + pos, want); + + dst += want; + src += want; + len -= want; + pos = 0; + } + + while (len >= 64) { chacha20_block(ctx, ctx->stream); - ctx->pos = 0; + + torsion_memxor3(dst, src, bytes, 64); + + dst += 64; + src += 64; + len -= 64; } + } + + if (len > 0) { + if (pos == 0) + chacha20_block(ctx, ctx->stream); + + torsion_memxor3(dst, src, bytes + pos, len); - out[i] = data[i] ^ bytes[ctx->pos++]; + pos += len; } + + ctx->pos = pos; } void @@ -249,7 +268,7 @@ chacha20_derive(unsigned char *out, write32le(out + 24, state[14]); write32le(out + 28, state[15]); - torsion_cleanse(state, sizeof(state)); + torsion_memzero(state, sizeof(state)); } #undef ROTL32 @@ -328,12 +347,11 @@ salsa20_init(salsa20_t *ctx, ctx->pos = 0; - torsion_cleanse(tmp, sizeof(tmp)); + torsion_memzero(tmp, sizeof(tmp)); } static void salsa20_block(salsa20_t *ctx, uint32_t *stream) { - uint64_t c; int i; for (i = 0; i < 16; i++) @@ -358,28 +376,50 @@ salsa20_block(salsa20_t *ctx, uint32_t *stream) { stream[i] = torsion_bswap32(stream[i]); } - c = (uint64_t)ctx->state[8] + 1; - - ctx->state[8] = c; - ctx->state[9] += (uint32_t)(c >> 32); + ctx->state[8] += 1; + ctx->state[9] += (ctx->state[8] < 1); } void salsa20_crypt(salsa20_t *ctx, - unsigned char *out, - const unsigned char *data, + unsigned char *dst, + const unsigned char *src, size_t len) { unsigned char *bytes = (unsigned char *)ctx->stream; - size_t i; + size_t pos = ctx->pos; + size_t want = 64 - pos; + + if (len >= want) { + if (pos > 0) { + torsion_memxor3(dst, src, bytes + pos, want); + + dst += want; + src += want; + len -= want; + pos = 0; + } - for (i = 0; i < len; i++) { - if ((ctx->pos & 63) == 0) { + while (len >= 64) { salsa20_block(ctx, ctx->stream); - ctx->pos = 0; + + torsion_memxor3(dst, src, bytes, 64); + + dst += 64; + src += 64; + len -= 64; } + } - out[i] = data[i] ^ bytes[ctx->pos++]; + if (len > 0) { + if (pos == 0) + salsa20_block(ctx, ctx->stream); + + torsion_memxor3(dst, src, bytes + pos, len); + + pos += len; } + + ctx->pos = pos; } void @@ -429,7 +469,7 @@ salsa20_derive(unsigned char *out, write32le(out + 24, state[8]); write32le(out + 28, state[9]); - torsion_cleanse(state, sizeof(state)); + torsion_memzero(state, sizeof(state)); } #undef ROTL32 diff --git a/node_modules/bcrypto/deps/torsion/src/tls.h b/node_modules/bcrypto/deps/torsion/src/tls.h index 31f42d2bf..043b96ea9 100644 --- a/node_modules/bcrypto/deps/torsion/src/tls.h +++ b/node_modules/bcrypto/deps/torsion/src/tls.h @@ -4,12 +4,12 @@ * https://github.com/bcoin-org/libtorsion */ -#ifndef _TORSION_TLS_H -#define _TORSION_TLS_H +#ifndef TORSION_TLS_H +#define TORSION_TLS_H /* TLS Compiler Support * - * GCC: + * GCC / G++: * * - Supports TLS via __thread[1]. * - TLS first implemented in GCC 3.3[1]. @@ -33,18 +33,20 @@ * - Support for OpenBSD added in Clang 5.0[16]. * - Support for iOS Simulator added in Clang 7.0[17]. * - Support for RISC-V added in Clang 9.0[18]. - * - No support for x86-64 Cygwin as of Clang 10.0[19]. - * - No support for ARM Cygwin as of Clang 10.0[20]. - * - No support for Haiku as of Clang 10.0[21]. + * - No support for x86-64 Cygwin as of Clang 12.0[19]. + * - No support for ARM Cygwin as of Clang 12.0[20]. + * - No support for Haiku as of Clang 12.0[21]. * - * Intel C: + * Intel C/C++: * * - Supports TLS via __thread[22], __declspec(thread)[23]. * - Intel mentions __thread in documentation from 2004[22]. - * This would suggest support from version 8.x onward. - * - Furthermore, this post[24] suggests __thread existed - * at least as far back as 2006 (version 9.0 or 10.0). + * This user guide lists __INTEL_COMPILER as 810, implying + * support on Linux from 8.1.0 onward. The Intel C++ 8.1 + * release notes confirm this[24]. * - Apple and Mach-O support implemented in 15.0[25]. + * - The exact version for Windows support is unknown + * (though, wikipedia cites the 10.0 documentation). * * MSVC: * @@ -53,18 +55,20 @@ * from 2009 suggests it existed in VS .NET 2002 (7.0). * - Another project dating from 1996-2003 suggests * TLS was supported in Visual Studio 6.0 (1998)[28]. + * - Wikipedia cites the VS .NET 2003 documentation as + * a source for __declspec(thread). * - Usage of TLS appears on the MSDN Library CD for * Visual Studio 6.0 (1998). The author of the code * samples claims to have written them in 1995. This * means TLS would have been supported in MSVC 4.0. * - * Sun Pro C / Sun Studio / Solaris Studio: + * Sun Pro C/C++ / Sun Studio / Solaris Studio: * * - Supports TLS via __thread[29]. * - First mentioned in documentation for Sun Studio 12[30]. * This would suggest support from 5.9 onward. * - * IBM XL C: + * IBM XL C/C++: * * - Supports TLS via __thread[31]. * - Support added for Linux in XL C 8.0[32]. @@ -86,19 +90,19 @@ * - Supports TLS via __thread, __declspec(thread)[37][38]. * - Mentioned on the gnulib mailing list[39]. * - * HP ANSI C: + * HP ANSI C / HP aC++: * * - Supports TLS via __thread[40]. * - The release notes suggest this has been the * case since at least version A.05.55.02. * - * Watcom C: + * Watcom C/C++: * * - TLS supported via __declspec(thread)[41]. * - TLS supported since at least version 11.0c[41]. * Notable as this predates Open Watcom. * - * Wind River Compiler (Diab C): + * Wind River Compiler (Diab C/C++): * * - TLS supported via __thread[42][43]. * - TLS supported since at least 2007 (5.6)[43]. @@ -109,7 +113,7 @@ * - TLS first implemented in NWCC 0.7.5 (2008). * See develop/oldnews/NEWS-0.7.5. * - * Metrowerks C: + * Metrowerks C/C++: * * - TLS supported via __declspec(thread)[45]. * Documentation explicitly states this is @@ -147,6 +151,10 @@ * or do not define it directly (in particular, Intel C * versions less than 18.0.0[52]). * + * C++11: + * + * - C++11 specifies support for thread_local[53]. + * * [1] https://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Thread-Local.html * [2] https://github.com/gcc-mirror/gcc/commit/8893239dc4ed32bd3bb4e00d6e43b859554ab82a * [3] https://clang.llvm.org/docs/AttributeReference.html#thread @@ -165,19 +173,22 @@ * [16] https://github.com/llvm/llvm-project/blob/llvmorg-5.0.0/clang/lib/Basic/Targets.cpp#L555 * [17] https://github.com/llvm/llvm-project/blob/llvmorg-7.0.0/clang/lib/Basic/Targets/OSTargets.h#L103 * [18] https://github.com/llvm/llvm-project/blob/llvmorg-9.0.0/clang/lib/Basic/Targets/RISCV.h#L24 - * [19] https://github.com/llvm/llvm-project/blob/llvmorg-10.0.0/clang/lib/Basic/Targets/X86.h#L819 - * [20] https://github.com/llvm/llvm-project/blob/llvmorg-10.0.0/clang/lib/Basic/Targets/ARM.cpp#L1208 - * [21] https://github.com/llvm/llvm-project/blob/llvmorg-10.0.0/clang/lib/Basic/Targets/OSTargets.h#L310 + * [19] https://github.com/llvm/llvm-project/blob/llvmorg-12.0.0/clang/lib/Basic/Targets/X86.h#L833 + * [20] https://github.com/llvm/llvm-project/blob/llvmorg-12.0.0/clang/lib/Basic/Targets/ARM.cpp#L1248 + * [21] https://github.com/llvm/llvm-project/blob/llvmorg-12.0.0/clang/lib/Basic/Targets/OSTargets.h#L291 * [22] https://software.intel.com/sites/default/files/ae/4f/6320 - * [23] https://community.intel.com/t5/Intel-C-Compiler/Thread-local-storage-support-on-Windows/td-p/949321 - * [24] https://community.intel.com/t5/Intel-C-Compiler/thread-local-storage-linking-problems/td-p/932631 + http://download.intel.com/support/performancetools/c/linux/sb/clin81_relnotes.pdf#4 + * [23] http://software.intel.com/sites/default/files/m/2/4/8/5/d/16949-347599.pdf#155 + * [24] https://www.tu-chemnitz.de/mathematik/mrz/neues/8.1/C++ReleaseNotes.htm * [25] https://community.intel.com/t5/Intel-C-Compiler/Mach-O-thread-local-storage/td-p/948267 * [26] https://docs.microsoft.com/en-us/cpp/c-language/thread-local-storage + https://docs.microsoft.com/en-us/previous-versions/6yh4a9k1%28v%3dvs.140%29 * [27] https://github.com/snaewe/loki-lib/commit/7d8e59abc8f48785d564ddabab5ba3f01cd24444 * [28] http://www.simkin.co.uk/Docs/cpp/api/skGeneral_8h-source.html * [29] https://docs.oracle.com/cd/E18659_01/html/821-1383/bkaeg.html * [30] https://docs.oracle.com/cd/E19205-01/819-5267/bkaeg/index.html * [31] https://www.ibm.com/support/knowledgecenter/en/SSXVZZ_13.1.3/com.ibm.xlcpp1313.lelinux.doc/language_ref/thread.html + http://www-01.ibm.com/support/docview.wss?uid=swg27007322&aid=1#6 * [32] https://www.ibm.com/support/pages/node/318521#6 * [33] http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devwin32/threadsusingthreadlocalvariables_xml.html * [34] http://docwiki.embarcadero.com/RADStudio/Sydney/en/Declspec(thread) @@ -199,6 +210,7 @@ * [50] https://github.com/IanHarvey/pcc/commit/109a8ee * [51] https://en.cppreference.com/w/c/keyword/_Thread_local * [52] https://software.intel.com/en-us/forums/intel-c-compiler/topic/721059 + * [53] https://en.cppreference.com/w/cpp/language/storage_duration */ /* Apple Quirks @@ -323,7 +335,10 @@ # if __HP_cc >= 55502 /* A.05.55.02 (2004) */ # define TORSION_TLS_GNUC # endif -# define TORSION_TLS_GNUC +#elif defined(__HP_aCC) +# if __HP_aCC >= 55502 /* A.05.55.02 (2004) */ +# define TORSION_TLS_GNUC +# endif #elif defined(__WATCOMC__) # if __WATCOMC__ >= 1200 /* Open Watcom 1.0 (2003) */ # define TORSION_TLS_MSVC @@ -346,28 +361,36 @@ # if __SUNPRO_C >= 0x590 /* 5.9 (2007) */ # define TORSION_TLS_GNUC # endif +#elif defined(__SUNPRO_CC) +# if __SUNPRO_CC >= 0x590 /* 5.9 (2007) */ +# define TORSION_TLS_GNUC +# endif #elif defined(__INTEL_COMPILER) -# if defined(__APPLE__) && defined(__MACH__) -# if defined(TORSION__APPLE_OS) && __INTEL_COMPILER >= 1500 /* 15.0.0 (2014) */ -# define TORSION_TLS_GNUC +# if defined(__GNUC__) && defined(__GNUC_MINOR__) +# if ((__GNUC__ << 16) + __GNUC_MINOR__ >= 0x30003) /* 3.3 */ +# define TORSION__GNUC_3_3 # endif -# elif __INTEL_COMPILER >= 800 /* 8.0.0 (2003) */ -# define TORSION_TLS_BOTH # endif -#elif defined(__ICC) -# if !defined(__APPLE__) && __ICC >= 800 /* 8.0.0 (2003) */ -# define TORSION_TLS_GNUC -# endif -#elif defined(__ICL) -# if __ICL >= 800 /* 8.0.0 (2003) */ -# define TORSION_TLS_MSVC +# if defined(TORSION__APPLE_OS) && __INTEL_COMPILER >= 1500 /* 15.0.0 (2014) */ +# ifdef TORSION__GNUC_3_3 +# define TORSION_TLS_GNUC +# endif +# elif defined(__linux__) && __INTEL_COMPILER >= 810 /* 8.1.0 (2004) */ +# ifdef TORSION__GNUC_3_3 +# define TORSION_TLS_GNUC +# endif +# elif defined(_WIN32) && __INTEL_COMPILER >= 1000 /* 10.0.0 (2007) */ +# ifdef _MSC_VER +# define TORSION_TLS_MSVC +# endif # endif #elif defined(__clang__) # if defined(__apple_build_version__) # if defined(TORSION__APPLE_OS) && __apple_build_version__ >= 8000038 /* 800.0.38 (2016) */ # define TORSION_TLS_GNUC # endif -# elif TORSION__HAS_EXTENSION(c_thread_local) /* 3.4 (late 2013) */ +# elif TORSION__HAS_EXTENSION(c_thread_local) \ + || TORSION__HAS_EXTENSION(cxx_thread_local) /* 3.4 (late 2013) */ # if defined(__ANDROID__) # if defined(__clang_major__) && __clang_major__ >= 5 /* 5.0 (2017) */ # define TORSION_TLS_GNUC @@ -418,6 +441,8 @@ # ifndef __STDC_NO_THREADS__ # define TORSION_TLS_STDC # endif +#elif defined(__cplusplus) && (__cplusplus + 0L) >= 201103L +# define TORSION_TLS_CPP #endif #ifdef TORSION_TLS_BOTH @@ -438,6 +463,9 @@ #elif defined(TORSION_TLS_STDC) # define TORSION_HAVE_TLS # define TORSION_TLS _Thread_local +#elif defined(TORSION_TLS_CPP) +# define TORSION_HAVE_TLS +# define TORSION_TLS thread_local #else # define TORSION_TLS #endif @@ -472,4 +500,4 @@ #endif /* !TORSION_HAVE_CONFIG */ -#endif /* _TORSION_TLS_H */ +#endif /* TORSION_TLS_H */ diff --git a/node_modules/bcrypto/deps/torsion/src/util.c b/node_modules/bcrypto/deps/torsion/src/util.c index 5b34f0a40..ea9074c15 100644 --- a/node_modules/bcrypto/deps/torsion/src/util.c +++ b/node_modules/bcrypto/deps/torsion/src/util.c @@ -26,7 +26,7 @@ */ void -torsion_cleanse(void *ptr, size_t len) { +torsion_memzero(void *ptr, size_t len) { #if defined(_WIN32) && defined(SecureZeroMemory) if (len > 0) SecureZeroMemory(ptr, len); @@ -47,17 +47,40 @@ torsion_cleanse(void *ptr, size_t len) { */ int -torsion_memequal(const void *s1, const void *s2, size_t n) { - const unsigned char *x = s1; - const unsigned char *y = s2; +torsion_memequal(const void *x, const void *y, size_t n) { + const unsigned char *xp = (const unsigned char *)x; + const unsigned char *yp = (const unsigned char *)y; uint32_t z = 0; while (n--) - z |= (uint32_t)x[n] ^ (uint32_t)y[n]; + z |= *xp++ ^ *yp++; return (z - 1) >> 31; } +/* + * Memxor + */ + +void +torsion_memxor(void *z, const void *x, size_t n) { + const unsigned char *xp = (const unsigned char *)x; + unsigned char *zp = (unsigned char *)z; + + while (n--) + *zp++ ^= *xp++; +} + +void +torsion_memxor3(void *z, const void *x, const void *y, size_t n) { + const unsigned char *xp = (const unsigned char *)x; + const unsigned char *yp = (const unsigned char *)y; + unsigned char *zp = (unsigned char *)z; + + while (n--) + *zp++ = *xp++ ^ *yp++; +} + /* * Murmur3 * @@ -74,7 +97,7 @@ murmur3_sum(const unsigned char *data, size_t len, uint32_t seed) { uint32_t k1 = 0; size_t left = len; -#define ROTL32(x, y) ((x) << (y)) | ((x) >> (32 - (y))) +#define ROTL32(w, b) ((w) << (b)) | ((w) >> (32 - (b))) while (left >= 4) { k1 = read32le(data); diff --git a/node_modules/bcrypto/lib/bcrypto.js b/node_modules/bcrypto/lib/bcrypto.js index 3895fdb6a..5cb542174 100644 --- a/node_modules/bcrypto/lib/bcrypto.js +++ b/node_modules/bcrypto/lib/bcrypto.js @@ -94,5 +94,5 @@ exports.Whirlpool = require('./whirlpool'); exports.x25519 = require('./x25519'); exports.x448 = require('./x448'); -exports.version = '5.4.0'; +exports.version = '5.5.0'; exports.native = exports.SHA256.native; diff --git a/node_modules/bcrypto/lib/encoding/bech32-browser.js b/node_modules/bcrypto/lib/encoding/bech32-browser.js index 18dc9a17c..4ea26f687 100644 --- a/node_modules/bcrypto/lib/encoding/bech32-browser.js +++ b/node_modules/bcrypto/lib/encoding/bech32-browser.js @@ -6,4 +6,5 @@ 'use strict'; -module.exports = require('../js/bech32'); +const BECH32 = require('../js/bech32'); +module.exports = new BECH32(1); diff --git a/node_modules/bcrypto/lib/encoding/bech32.js b/node_modules/bcrypto/lib/encoding/bech32.js index 31b24f1d1..25f559c25 100644 --- a/node_modules/bcrypto/lib/encoding/bech32.js +++ b/node_modules/bcrypto/lib/encoding/bech32.js @@ -6,7 +6,10 @@ 'use strict'; +let BECH32; if (process.env.NODE_BACKEND === 'js') - module.exports = require('../js/bech32'); + BECH32 = require('../js/bech32'); else - module.exports = require('../native/bech32'); + BECH32 = require('../native/bech32'); + +module.exports = new BECH32(1); diff --git a/node_modules/bcrypto/lib/encoding/bech32m-browser.js b/node_modules/bcrypto/lib/encoding/bech32m-browser.js new file mode 100644 index 000000000..c139a28aa --- /dev/null +++ b/node_modules/bcrypto/lib/encoding/bech32m-browser.js @@ -0,0 +1,10 @@ +/*! + * bech32m.js - bech32m for bcrypto + * Copyright (c) 2021, the bcoin developers (MIT License). + * https://github.com/bcoin-org/bcrypto + */ + +'use strict'; + +const BECH32 = require('../js/bech32'); +module.exports = new BECH32(0x2bc830a3); diff --git a/node_modules/bcrypto/lib/encoding/bech32m.js b/node_modules/bcrypto/lib/encoding/bech32m.js new file mode 100644 index 000000000..a442f89b2 --- /dev/null +++ b/node_modules/bcrypto/lib/encoding/bech32m.js @@ -0,0 +1,15 @@ +/*! + * bech32m.js - bech32m for bcrypto + * Copyright (c) 2021, the bcoin developers (MIT License). + * https://github.com/bcoin-org/bcrypto + */ + +'use strict'; + +let BECH32; +if (process.env.NODE_BACKEND === 'js') + BECH32 = require('../js/bech32'); +else + BECH32 = require('../native/bech32'); + +module.exports = new BECH32(0x2bc830a3); diff --git a/node_modules/bcrypto/lib/js/bech32.js b/node_modules/bcrypto/lib/js/bech32.js index 95458e061..1903e1874 100644 --- a/node_modules/bcrypto/lib/js/bech32.js +++ b/node_modules/bcrypto/lib/js/bech32.js @@ -44,352 +44,364 @@ const TABLE = [ ]; /** - * Update checksum. - * @ignore - * @param {Number} c - * @returns {Number} + * BECH32 */ -function polymod(c) { - const b = c >>> 25; - - return ((c & 0x1ffffff) << 5) - ^ (0x3b6a57b2 & -((b >> 0) & 1)) - ^ (0x26508e6d & -((b >> 1) & 1)) - ^ (0x1ea119fa & -((b >> 2) & 1)) - ^ (0x3d4233dd & -((b >> 3) & 1)) - ^ (0x2a1462b3 & -((b >> 4) & 1)); -} - -/** - * Encode hrp and data as a bech32 string. - * @param {String} hrp - * @param {Buffer} data - * @returns {String} - */ - -function serialize(hrp, data) { - assert(typeof hrp === 'string'); - assert(Buffer.isBuffer(data)); +class BECH32 { + constructor(checksum) { + assert((checksum >>> 0) === checksum); + this.checksum = checksum; + this.native = 0; + } - if (hrp.length === 0 || hrp.length > 83) - throw new Error('Invalid bech32 human-readable part.'); + /** + * Update checksum. + * @ignore + * @param {Number} c + * @returns {Number} + */ + + polymod(c) { + const b = c >>> 25; + + return ((c & 0x1ffffff) << 5) + ^ (0x3b6a57b2 & -((b >> 0) & 1)) + ^ (0x26508e6d & -((b >> 1) & 1)) + ^ (0x1ea119fa & -((b >> 2) & 1)) + ^ (0x3d4233dd & -((b >> 3) & 1)) + ^ (0x2a1462b3 & -((b >> 4) & 1)); + } - if (hrp.length + 1 + data.length + 6 > 90) - throw new Error('Invalid bech32 data length.'); + /** + * Encode hrp and data as a bech32 string. + * @param {String} hrp + * @param {Buffer} data + * @returns {String} + */ - let str = ''; - let chk = 1; - let i; + serialize(hrp, data) { + assert(typeof hrp === 'string'); + assert(Buffer.isBuffer(data)); - for (i = 0; i < hrp.length; i++) { - const ch = hrp.charCodeAt(i); + if (hrp.length === 0 || hrp.length > 83) + throw new Error('Invalid bech32 human-readable part.'); - if (ch < 33 || ch > 126) - throw new Error('Invalid bech32 character.'); + if (hrp.length + 1 + data.length + 6 > 90) + throw new Error('Invalid bech32 data length.'); - if (ch >= 65 && ch <= 90) - throw new Error('Invalid bech32 character.'); + let str = ''; + let chk = 1; + let i; - chk = polymod(chk) ^ (ch >> 5); - } + for (i = 0; i < hrp.length; i++) { + const ch = hrp.charCodeAt(i); - chk = polymod(chk); + if (ch < 33 || ch > 126) + throw new Error('Invalid bech32 character.'); - for (let i = 0; i < hrp.length; i++) { - const ch = hrp.charCodeAt(i); + if (ch >= 65 && ch <= 90) + throw new Error('Invalid bech32 character.'); - chk = polymod(chk) ^ (ch & 0x1f); + chk = this.polymod(chk) ^ (ch >> 5); + } - str += hrp[i]; - } + chk = this.polymod(chk); - str += '1'; + for (let i = 0; i < hrp.length; i++) { + const ch = hrp.charCodeAt(i); - for (let i = 0; i < data.length; i++) { - const ch = data[i]; + chk = this.polymod(chk) ^ (ch & 0x1f); - if (ch >> 5) - throw new Error('Invalid bech32 value.'); + str += hrp[i]; + } - chk = polymod(chk) ^ ch; + str += '1'; - str += CHARSET[ch]; - } + for (let i = 0; i < data.length; i++) { + const ch = data[i]; - for (let i = 0; i < 6; i++) - chk = polymod(chk); + if (ch >> 5) + throw new Error('Invalid bech32 value.'); - chk ^= 1; + chk = this.polymod(chk) ^ ch; - for (let i = 0; i < 6; i++) - str += CHARSET[(chk >>> ((5 - i) * 5)) & 0x1f]; + str += CHARSET[ch]; + } - return str; -} + for (let i = 0; i < 6; i++) + chk = this.polymod(chk); -/** - * Decode a bech32 string. - * @param {String} str - * @returns {Array} [hrp, data] - */ + chk ^= this.checksum; -function deserialize(str) { - assert(typeof str === 'string'); + for (let i = 0; i < 6; i++) + str += CHARSET[(chk >>> ((5 - i) * 5)) & 0x1f]; - if (str.length < 8 || str.length > 90) - throw new Error('Invalid bech32 string length.'); + return str; + } - let lower = false; - let upper = false; - let hlen = 0; + /** + * Decode a bech32 string. + * @param {String} str + * @returns {Array} [hrp, data] + */ - for (let i = 0; i < str.length; i++) { - const ch = str.charCodeAt(i); + deserialize(str) { + assert(typeof str === 'string'); - if (ch < 33 || ch > 126) - throw new Error('Invalid bech32 character.'); + if (str.length < 8 || str.length > 90) + throw new Error('Invalid bech32 string length.'); - if (ch >= 97 && ch <= 122) - lower = true; - else if (ch >= 65 && ch <= 90) - upper = true; - else if (ch === 49) - hlen = i; - } + let lower = false; + let upper = false; + let hlen = 0; - if (hlen === 0) - throw new Error('Invalid bech32 human-readable part.'); + for (let i = 0; i < str.length; i++) { + const ch = str.charCodeAt(i); - const dlen = str.length - (hlen + 1); + if (ch < 33 || ch > 126) + throw new Error('Invalid bech32 character.'); - if (dlen < 6) - throw new Error('Invalid bech32 data length.'); + if (ch >= 97 && ch <= 122) + lower = true; + else if (ch >= 65 && ch <= 90) + upper = true; + else if (ch === 49) + hlen = i; + } - if (lower && upper) - throw new Error('Invalid bech32 casing.'); + if (hlen === 0) + throw new Error('Invalid bech32 human-readable part.'); - let chk = 1; - let hrp = ''; + const dlen = str.length - (hlen + 1); - for (let i = 0; i < hlen; i++) { - let ch = str.charCodeAt(i); + if (dlen < 6) + throw new Error('Invalid bech32 data length.'); - if (ch >= 65 && ch <= 90) - ch += 32; + if (lower && upper) + throw new Error('Invalid bech32 casing.'); - chk = polymod(chk) ^ (ch >> 5); + let chk = 1; + let hrp = ''; - hrp += String.fromCharCode(ch); - } + for (let i = 0; i < hlen; i++) { + let ch = str.charCodeAt(i); - chk = polymod(chk); + if (ch >= 65 && ch <= 90) + ch += 32; - for (let i = 0; i < hlen; i++) - chk = polymod(chk) ^ (str.charCodeAt(i) & 0x1f); + chk = this.polymod(chk) ^ (ch >> 5); - const data = Buffer.alloc(dlen - 6); + hrp += String.fromCharCode(ch); + } - let j = 0; + chk = this.polymod(chk); - for (let i = hlen + 1; i < str.length; i++) { - const val = TABLE[str.charCodeAt(i)]; + for (let i = 0; i < hlen; i++) + chk = this.polymod(chk) ^ (str.charCodeAt(i) & 0x1f); - if (val === -1) - throw new Error('Invalid bech32 character.'); + const data = Buffer.alloc(dlen - 6); - chk = polymod(chk) ^ val; + let j = 0; - if (i < str.length - 6) - data[j++] = val; - } + for (let i = hlen + 1; i < str.length; i++) { + const val = TABLE[str.charCodeAt(i)]; - if (chk !== 1) - throw new Error('Invalid bech32 checksum.'); + if (val === -1) + throw new Error('Invalid bech32 character.'); - assert(j === data.length); + chk = this.polymod(chk) ^ val; - return [hrp, data]; -} + if (i < str.length - 6) + data[j++] = val; + } -/** - * Test whether a string is a bech32 string. - * @param {String} str - * @returns {Boolean} - */ + if (chk !== this.checksum) + throw new Error('Invalid bech32 checksum.'); -function is(str) { - assert(typeof str === 'string'); + assert(j === data.length); - try { - deserialize(str); - return true; - } catch (e) { - return false; + return [hrp, data]; } -} -/** - * Convert serialized data to another base. - * @param {Buffer} dst - * @param {Number} dstoff - * @param {Number} dstbits - * @param {Buffer} src - * @param {Number} srcoff - * @param {Number} srcbits - * @param {Boolean} pad - * @returns {Buffer} - */ + /** + * Test whether a string is a bech32 string. + * @param {String} str + * @returns {Boolean} + */ -function convert(dst, dstoff, dstbits, src, srcoff, srcbits, pad) { - assert(Buffer.isBuffer(dst)); - assert((dstoff >>> 0) === dstoff); - assert((dstbits >>> 0) === dstbits); - assert(Buffer.isBuffer(src)); - assert((srcoff >>> 0) === srcoff); - assert((srcbits >>> 0) === srcbits); - assert(typeof pad === 'boolean'); - assert(dstbits >= 1 && dstbits <= 8); - assert(srcbits >= 1 && srcbits <= 8); - - const mask = (1 << dstbits) - 1; - - let acc = 0; - let bits = 0; - let i = srcoff; - let j = dstoff; - - for (; i < src.length; i++) { - acc = (acc << srcbits) | src[i]; - bits += srcbits; - - while (bits >= dstbits) { - bits -= dstbits; - dst[j++] = (acc >>> bits) & mask; + is(str) { + assert(typeof str === 'string'); + + try { + this.deserialize(str); + return true; + } catch (e) { + return false; } } - const left = dstbits - bits; - - if (pad) { - if (bits) - dst[j++] = (acc << left) & mask; - } else { - if (((acc << left) & mask) || bits >= srcbits) - throw new Error('Invalid bits.'); - } + /** + * Convert serialized data to another base. + * @param {Buffer} dst + * @param {Number} dstoff + * @param {Number} dstbits + * @param {Buffer} src + * @param {Number} srcoff + * @param {Number} srcbits + * @param {Boolean} pad + * @returns {Buffer} + */ + + convert(dst, dstoff, dstbits, src, srcoff, srcbits, pad) { + assert(Buffer.isBuffer(dst)); + assert((dstoff >>> 0) === dstoff); + assert((dstbits >>> 0) === dstbits); + assert(Buffer.isBuffer(src)); + assert((srcoff >>> 0) === srcoff); + assert((srcbits >>> 0) === srcbits); + assert(typeof pad === 'boolean'); + assert(dstbits >= 1 && dstbits <= 8); + assert(srcbits >= 1 && srcbits <= 8); + + const mask = (1 << dstbits) - 1; + + let acc = 0; + let bits = 0; + let i = srcoff; + let j = dstoff; + + for (; i < src.length; i++) { + acc = (acc << srcbits) | src[i]; + bits += srcbits; + + while (bits >= dstbits) { + bits -= dstbits; + dst[j++] = (acc >>> bits) & mask; + } + } - assert(j <= dst.length); + const left = dstbits - bits; - return dst.slice(0, j); -} + if (pad) { + if (bits) + dst[j++] = (acc << left) & mask; + } else { + if (((acc << left) & mask) || bits >= srcbits) + throw new Error('Invalid bits.'); + } -/** - * Calculate size required for bit conversion. - * @param {Number} len - * @param {Number} srcbits - * @param {Number} dstbits - * @param {Boolean} pad - * @returns {Number} - */ + assert(j <= dst.length); -function convertSize(len, srcbits, dstbits, pad) { - assert((len >>> 0) === len); - assert((srcbits >>> 0) === srcbits); - assert((dstbits >>> 0) === dstbits); - assert(typeof pad === 'boolean'); - assert(srcbits >= 1 && srcbits <= 8); - assert(dstbits >= 1 && dstbits <= 8); + return dst.slice(0, j); + } - return ((len * srcbits + (dstbits - 1) * (pad | 0)) / dstbits) >>> 0; -} + /** + * Calculate size required for bit conversion. + * @param {Number} len + * @param {Number} srcbits + * @param {Number} dstbits + * @param {Boolean} pad + * @returns {Number} + */ + + convertSize(len, srcbits, dstbits, pad) { + assert((len >>> 0) === len); + assert((srcbits >>> 0) === srcbits); + assert((dstbits >>> 0) === dstbits); + assert(typeof pad === 'boolean'); + assert(srcbits >= 1 && srcbits <= 8); + assert(dstbits >= 1 && dstbits <= 8); + + return ((len * srcbits + (dstbits - 1) * (pad | 0)) / dstbits) >>> 0; + } -/** - * Convert serialized data to another base. - * @param {Buffer} data - * @param {Number} srcbits - * @param {Number} dstbits - * @param {Boolean} pad - * @returns {Buffer} - */ + /** + * Convert serialized data to another base. + * @param {Buffer} data + * @param {Number} srcbits + * @param {Number} dstbits + * @param {Boolean} pad + * @returns {Buffer} + */ -function convertBits(data, srcbits, dstbits, pad) { - assert(Buffer.isBuffer(data)); + convertBits(data, srcbits, dstbits, pad) { + assert(Buffer.isBuffer(data)); - const size = convertSize(data.length, srcbits, dstbits, pad); - const out = Buffer.alloc(size); + const size = this.convertSize(data.length, srcbits, dstbits, pad); + const out = Buffer.alloc(size); - return convert(out, 0, dstbits, data, 0, srcbits, pad); -} + return this.convert(out, 0, dstbits, data, 0, srcbits, pad); + } -/** - * Serialize data to bech32 address. - * @param {String} hrp - * @param {Number} version - * @param {Buffer} hash - * @returns {String} - */ + /** + * Serialize data to bech32 address. + * @param {String} hrp + * @param {Number} version + * @param {Buffer} hash + * @returns {String} + */ -function encode(hrp, version, hash) { - assert(typeof hrp === 'string'); - assert((version >>> 0) === version); - assert(Buffer.isBuffer(hash)); + encode(hrp, version, hash) { + assert(typeof hrp === 'string'); + assert((version >>> 0) === version); + assert(Buffer.isBuffer(hash)); - if (version > 31) - throw new Error('Invalid bech32 version.'); + if (version > 31) + throw new Error('Invalid bech32 version.'); - if (hash.length < 2 || hash.length > 40) - throw new Error('Invalid bech32 data length.'); + if (hash.length < 2 || hash.length > 40) + throw new Error('Invalid bech32 data length.'); - const out = POOL65; + const out = POOL65; - out[0] = version; + out[0] = version; - const data = convert(out, 1, 5, hash, 0, 8, true); + const data = this.convert(out, 1, 5, hash, 0, 8, true); - return serialize(hrp, data); -} + return this.serialize(hrp, data); + } -/** - * Deserialize data from bech32 address. - * @param {String} addr - * @returns {Array} - */ + /** + * Deserialize data from bech32 address. + * @param {String} addr + * @returns {Array} + */ -function decode(addr) { - const [hrp, data] = deserialize(addr); + decode(addr) { + const [hrp, data] = this.deserialize(addr); - if (data.length === 0 || data.length > 65) - throw new Error('Invalid bech32 data length.'); + if (data.length === 0 || data.length > 65) + throw new Error('Invalid bech32 data length.'); - const version = data[0]; + const version = data[0]; - if (version > 31) - throw new Error('Invalid bech32 version.'); + if (version > 31) + throw new Error('Invalid bech32 version.'); - const output = data; // Works because dstbits > srcbits. - const hash = convert(output, 0, 8, data, 1, 5, false); + const output = data; // Works because dstbits > srcbits. + const hash = this.convert(output, 0, 8, data, 1, 5, false); - if (hash.length < 2 || hash.length > 40) - throw new Error('Invalid bech32 data length.'); + if (hash.length < 2 || hash.length > 40) + throw new Error('Invalid bech32 data length.'); - return [hrp, version, hash]; -} + return [hrp, version, hash]; + } -/** - * Test whether a string is a bech32 string. - * @param {String} addr - * @returns {Boolean} - */ + /** + * Test whether a string is a bech32 string. + * @param {String} addr + * @returns {Boolean} + */ -function test(addr) { - assert(typeof addr === 'string'); + test(addr) { + assert(typeof addr === 'string'); - try { - decode(addr); - return true; - } catch (e) { - return false; + try { + this.decode(addr); + return true; + } catch (e) { + return false; + } } } @@ -397,11 +409,4 @@ function test(addr) { * Expose */ -exports.native = 0; -exports.serialize = serialize; -exports.deserialize = deserialize; -exports.is = is; -exports.convertBits = convertBits; -exports.encode = encode; -exports.decode = decode; -exports.test = test; +module.exports = BECH32; diff --git a/node_modules/bcrypto/lib/native/bech32.js b/node_modules/bcrypto/lib/native/bech32.js index a87982688..392a584e1 100644 --- a/node_modules/bcrypto/lib/native/bech32.js +++ b/node_modules/bcrypto/lib/native/bech32.js @@ -13,59 +13,60 @@ const binding = require('./binding'); * Bech32 */ -function serialize(hrp, data) { - assert(typeof hrp === 'string'); - assert(Buffer.isBuffer(data)); +class BECH32 { + constructor(checksum) { + assert((checksum >>> 0) === checksum); + this.checksum = checksum; + this.native = 2; + } - return binding.bech32_serialize(hrp, data); -} + serialize(hrp, data) { + assert(typeof hrp === 'string'); + assert(Buffer.isBuffer(data)); -function deserialize(str) { - assert(typeof str === 'string'); - return binding.bech32_deserialize(str); -} + return binding.bech32_serialize(hrp, data, this.checksum); + } -function is(str) { - assert(typeof str === 'string'); - return binding.bech32_is(str); -} + deserialize(str) { + assert(typeof str === 'string'); + return binding.bech32_deserialize(str, this.checksum); + } -function convertBits(data, srcbits, dstbits, pad) { - assert(Buffer.isBuffer(data)); - assert((srcbits >>> 0) === srcbits); - assert((dstbits >>> 0) === dstbits); - assert(typeof pad === 'boolean'); + is(str) { + assert(typeof str === 'string'); + return binding.bech32_is(str, this.checksum); + } - return binding.bech32_convert_bits(data, srcbits, dstbits, pad); -} + convertBits(data, srcbits, dstbits, pad) { + assert(Buffer.isBuffer(data)); + assert((srcbits >>> 0) === srcbits); + assert((dstbits >>> 0) === dstbits); + assert(typeof pad === 'boolean'); -function encode(hrp, version, hash) { - assert(typeof hrp === 'string'); - assert((version >>> 0) === version); - assert(Buffer.isBuffer(hash)); + return binding.bech32_convert_bits(data, srcbits, dstbits, pad); + } - return binding.bech32_encode(hrp, version, hash); -} + encode(hrp, version, hash) { + assert(typeof hrp === 'string'); + assert((version >>> 0) === version); + assert(Buffer.isBuffer(hash)); -function decode(addr) { - assert(typeof addr === 'string'); - return binding.bech32_decode(addr); -} + return binding.bech32_encode(hrp, version, hash, this.checksum); + } + + decode(addr) { + assert(typeof addr === 'string'); + return binding.bech32_decode(addr, this.checksum); + } -function test(addr) { - assert(typeof addr === 'string'); - return binding.bech32_test(addr); + test(addr) { + assert(typeof addr === 'string'); + return binding.bech32_test(addr, this.checksum); + } } /* * Expose */ -exports.native = 2; -exports.serialize = serialize; -exports.deserialize = deserialize; -exports.is = is; -exports.convertBits = convertBits; -exports.encode = encode; -exports.decode = decode; -exports.test = test; +module.exports = BECH32; diff --git a/node_modules/bcrypto/lib/native/binding.js b/node_modules/bcrypto/lib/native/binding.js index 098fd5057..21d34d854 100644 --- a/node_modules/bcrypto/lib/native/binding.js +++ b/node_modules/bcrypto/lib/native/binding.js @@ -16,38 +16,39 @@ const binding = require('loady')('bcrypto', __dirname); binding.hashes = { __proto__: null, - BLAKE2B160: 0, - BLAKE2B256: 1, - BLAKE2B384: 2, - BLAKE2B512: 3, - BLAKE2S128: 4, - BLAKE2S160: 5, - BLAKE2S224: 6, - BLAKE2S256: 7, - GOST94: 8, - HASH160: 9, - HASH256: 10, - KECCAK224: 11, - KECCAK256: 12, - KECCAK384: 13, - KECCAK512: 14, - MD2: 15, - MD4: 16, - MD5: 17, - MD5SHA1: 18, - RIPEMD160: 19, - SHA1: 20, - SHA224: 21, - SHA256: 22, - SHA384: 23, - SHA512: 24, - SHA3_224: 25, - SHA3_256: 26, - SHA3_384: 27, - SHA3_512: 28, - SHAKE128: 29, - SHAKE256: 30, - WHIRLPOOL: 31 + NONE: 0, + BLAKE2B160: 1, + BLAKE2B256: 2, + BLAKE2B384: 3, + BLAKE2B512: 4, + BLAKE2S128: 5, + BLAKE2S160: 6, + BLAKE2S224: 7, + BLAKE2S256: 8, + GOST94: 9, + HASH160: 10, + HASH256: 11, + KECCAK224: 12, + KECCAK256: 13, + KECCAK384: 14, + KECCAK512: 15, + MD2: 16, + MD4: 17, + MD5: 18, + MD5SHA1: 19, + RIPEMD160: 20, + SHA1: 21, + SHA224: 22, + SHA256: 23, + SHA384: 24, + SHA512: 25, + SHA3_224: 26, + SHA3_256: 27, + SHA3_384: 28, + SHA3_512: 29, + SHAKE128: 30, + SHAKE256: 31, + WHIRLPOOL: 32 }; binding.curves = { diff --git a/node_modules/bcrypto/lib/native/ecdsa.js b/node_modules/bcrypto/lib/native/ecdsa.js index 9864fc2b4..e795fc486 100644 --- a/node_modules/bcrypto/lib/native/ecdsa.js +++ b/node_modules/bcrypto/lib/native/ecdsa.js @@ -351,7 +351,7 @@ class ECDSA { assert(Buffer.isBuffer(msg)); assert(Buffer.isBuffer(key)); - return binding.schnorr_legacy_sign(this._handle, msg, key); + return binding.bipschnorr_sign(this._handle, msg, key); } schnorrVerify(msg, sig, key) { @@ -360,7 +360,7 @@ class ECDSA { assert(Buffer.isBuffer(sig)); assert(Buffer.isBuffer(key)); - return binding.schnorr_legacy_verify(this._handle, msg, sig, key); + return binding.bipschnorr_verify(this._handle, msg, sig, key); } schnorrVerifyBatch(batch) { @@ -375,7 +375,7 @@ class ECDSA { assert(Buffer.isBuffer(item[2])); } - return binding.schnorr_legacy_verify_batch(this._handle, batch); + return binding.bipschnorr_verify_batch(this._handle, batch); } } diff --git a/node_modules/bcrypto/lib/native/schnorr-libsecp256k1.js b/node_modules/bcrypto/lib/native/schnorr-libsecp256k1.js index e1a1d1efa..6c3461f6d 100644 --- a/node_modules/bcrypto/lib/native/schnorr-libsecp256k1.js +++ b/node_modules/bcrypto/lib/native/schnorr-libsecp256k1.js @@ -312,7 +312,7 @@ function sign(msg, key, aux = binding.entropy(32)) { assert(Buffer.isBuffer(key)); assert(Buffer.isBuffer(aux)); - return binding.secp256k1_schnorr_sign(handle(), msg, key, aux); + return binding.secp256k1_bip340_sign(handle(), msg, key, aux); } /** @@ -328,7 +328,7 @@ function verify(msg, sig, key) { assert(Buffer.isBuffer(sig)); assert(Buffer.isBuffer(key)); - return binding.secp256k1_schnorr_verify(handle(), msg, sig, key); + return binding.secp256k1_bip340_verify(handle(), msg, sig, key); } /** @@ -348,7 +348,7 @@ function verifyBatch(batch) { assert(Buffer.isBuffer(item[2])); } - return binding.secp256k1_schnorr_verify_batch(handle(), batch); + return binding.secp256k1_bip340_verify_batch(handle(), batch); } /** diff --git a/node_modules/bcrypto/lib/native/schnorr-torsion.js b/node_modules/bcrypto/lib/native/schnorr-torsion.js index 22bad5ae6..d3d469e50 100644 --- a/node_modules/bcrypto/lib/native/schnorr-torsion.js +++ b/node_modules/bcrypto/lib/native/schnorr-torsion.js @@ -42,21 +42,21 @@ class Schnorr { privateKeyGenerate() { assert(this instanceof Schnorr); - return binding.schnorr_privkey_generate(this._handle, binding.entropy()); + return binding.bip340_privkey_generate(this._handle, binding.entropy()); } privateKeyVerify(key) { assert(this instanceof Schnorr); assert(Buffer.isBuffer(key)); - return binding.schnorr_privkey_verify(this._handle, key); + return binding.bip340_privkey_verify(this._handle, key); } privateKeyExport(key) { assert(this instanceof Schnorr); assert(Buffer.isBuffer(key)); - const [d, x, y] = binding.schnorr_privkey_export(this._handle, key); + const [d, x, y] = binding.bip340_privkey_export(this._handle, key); return { d, x, y }; } @@ -66,7 +66,7 @@ class Schnorr { assert(json && typeof json === 'object'); assert(Buffer.isBuffer(json.d)); - return binding.schnorr_privkey_import(this._handle, json.d); + return binding.bip340_privkey_import(this._handle, json.d); } privateKeyTweakAdd(key, tweak) { @@ -74,7 +74,7 @@ class Schnorr { assert(Buffer.isBuffer(key)); assert(Buffer.isBuffer(tweak)); - return binding.schnorr_privkey_tweak_add(this._handle, key, tweak); + return binding.bip340_privkey_tweak_add(this._handle, key, tweak); } privateKeyTweakMul(key, tweak) { @@ -82,28 +82,28 @@ class Schnorr { assert(Buffer.isBuffer(key)); assert(Buffer.isBuffer(tweak)); - return binding.schnorr_privkey_tweak_mul(this._handle, key, tweak); + return binding.bip340_privkey_tweak_mul(this._handle, key, tweak); } privateKeyInvert(key) { assert(this instanceof Schnorr); assert(Buffer.isBuffer(key)); - return binding.schnorr_privkey_invert(this._handle, key); + return binding.bip340_privkey_invert(this._handle, key); } publicKeyCreate(key) { assert(this instanceof Schnorr); assert(Buffer.isBuffer(key)); - return binding.schnorr_pubkey_create(this._handle, key); + return binding.bip340_pubkey_create(this._handle, key); } publicKeyFromUniform(bytes) { assert(this instanceof Schnorr); assert(Buffer.isBuffer(bytes)); - return binding.schnorr_pubkey_from_uniform(this._handle, bytes); + return binding.bip340_pubkey_from_uniform(this._handle, bytes); } publicKeyToUniform(key, hint = binding.hint()) { @@ -111,35 +111,35 @@ class Schnorr { assert(Buffer.isBuffer(key)); assert((hint >>> 0) === hint); - return binding.schnorr_pubkey_to_uniform(this._handle, key, hint); + return binding.bip340_pubkey_to_uniform(this._handle, key, hint); } publicKeyFromHash(bytes) { assert(this instanceof Schnorr); assert(Buffer.isBuffer(bytes)); - return binding.schnorr_pubkey_from_hash(this._handle, bytes); + return binding.bip340_pubkey_from_hash(this._handle, bytes); } publicKeyToHash(key) { assert(this instanceof Schnorr); assert(Buffer.isBuffer(key)); - return binding.schnorr_pubkey_to_hash(this._handle, key, binding.entropy()); + return binding.bip340_pubkey_to_hash(this._handle, key, binding.entropy()); } publicKeyVerify(key) { assert(this instanceof Schnorr); assert(Buffer.isBuffer(key)); - return binding.schnorr_pubkey_verify(this._handle, key); + return binding.bip340_pubkey_verify(this._handle, key); } publicKeyExport(key) { assert(this instanceof Schnorr); assert(Buffer.isBuffer(key)); - const [x, y] = binding.schnorr_pubkey_export(this._handle, key); + const [x, y] = binding.bip340_pubkey_export(this._handle, key); return { x, y }; } @@ -159,7 +159,7 @@ class Schnorr { assert(Buffer.isBuffer(x)); assert(Buffer.isBuffer(y)); - return binding.schnorr_pubkey_import(this._handle, x, y); + return binding.bip340_pubkey_import(this._handle, x, y); } publicKeyTweakAdd(key, tweak) { @@ -167,7 +167,7 @@ class Schnorr { assert(Buffer.isBuffer(key)); assert(Buffer.isBuffer(tweak)); - return binding.schnorr_pubkey_tweak_add(this._handle, key, tweak); + return binding.bip340_pubkey_tweak_add(this._handle, key, tweak); } publicKeyTweakMul(key, tweak) { @@ -175,7 +175,7 @@ class Schnorr { assert(Buffer.isBuffer(key)); assert(Buffer.isBuffer(tweak)); - return binding.schnorr_pubkey_tweak_mul(this._handle, key, tweak); + return binding.bip340_pubkey_tweak_mul(this._handle, key, tweak); } publicKeyTweakSum(key, tweak) { @@ -183,7 +183,7 @@ class Schnorr { assert(Buffer.isBuffer(key)); assert(Buffer.isBuffer(tweak)); - return binding.schnorr_pubkey_tweak_sum(this._handle, key, tweak); + return binding.bip340_pubkey_tweak_sum(this._handle, key, tweak); } publicKeyTweakCheck(key, tweak, expect, negated) { @@ -193,7 +193,7 @@ class Schnorr { assert(Buffer.isBuffer(expect)); assert(typeof negated === 'boolean'); - return binding.schnorr_pubkey_tweak_check(this._handle, key, + return binding.bip340_pubkey_tweak_check(this._handle, key, tweak, expect, negated); } @@ -204,7 +204,7 @@ class Schnorr { for (const key of keys) assert(Buffer.isBuffer(key)); - return binding.schnorr_pubkey_combine(this._handle, keys); + return binding.bip340_pubkey_combine(this._handle, keys); } sign(msg, key, aux = binding.entropy(32)) { @@ -216,7 +216,7 @@ class Schnorr { assert(Buffer.isBuffer(key)); assert(Buffer.isBuffer(aux)); - return binding.schnorr_sign(this._handle, msg, key, aux); + return binding.bip340_sign(this._handle, msg, key, aux); } verify(msg, sig, key) { @@ -225,7 +225,7 @@ class Schnorr { assert(Buffer.isBuffer(sig)); assert(Buffer.isBuffer(key)); - return binding.schnorr_verify(this._handle, msg, sig, key); + return binding.bip340_verify(this._handle, msg, sig, key); } verifyBatch(batch) { @@ -240,7 +240,7 @@ class Schnorr { assert(Buffer.isBuffer(item[2])); } - return binding.schnorr_verify_batch(this._handle, batch); + return binding.bip340_verify_batch(this._handle, batch); } derive(pub, priv) { @@ -248,7 +248,7 @@ class Schnorr { assert(Buffer.isBuffer(pub)); assert(Buffer.isBuffer(priv)); - return binding.schnorr_derive(this._handle, pub, priv); + return binding.bip340_derive(this._handle, pub, priv); } } diff --git a/node_modules/bcrypto/lib/native/secp256k1-libsecp256k1.js b/node_modules/bcrypto/lib/native/secp256k1-libsecp256k1.js index ca7d1151c..f46bcf51c 100644 --- a/node_modules/bcrypto/lib/native/secp256k1-libsecp256k1.js +++ b/node_modules/bcrypto/lib/native/secp256k1-libsecp256k1.js @@ -526,7 +526,7 @@ function schnorrSign(msg, key) { assert(Buffer.isBuffer(msg)); assert(Buffer.isBuffer(key)); - return binding.secp256k1_schnorr_legacy_sign(handle(), msg, key); + return binding.secp256k1_bipschnorr_sign(handle(), msg, key); } /** @@ -542,7 +542,7 @@ function schnorrVerify(msg, sig, key) { assert(Buffer.isBuffer(sig)); assert(Buffer.isBuffer(key)); - return binding.secp256k1_schnorr_legacy_verify(handle(), msg, sig, key); + return binding.secp256k1_bipschnorr_verify(handle(), msg, sig, key); } /** @@ -562,7 +562,7 @@ function schnorrVerifyBatch(batch) { assert(Buffer.isBuffer(item[2])); } - return binding.secp256k1_schnorr_legacy_verify_batch(handle(), batch); + return binding.secp256k1_bipschnorr_verify_batch(handle(), batch); } /* diff --git a/node_modules/bcrypto/package.json b/node_modules/bcrypto/package.json index a6dfe5291..6bd9a6ad5 100644 --- a/node_modules/bcrypto/package.json +++ b/node_modules/bcrypto/package.json @@ -1,6 +1,6 @@ { "name": "bcrypto", - "version": "5.4.0", + "version": "5.5.0", "description": "JS crypto library", "keywords": [ "cipher", @@ -108,7 +108,7 @@ "./lib/x25519": "./lib/x25519-browser.js", "./lib/x448": "./lib/x448-browser.js" }, - "_from": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.4.0", - "_resolved": "git+https://github.com/bcoin-org/bcrypto.git#b73dbc69884ecc790864e8ac513d627cdb0318d7", - "_commit": "b73dbc69884ecc790864e8ac513d627cdb0318d7" + "_from": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.5.0", + "_resolved": "git+https://github.com/bcoin-org/bcrypto.git#34738cf15033e3bce91a4f6f41ec1ebee3c2fdc8", + "_commit": "34738cf15033e3bce91a4f6f41ec1ebee3c2fdc8" } diff --git a/node_modules/bcrypto/src/bcrypto.c b/node_modules/bcrypto/src/bcrypto.c index 022589db1..b74a6269c 100644 --- a/node_modules/bcrypto/src/bcrypto.c +++ b/node_modules/bcrypto/src/bcrypto.c @@ -226,8 +226,8 @@ typedef struct bcrypto_wei_s { size_t field_size; size_t field_bits; size_t sig_size; - size_t legacy_size; - size_t schnorr_size; + size_t bipschnorr_size; + size_t bip340_size; } bcrypto_wei_curve_t; /* @@ -320,7 +320,7 @@ static void bcrypto_aead_destroy_(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(aead_t)); + torsion_memzero(data, sizeof(aead_t)); bcrypto_free(data); } @@ -331,8 +331,6 @@ bcrypto_aead_create(napi_env env, napi_callback_info info) { (void)info; - ctx->mode = -1; - CHECK(napi_create_external(env, ctx, bcrypto_aead_destroy_, @@ -378,9 +376,6 @@ bcrypto_aead_aad(napi_env env, napi_callback_info info) { CHECK(napi_get_value_external(env, argv[0], (void **)&ctx) == napi_ok); CHECK(napi_get_buffer_info(env, argv[1], (void **)&aad, &aad_len) == napi_ok); - JS_ASSERT(ctx->mode != -1, JS_ERR_INIT); - JS_ASSERT(ctx->mode == 0, JS_ERR_STATE); - aead_aad(ctx, aad, aad_len); return argv[0]; @@ -399,9 +394,6 @@ bcrypto_aead_encrypt(napi_env env, napi_callback_info info) { CHECK(napi_get_value_external(env, argv[0], (void **)&ctx) == napi_ok); CHECK(napi_get_buffer_info(env, argv[1], (void **)&msg, &msg_len) == napi_ok); - JS_ASSERT(ctx->mode != -1, JS_ERR_INIT); - JS_ASSERT(ctx->mode == 0 || ctx->mode == 1, JS_ERR_STATE); - aead_encrypt(ctx, msg, msg, msg_len); return argv[1]; @@ -420,9 +412,6 @@ bcrypto_aead_decrypt(napi_env env, napi_callback_info info) { CHECK(napi_get_value_external(env, argv[0], (void **)&ctx) == napi_ok); CHECK(napi_get_buffer_info(env, argv[1], (void **)&msg, &msg_len) == napi_ok); - JS_ASSERT(ctx->mode != -1, JS_ERR_INIT); - JS_ASSERT(ctx->mode == 0 || ctx->mode == 2, JS_ERR_STATE); - aead_decrypt(ctx, msg, msg, msg_len); return argv[1]; @@ -441,9 +430,6 @@ bcrypto_aead_auth(napi_env env, napi_callback_info info) { CHECK(napi_get_value_external(env, argv[0], (void **)&ctx) == napi_ok); CHECK(napi_get_buffer_info(env, argv[1], (void **)&msg, &msg_len) == napi_ok); - JS_ASSERT(ctx->mode != -1, JS_ERR_INIT); - JS_ASSERT(ctx->mode == 0 || ctx->mode == 3, JS_ERR_STATE); - aead_auth(ctx, msg, msg_len); return argv[1]; @@ -461,8 +447,6 @@ bcrypto_aead_final(napi_env env, napi_callback_info info) { CHECK(argc == 1); CHECK(napi_get_value_external(env, argv[0], (void **)&ctx) == napi_ok); - JS_ASSERT(ctx->mode != -1, JS_ERR_INIT); - aead_final(ctx, out); CHECK(napi_create_buffer_copy(env, 16, out, NULL, &result) == napi_ok); @@ -480,8 +464,6 @@ bcrypto_aead_destroy(napi_env env, napi_callback_info info) { CHECK(argc == 1); CHECK(napi_get_value_external(env, argv[0], (void **)&ctx) == napi_ok); - ctx->mode = -1; - return argv[0]; } @@ -501,7 +483,6 @@ bcrypto_aead_verify(napi_env env, napi_callback_info info) { CHECK(napi_get_value_external(env, argv[0], (void **)&ctx) == napi_ok); CHECK(napi_get_buffer_info(env, argv[1], (void **)&tag, &tag_len) == napi_ok); - JS_ASSERT(ctx->mode != -1, JS_ERR_INIT); JS_ASSERT(tag_len == 16, JS_ERR_TAG_SIZE); aead_final(ctx, mac); @@ -541,7 +522,7 @@ bcrypto_aead_static_encrypt(napi_env env, napi_callback_info info) { aead_encrypt(&ctx, msg, msg, msg_len); aead_final(&ctx, out); - torsion_cleanse(&ctx, sizeof(aead_t)); + torsion_memzero(&ctx, sizeof(aead_t)); CHECK(napi_create_buffer_copy(env, 16, out, NULL, &result) == napi_ok); @@ -579,7 +560,7 @@ bcrypto_aead_static_decrypt(napi_env env, napi_callback_info info) { aead_decrypt(&ctx, msg, msg, msg_len); aead_final(&ctx, mac); - torsion_cleanse(&ctx, sizeof(aead_t)); + torsion_memzero(&ctx, sizeof(aead_t)); ok = torsion_memequal(mac, tag, 16); @@ -617,7 +598,7 @@ bcrypto_aead_static_auth(napi_env env, napi_callback_info info) { aead_auth(&ctx, msg, msg_len); aead_final(&ctx, mac); - torsion_cleanse(&ctx, sizeof(aead_t)); + torsion_memzero(&ctx, sizeof(aead_t)); ok = torsion_memequal(mac, tag, 16); @@ -634,7 +615,7 @@ static void bcrypto_arc4_destroy_(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_arc4_t)); + torsion_memzero(data, sizeof(bcrypto_arc4_t)); bcrypto_free(data); } @@ -1540,8 +1521,8 @@ bcrypto_bcrypt_execute_(napi_env env, void *data) { w->error = JS_ERR_DERIVE; } - torsion_cleanse(w->pass, w->pass_len); - torsion_cleanse(w->salt, w->salt_len); + torsion_memzero(w->pass, w->pass_len); + torsion_memzero(w->salt, w->salt_len); } static void @@ -1760,24 +1741,27 @@ bcrypto_bcrypt_verify(napi_env env, napi_callback_info info) { static napi_value bcrypto_bech32_serialize(napi_env env, napi_callback_info info) { - napi_value argv[2]; - size_t argc = 2; + napi_value argv[3]; + size_t argc = 3; char str[BECH32_MAX_SERIALIZE_SIZE + 1]; char hrp[BECH32_MAX_HRP_SIZE + 2]; const uint8_t *data; size_t hrp_len, data_len; + uint32_t checksum; napi_value result; CHECK(napi_get_cb_info(env, info, &argc, argv, NULL, NULL) == napi_ok); - CHECK(argc == 2); + CHECK(argc == 3); CHECK(napi_get_value_string_latin1(env, argv[0], hrp, sizeof(hrp), &hrp_len) == napi_ok); CHECK(napi_get_buffer_info(env, argv[1], (void **)&data, &data_len) == napi_ok); + CHECK(napi_get_value_uint32(env, argv[2], &checksum) == napi_ok); JS_ASSERT(hrp_len != sizeof(hrp) - 1, JS_ERR_ENCODE); JS_ASSERT(hrp_len == strlen(hrp), JS_ERR_ENCODE); - JS_ASSERT(bech32_serialize(str, hrp, data, data_len), JS_ERR_ENCODE); + JS_ASSERT(bech32_serialize(str, hrp, data, data_len, checksum), + JS_ERR_ENCODE); CHECK(napi_create_string_latin1(env, str, NAPI_AUTO_LENGTH, &result) == napi_ok); @@ -1787,22 +1771,25 @@ bcrypto_bech32_serialize(napi_env env, napi_callback_info info) { static napi_value bcrypto_bech32_deserialize(napi_env env, napi_callback_info info) { - napi_value argv[1]; - size_t argc = 1; + napi_value argv[2]; + size_t argc = 2; char hrp[BECH32_MAX_HRP_SIZE + 1]; uint8_t data[BECH32_MAX_DESERIALIZE_SIZE]; char str[BECH32_MAX_SERIALIZE_SIZE + 2]; size_t data_len, str_len; + uint32_t checksum; napi_value hrpval, dataval, result; CHECK(napi_get_cb_info(env, info, &argc, argv, NULL, NULL) == napi_ok); - CHECK(argc == 1); + CHECK(argc == 2); CHECK(napi_get_value_string_latin1(env, argv[0], str, sizeof(str), &str_len) == napi_ok); + CHECK(napi_get_value_uint32(env, argv[1], &checksum) == napi_ok); JS_ASSERT(str_len != sizeof(str) - 1, JS_ERR_ENCODE); JS_ASSERT(str_len == strlen(str), JS_ERR_ENCODE); - JS_ASSERT(bech32_deserialize(hrp, data, &data_len, str), JS_ERR_ENCODE); + JS_ASSERT(bech32_deserialize(hrp, data, &data_len, str, checksum), + JS_ERR_ENCODE); CHECK(napi_create_string_latin1(env, hrp, NAPI_AUTO_LENGTH, &hrpval) == napi_ok); @@ -1819,21 +1806,23 @@ bcrypto_bech32_deserialize(napi_env env, napi_callback_info info) { static napi_value bcrypto_bech32_is(napi_env env, napi_callback_info info) { - napi_value argv[1]; - size_t argc = 1; + napi_value argv[2]; + size_t argc = 2; char str[BECH32_MAX_SERIALIZE_SIZE + 2]; size_t str_len; + uint32_t checksum; napi_value result; int ok; CHECK(napi_get_cb_info(env, info, &argc, argv, NULL, NULL) == napi_ok); - CHECK(argc == 1); + CHECK(argc == 2); CHECK(napi_get_value_string_latin1(env, argv[0], str, sizeof(str), &str_len) == napi_ok); + CHECK(napi_get_value_uint32(env, argv[1], &checksum) == napi_ok); ok = str_len != sizeof(str) - 1 && str_len == strlen(str) - && bech32_is(str); + && bech32_is(str, checksum); CHECK(napi_get_boolean(env, ok, &result) == napi_ok); @@ -1884,27 +1873,30 @@ bcrypto_bech32_convert_bits(napi_env env, napi_callback_info info) { static napi_value bcrypto_bech32_encode(napi_env env, napi_callback_info info) { - napi_value argv[3]; - size_t argc = 3; + napi_value argv[4]; + size_t argc = 4; char addr[BECH32_MAX_ENCODE_SIZE + 1]; char hrp[BECH32_MAX_HRP_SIZE + 2]; size_t hrp_len; uint32_t version; const uint8_t *data; size_t data_len; + uint32_t checksum; napi_value result; CHECK(napi_get_cb_info(env, info, &argc, argv, NULL, NULL) == napi_ok); - CHECK(argc == 3); + CHECK(argc == 4); CHECK(napi_get_value_string_latin1(env, argv[0], hrp, sizeof(hrp), &hrp_len) == napi_ok); CHECK(napi_get_value_uint32(env, argv[1], &version) == napi_ok); CHECK(napi_get_buffer_info(env, argv[2], (void **)&data, &data_len) == napi_ok); + CHECK(napi_get_value_uint32(env, argv[3], &checksum) == napi_ok); JS_ASSERT(hrp_len != sizeof(hrp) - 1, JS_ERR_ENCODE); JS_ASSERT(hrp_len == strlen(hrp), JS_ERR_ENCODE); - JS_ASSERT(bech32_encode(addr, hrp, version, data, data_len), JS_ERR_ENCODE); + JS_ASSERT(bech32_encode(addr, hrp, version, data, data_len, checksum), + JS_ERR_ENCODE); CHECK(napi_create_string_latin1(env, addr, NAPI_AUTO_LENGTH, &result) == napi_ok); @@ -1914,24 +1906,27 @@ bcrypto_bech32_encode(napi_env env, napi_callback_info info) { static napi_value bcrypto_bech32_decode(napi_env env, napi_callback_info info) { - napi_value argv[1]; - size_t argc = 1; + napi_value argv[2]; + size_t argc = 2; char hrp[BECH32_MAX_HRP_SIZE + 1]; unsigned int version; uint8_t data[BECH32_MAX_DECODE_SIZE]; char addr[BECH32_MAX_ENCODE_SIZE + 2]; size_t data_len, addr_len; + uint32_t checksum; napi_value hrpval, versionval, dataval, result; CHECK(napi_get_cb_info(env, info, &argc, argv, NULL, NULL) == napi_ok); - CHECK(argc == 1); + CHECK(argc == 2); CHECK(napi_get_value_string_latin1(env, argv[0], addr, sizeof(addr), &addr_len) == napi_ok); + CHECK(napi_get_value_uint32(env, argv[1], &checksum) == napi_ok); JS_ASSERT(addr_len != sizeof(addr) - 1, JS_ERR_ENCODE); JS_ASSERT(addr_len == strlen(addr), JS_ERR_ENCODE); - JS_ASSERT(bech32_decode(hrp, &version, data, &data_len, addr), JS_ERR_ENCODE); + JS_ASSERT(bech32_decode(hrp, &version, data, &data_len, addr, checksum), + JS_ERR_ENCODE); CHECK(napi_create_string_latin1(env, hrp, NAPI_AUTO_LENGTH, &hrpval) == napi_ok); @@ -1951,21 +1946,23 @@ bcrypto_bech32_decode(napi_env env, napi_callback_info info) { static napi_value bcrypto_bech32_test(napi_env env, napi_callback_info info) { - napi_value argv[1]; - size_t argc = 1; + napi_value argv[2]; + size_t argc = 2; char addr[BECH32_MAX_ENCODE_SIZE + 2]; size_t addr_len; + uint32_t checksum; napi_value result; int ok; CHECK(napi_get_cb_info(env, info, &argc, argv, NULL, NULL) == napi_ok); - CHECK(argc == 1); + CHECK(argc == 2); CHECK(napi_get_value_string_latin1(env, argv[0], addr, sizeof(addr), &addr_len) == napi_ok); + CHECK(napi_get_value_uint32(env, argv[1], &checksum) == napi_ok); ok = addr_len != sizeof(addr) - 1 && addr_len == strlen(addr) - && bech32_test(addr); + && bech32_test(addr,checksum); CHECK(napi_get_boolean(env, ok, &result) == napi_ok); @@ -1980,7 +1977,7 @@ static void bcrypto_blake2b_destroy(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_blake2b_t)); + torsion_memzero(data, sizeof(bcrypto_blake2b_t)); bcrypto_free(data); } @@ -2175,7 +2172,7 @@ static void bcrypto_blake2s_destroy(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_blake2s_t)); + torsion_memzero(data, sizeof(bcrypto_blake2s_t)); bcrypto_free(data); } @@ -2608,7 +2605,7 @@ static void bcrypto_chacha20_destroy_(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_chacha20_t)); + torsion_memzero(data, sizeof(bcrypto_chacha20_t)); bcrypto_free(data); } @@ -2726,7 +2723,7 @@ static void bcrypto_cipher_destroy_(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_cipher_t)); + torsion_memzero(data, sizeof(bcrypto_cipher_t)); bcrypto_free(data); } @@ -2745,9 +2742,6 @@ bcrypto_cipher_create(napi_env env, napi_callback_info info) { CHECK(napi_get_value_uint32(env, argv[1], &mode) == napi_ok); CHECK(napi_get_value_bool(env, argv[2], &encrypt) == napi_ok); - JS_ASSERT(type <= CIPHER_MAX, JS_ERR_CONTEXT); - JS_ASSERT(mode <= CIPHER_MODE_MAX, JS_ERR_CONTEXT); - cipher = bcrypto_xmalloc(sizeof(bcrypto_cipher_t)); cipher->type = type; cipher->mode = mode; @@ -3017,9 +3011,6 @@ bcrypto_cipher_encrypt(napi_env env, napi_callback_info info) { CHECK(napi_get_buffer_info(env, argv[3], (void **)&iv, &iv_len) == napi_ok); CHECK(napi_get_buffer_info(env, argv[4], (void **)&in, &in_len) == napi_ok); - JS_ASSERT(type <= CIPHER_MAX, JS_ERR_CONTEXT); - JS_ASSERT(mode <= CIPHER_MODE_MAX, JS_ERR_CONTEXT); - out_len = CIPHER_MAX_ENCRYPT_SIZE(in_len); JS_ASSERT(out_len <= MAX_BUFFER_LENGTH, JS_ERR_ALLOC); @@ -3060,9 +3051,6 @@ bcrypto_cipher_decrypt(napi_env env, napi_callback_info info) { CHECK(napi_get_buffer_info(env, argv[3], (void **)&iv, &iv_len) == napi_ok); CHECK(napi_get_buffer_info(env, argv[4], (void **)&in, &in_len) == napi_ok); - JS_ASSERT(type <= CIPHER_MAX, JS_ERR_CONTEXT); - JS_ASSERT(mode <= CIPHER_MODE_MAX, JS_ERR_CONTEXT); - out_len = CIPHER_MAX_DECRYPT_SIZE(in_len); JS_ASSERT(out_len <= MAX_BUFFER_LENGTH, JS_ERR_ALLOC); @@ -3098,7 +3086,7 @@ bcrypto_cleanse(napi_env env, napi_callback_info info) { CHECK(argc == 1); CHECK(napi_get_buffer_info(env, argv[0], (void **)&buf, &buf_len) == napi_ok); - torsion_cleanse(buf, buf_len); + torsion_memzero(buf, buf_len); return argv[0]; } @@ -3111,7 +3099,7 @@ static void bcrypto_ctr_drbg_destroy(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_ctr_drbg_t)); + torsion_memzero(data, sizeof(bcrypto_ctr_drbg_t)); bcrypto_free(data); } @@ -3265,7 +3253,7 @@ bcrypto_dsa_params_generate(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -3289,7 +3277,7 @@ bcrypto_dsa_execute_(napi_env env, void *data) { if (!dsa_params_generate(w->out, &w->out_len, w->bits, w->entropy)) w->error = JS_ERR_GENERATE; - torsion_cleanse(w->entropy, ENTROPY_SIZE); + torsion_memzero(w->entropy, ENTROPY_SIZE); } static void @@ -3357,7 +3345,7 @@ bcrypto_dsa_params_generate_async(napi_env env, napi_callback_info info) { CHECK(napi_queue_async_work(env, worker->work) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -3444,7 +3432,7 @@ bcrypto_dsa_params_import(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)key, key_len); + torsion_memzero((void *)key, key_len); return result; } @@ -3492,8 +3480,8 @@ bcrypto_dsa_privkey_create(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); - torsion_cleanse(out, out_len); + torsion_memzero((void *)entropy, entropy_len); + torsion_memzero(out, out_len); return result; } @@ -3580,8 +3568,8 @@ bcrypto_dsa_privkey_import(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)key, key_len); - torsion_cleanse(out, out_len); + torsion_memzero((void *)key, key_len); + torsion_memzero(out, out_len); return result; } @@ -3604,7 +3592,7 @@ bcrypto_dsa_privkey_export(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse(out, out_len); + torsion_memzero(out, out_len); return result; } @@ -3712,7 +3700,7 @@ bcrypto_dsa_pubkey_import(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)key, key_len); + torsion_memzero((void *)key, key_len); return result; } @@ -3809,7 +3797,7 @@ bcrypto_dsa_sign(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -3839,7 +3827,7 @@ bcrypto_dsa_sign_der(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -3915,7 +3903,7 @@ bcrypto_dsa_derive(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse(out, out_len); + torsion_memzero(out, out_len); return result; } @@ -3996,7 +3984,7 @@ bcrypto_ecdh_privkey_generate(napi_env env, napi_callback_info info) { NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -4251,7 +4239,7 @@ bcrypto_ecdh_pubkey_to_hash(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, ec->field_size * 2, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -4445,7 +4433,7 @@ bcrypto_ecdsa_privkey_generate(napi_env env, napi_callback_info info) { NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -4811,7 +4799,7 @@ bcrypto_ecdsa_pubkey_to_hash(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, ec->field_size * 2, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -5528,7 +5516,7 @@ bcrypto_eddsa_privkey_generate(napi_env env, napi_callback_info info) { NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -5706,7 +5694,7 @@ bcrypto_eddsa_scalar_generate(napi_env env, napi_callback_info info) { NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -6138,7 +6126,7 @@ bcrypto_eddsa_pubkey_to_hash(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, ec->field_size * 2, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -6873,7 +6861,7 @@ bcrypto_edwards_curve_randomize(napi_env env, napi_callback_info info) { edwards_curve_randomize(ec->ctx, entropy); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return argv[0]; } @@ -6886,7 +6874,7 @@ static void bcrypto_hash_destroy(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_hash_t)); + torsion_memzero(data, sizeof(bcrypto_hash_t)); bcrypto_free(data); } @@ -7086,7 +7074,7 @@ static void bcrypto_hash_drbg_destroy(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_hash_drbg_t)); + torsion_memzero(data, sizeof(bcrypto_hash_drbg_t)); bcrypto_free(data); } @@ -7256,7 +7244,7 @@ static void bcrypto_hmac_destroy(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_hmac_t)); + torsion_memzero(data, sizeof(bcrypto_hmac_t)); bcrypto_free(data); } @@ -7390,7 +7378,7 @@ static void bcrypto_hmac_drbg_destroy(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_hmac_drbg_t)); + torsion_memzero(data, sizeof(bcrypto_hmac_drbg_t)); bcrypto_free(data); } @@ -7497,7 +7485,7 @@ static void bcrypto_keccak_destroy(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_keccak_t)); + torsion_memzero(data, sizeof(bcrypto_keccak_t)); bcrypto_free(data); } @@ -7894,8 +7882,8 @@ bcrypto_pbkdf2_execute_(napi_env env, void *data) { w->error = JS_ERR_DERIVE; } - torsion_cleanse(w->pass, w->pass_len); - torsion_cleanse(w->salt, w->salt_len); + torsion_memzero(w->pass, w->pass_len); + torsion_memzero(w->salt, w->salt_len); } static void @@ -8101,7 +8089,7 @@ static void bcrypto_poly1305_destroy_(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_poly1305_t)); + torsion_memzero(data, sizeof(bcrypto_poly1305_t)); bcrypto_free(data); } @@ -8339,8 +8327,8 @@ bcrypto_rsa_privkey_generate(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); - torsion_cleanse(out, out_len); + torsion_memzero((void *)entropy, entropy_len); + torsion_memzero(out, out_len); return result; } @@ -8365,7 +8353,7 @@ bcrypto_rsa_execute_(napi_env env, void *data) { if (!rsa_privkey_generate(w->out, &w->out_len, w->bits, w->exp, w->entropy)) w->error = JS_ERR_GENERATE; - torsion_cleanse(w->entropy, ENTROPY_SIZE); + torsion_memzero(w->entropy, ENTROPY_SIZE); } static void @@ -8390,7 +8378,7 @@ bcrypto_rsa_complete_(napi_env env, napi_status status, void *data) { CHECK(napi_delete_async_work(env, w->work) == napi_ok); - torsion_cleanse(w->out, w->out_len); + torsion_memzero(w->out, w->out_len); bcrypto_free(w); } @@ -8438,7 +8426,7 @@ bcrypto_rsa_privkey_generate_async(napi_env env, napi_callback_info info) { CHECK(napi_queue_async_work(env, worker->work) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -8507,9 +8495,9 @@ bcrypto_rsa_privkey_import(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); - torsion_cleanse((void *)key, key_len); - torsion_cleanse(out, out_len); + torsion_memzero((void *)entropy, entropy_len); + torsion_memzero((void *)key, key_len); + torsion_memzero(out, out_len); return result; } @@ -8532,7 +8520,7 @@ bcrypto_rsa_privkey_export(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse(out, out_len); + torsion_memzero(out, out_len); return result; } @@ -8618,7 +8606,7 @@ bcrypto_rsa_pubkey_import(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)key, key_len); + torsion_memzero((void *)key, key_len); return result; } @@ -8669,7 +8657,7 @@ bcrypto_rsa_sign(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -8721,7 +8709,7 @@ bcrypto_rsa_encrypt(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -8749,8 +8737,8 @@ bcrypto_rsa_decrypt(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); - torsion_cleanse(out, out_len); + torsion_memzero((void *)entropy, entropy_len); + torsion_memzero(out, out_len); return result; } @@ -8786,7 +8774,7 @@ bcrypto_rsa_sign_pss(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -8848,7 +8836,7 @@ bcrypto_rsa_encrypt_oaep(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -8884,7 +8872,7 @@ bcrypto_rsa_decrypt_oaep(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -8916,7 +8904,7 @@ bcrypto_rsa_veil(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -8943,7 +8931,7 @@ bcrypto_rsa_unveil(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, out_len, out, NULL, &result) == napi_ok); - torsion_cleanse(out, out_len); + torsion_memzero(out, out_len); return result; } @@ -8956,7 +8944,7 @@ static void bcrypto_salsa20_destroy_(napi_env env, void *data, void *hint) { (void)env; (void)hint; - torsion_cleanse(data, sizeof(bcrypto_salsa20_t)); + torsion_memzero(data, sizeof(bcrypto_salsa20_t)); bcrypto_free(data); } @@ -9067,16 +9055,16 @@ bcrypto_salsa20_derive(napi_env env, napi_callback_info info) { } /* - * Schnorr + * Schnorr BIP340 */ static napi_value -bcrypto_schnorr_privkey_generate(napi_env env, napi_callback_info info) { +bcrypto_bip340_privkey_generate(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; const uint8_t *entropy; size_t entropy_len; - uint8_t out[SCHNORR_MAX_PRIV_SIZE]; + uint8_t out[BIP340_MAX_PRIV_SIZE]; bcrypto_wei_curve_t *ec; napi_value result; @@ -9088,7 +9076,7 @@ bcrypto_schnorr_privkey_generate(napi_env env, napi_callback_info info) { JS_ASSERT(entropy_len == ENTROPY_SIZE, JS_ERR_ENTROPY_SIZE); - schnorr_privkey_generate(ec->ctx, out, entropy); + bip340_privkey_generate(ec->ctx, out, entropy); CHECK(napi_create_buffer_copy(env, ec->scalar_size, @@ -9096,13 +9084,13 @@ bcrypto_schnorr_privkey_generate(napi_env env, napi_callback_info info) { NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } static napi_value -bcrypto_schnorr_privkey_verify(napi_env env, napi_callback_info info) { +bcrypto_bip340_privkey_verify(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; const uint8_t *priv; @@ -9117,7 +9105,7 @@ bcrypto_schnorr_privkey_verify(napi_env env, napi_callback_info info) { CHECK(napi_get_buffer_info(env, argv[1], (void **)&priv, &priv_len) == napi_ok); - ok = priv_len == ec->scalar_size && schnorr_privkey_verify(ec->ctx, priv); + ok = priv_len == ec->scalar_size && bip340_privkey_verify(ec->ctx, priv); CHECK(napi_get_boolean(env, ok, &result) == napi_ok); @@ -9125,10 +9113,10 @@ bcrypto_schnorr_privkey_verify(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_privkey_export(napi_env env, napi_callback_info info) { +bcrypto_bip340_privkey_export(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; - uint8_t d[SCHNORR_MAX_PRIV_SIZE]; + uint8_t d[BIP340_MAX_PRIV_SIZE]; uint8_t x[WEI_MAX_FIELD_SIZE]; uint8_t y[WEI_MAX_FIELD_SIZE]; const uint8_t *priv; @@ -9143,7 +9131,7 @@ bcrypto_schnorr_privkey_export(napi_env env, napi_callback_info info) { &priv_len) == napi_ok); JS_ASSERT(priv_len == ec->scalar_size, JS_ERR_PRIVKEY_SIZE); - JS_ASSERT(schnorr_privkey_export(ec->ctx, d, x, y, priv), JS_ERR_PRIVKEY); + JS_ASSERT(bip340_privkey_export(ec->ctx, d, x, y, priv), JS_ERR_PRIVKEY); CHECK(napi_create_buffer_copy(env, ec->scalar_size, d, NULL, &bd) == napi_ok); CHECK(napi_create_buffer_copy(env, ec->field_size, x, NULL, &bx) == napi_ok); @@ -9158,10 +9146,10 @@ bcrypto_schnorr_privkey_export(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_privkey_import(napi_env env, napi_callback_info info) { +bcrypto_bip340_privkey_import(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; - uint8_t out[SCHNORR_MAX_PRIV_SIZE]; + uint8_t out[BIP340_MAX_PRIV_SIZE]; const uint8_t *priv; size_t priv_len; bcrypto_wei_curve_t *ec; @@ -9173,7 +9161,7 @@ bcrypto_schnorr_privkey_import(napi_env env, napi_callback_info info) { CHECK(napi_get_buffer_info(env, argv[1], (void **)&priv, &priv_len) == napi_ok); - JS_ASSERT(schnorr_privkey_import(ec->ctx, out, priv, priv_len), + JS_ASSERT(bip340_privkey_import(ec->ctx, out, priv, priv_len), JS_ERR_PRIVKEY); CHECK(napi_create_buffer_copy(env, @@ -9186,10 +9174,10 @@ bcrypto_schnorr_privkey_import(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_privkey_tweak_add(napi_env env, napi_callback_info info) { +bcrypto_bip340_privkey_tweak_add(napi_env env, napi_callback_info info) { napi_value argv[3]; size_t argc = 3; - uint8_t out[SCHNORR_MAX_PRIV_SIZE]; + uint8_t out[BIP340_MAX_PRIV_SIZE]; const uint8_t *priv, *tweak; size_t priv_len, tweak_len; bcrypto_wei_curve_t *ec; @@ -9205,7 +9193,7 @@ bcrypto_schnorr_privkey_tweak_add(napi_env env, napi_callback_info info) { JS_ASSERT(priv_len == ec->scalar_size, JS_ERR_PRIVKEY_SIZE); JS_ASSERT(tweak_len == ec->scalar_size, JS_ERR_SCALAR_SIZE); - JS_ASSERT(schnorr_privkey_tweak_add(ec->ctx, out, priv, tweak), + JS_ASSERT(bip340_privkey_tweak_add(ec->ctx, out, priv, tweak), JS_ERR_PRIVKEY); CHECK(napi_create_buffer_copy(env, @@ -9218,10 +9206,10 @@ bcrypto_schnorr_privkey_tweak_add(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_privkey_tweak_mul(napi_env env, napi_callback_info info) { +bcrypto_bip340_privkey_tweak_mul(napi_env env, napi_callback_info info) { napi_value argv[3]; size_t argc = 3; - uint8_t out[SCHNORR_MAX_PRIV_SIZE]; + uint8_t out[BIP340_MAX_PRIV_SIZE]; const uint8_t *priv, *tweak; size_t priv_len, tweak_len; bcrypto_wei_curve_t *ec; @@ -9237,7 +9225,7 @@ bcrypto_schnorr_privkey_tweak_mul(napi_env env, napi_callback_info info) { JS_ASSERT(priv_len == ec->scalar_size, JS_ERR_PRIVKEY_SIZE); JS_ASSERT(tweak_len == ec->scalar_size, JS_ERR_SCALAR_SIZE); - JS_ASSERT(schnorr_privkey_tweak_mul(ec->ctx, out, priv, tweak), + JS_ASSERT(bip340_privkey_tweak_mul(ec->ctx, out, priv, tweak), JS_ERR_PRIVKEY); CHECK(napi_create_buffer_copy(env, @@ -9250,10 +9238,10 @@ bcrypto_schnorr_privkey_tweak_mul(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_privkey_invert(napi_env env, napi_callback_info info) { +bcrypto_bip340_privkey_invert(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; - uint8_t out[SCHNORR_MAX_PRIV_SIZE]; + uint8_t out[BIP340_MAX_PRIV_SIZE]; const uint8_t *priv; size_t priv_len; bcrypto_wei_curve_t *ec; @@ -9266,7 +9254,7 @@ bcrypto_schnorr_privkey_invert(napi_env env, napi_callback_info info) { &priv_len) == napi_ok); JS_ASSERT(priv_len == ec->scalar_size, JS_ERR_PRIVKEY_SIZE); - JS_ASSERT(schnorr_privkey_invert(ec->ctx, out, priv), JS_ERR_PRIVKEY); + JS_ASSERT(bip340_privkey_invert(ec->ctx, out, priv), JS_ERR_PRIVKEY); CHECK(napi_create_buffer_copy(env, ec->scalar_size, @@ -9278,10 +9266,10 @@ bcrypto_schnorr_privkey_invert(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_pubkey_create(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_create(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; - uint8_t out[SCHNORR_MAX_PUB_SIZE]; + uint8_t out[BIP340_MAX_PUB_SIZE]; const uint8_t *priv; size_t priv_len; bcrypto_wei_curve_t *ec; @@ -9294,7 +9282,7 @@ bcrypto_schnorr_pubkey_create(napi_env env, napi_callback_info info) { &priv_len) == napi_ok); JS_ASSERT(priv_len == ec->scalar_size, JS_ERR_PRIVKEY_SIZE); - JS_ASSERT(schnorr_pubkey_create(ec->ctx, out, priv), JS_ERR_PRIVKEY); + JS_ASSERT(bip340_pubkey_create(ec->ctx, out, priv), JS_ERR_PRIVKEY); CHECK(napi_create_buffer_copy(env, ec->field_size, @@ -9306,10 +9294,10 @@ bcrypto_schnorr_pubkey_create(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_pubkey_from_uniform(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_from_uniform(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; - uint8_t out[SCHNORR_MAX_PUB_SIZE]; + uint8_t out[BIP340_MAX_PUB_SIZE]; const uint8_t *data; size_t data_len; bcrypto_wei_curve_t *ec; @@ -9323,7 +9311,7 @@ bcrypto_schnorr_pubkey_from_uniform(napi_env env, napi_callback_info info) { JS_ASSERT(data_len == ec->field_size, JS_ERR_PREIMAGE_SIZE); - schnorr_pubkey_from_uniform(ec->ctx, out, data); + bip340_pubkey_from_uniform(ec->ctx, out, data); CHECK(napi_create_buffer_copy(env, ec->field_size, @@ -9335,7 +9323,7 @@ bcrypto_schnorr_pubkey_from_uniform(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_pubkey_to_uniform(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_to_uniform(napi_env env, napi_callback_info info) { napi_value argv[3]; size_t argc = 3; uint8_t out[WEI_MAX_FIELD_SIZE]; @@ -9353,7 +9341,7 @@ bcrypto_schnorr_pubkey_to_uniform(napi_env env, napi_callback_info info) { CHECK(napi_get_value_uint32(env, argv[2], &hint) == napi_ok); JS_ASSERT(pub_len == ec->field_size, JS_ERR_PUBKEY_SIZE); - JS_ASSERT(schnorr_pubkey_to_uniform(ec->ctx, out, pub, hint), JS_ERR_PUBKEY); + JS_ASSERT(bip340_pubkey_to_uniform(ec->ctx, out, pub, hint), JS_ERR_PUBKEY); CHECK(napi_create_buffer_copy(env, ec->field_size, out, NULL, &result) == napi_ok); @@ -9362,10 +9350,10 @@ bcrypto_schnorr_pubkey_to_uniform(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_pubkey_from_hash(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_from_hash(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; - uint8_t out[SCHNORR_MAX_PUB_SIZE]; + uint8_t out[BIP340_MAX_PUB_SIZE]; const uint8_t *data; size_t data_len; bcrypto_wei_curve_t *ec; @@ -9378,7 +9366,7 @@ bcrypto_schnorr_pubkey_from_hash(napi_env env, napi_callback_info info) { &data_len) == napi_ok); JS_ASSERT(data_len == ec->field_size * 2, JS_ERR_PREIMAGE_SIZE); - JS_ASSERT(schnorr_pubkey_from_hash(ec->ctx, out, data), JS_ERR_PREIMAGE); + JS_ASSERT(bip340_pubkey_from_hash(ec->ctx, out, data), JS_ERR_PREIMAGE); CHECK(napi_create_buffer_copy(env, ec->field_size, @@ -9390,7 +9378,7 @@ bcrypto_schnorr_pubkey_from_hash(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_pubkey_to_hash(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_to_hash(napi_env env, napi_callback_info info) { napi_value argv[3]; size_t argc = 3; uint8_t out[WEI_MAX_FIELD_SIZE * 2]; @@ -9409,19 +9397,19 @@ bcrypto_schnorr_pubkey_to_hash(napi_env env, napi_callback_info info) { JS_ASSERT(pub_len == ec->field_size, JS_ERR_PUBKEY_SIZE); JS_ASSERT(entropy_len == ENTROPY_SIZE, JS_ERR_ENTROPY_SIZE); - JS_ASSERT(schnorr_pubkey_to_hash(ec->ctx, out, pub, 0, entropy), + JS_ASSERT(bip340_pubkey_to_hash(ec->ctx, out, pub, 0, entropy), JS_ERR_PUBKEY); CHECK(napi_create_buffer_copy(env, ec->field_size * 2, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } static napi_value -bcrypto_schnorr_pubkey_verify(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_verify(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; const uint8_t *pub; @@ -9436,7 +9424,7 @@ bcrypto_schnorr_pubkey_verify(napi_env env, napi_callback_info info) { CHECK(napi_get_buffer_info(env, argv[1], (void **)&pub, &pub_len) == napi_ok); - ok = pub_len == ec->field_size && schnorr_pubkey_verify(ec->ctx, pub); + ok = pub_len == ec->field_size && bip340_pubkey_verify(ec->ctx, pub); CHECK(napi_get_boolean(env, ok, &result) == napi_ok); @@ -9444,7 +9432,7 @@ bcrypto_schnorr_pubkey_verify(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_pubkey_export(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_export(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; uint8_t x[WEI_MAX_FIELD_SIZE]; @@ -9461,7 +9449,7 @@ bcrypto_schnorr_pubkey_export(napi_env env, napi_callback_info info) { &pub_len) == napi_ok); JS_ASSERT(pub_len == ec->field_size, JS_ERR_PUBKEY_SIZE); - JS_ASSERT(schnorr_pubkey_export(ec->ctx, x, y, pub), JS_ERR_PUBKEY); + JS_ASSERT(bip340_pubkey_export(ec->ctx, x, y, pub), JS_ERR_PUBKEY); CHECK(napi_create_buffer_copy(env, ec->field_size, x, NULL, &bx) == napi_ok); CHECK(napi_create_buffer_copy(env, ec->field_size, y, NULL, &by) == napi_ok); @@ -9474,10 +9462,10 @@ bcrypto_schnorr_pubkey_export(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_pubkey_import(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_import(napi_env env, napi_callback_info info) { napi_value argv[3]; size_t argc = 3; - uint8_t out[SCHNORR_MAX_PUB_SIZE]; + uint8_t out[BIP340_MAX_PUB_SIZE]; const uint8_t *x, *y; size_t x_len, y_len; bcrypto_wei_curve_t *ec; @@ -9489,7 +9477,7 @@ bcrypto_schnorr_pubkey_import(napi_env env, napi_callback_info info) { CHECK(napi_get_buffer_info(env, argv[1], (void **)&x, &x_len) == napi_ok); CHECK(napi_get_buffer_info(env, argv[2], (void **)&y, &y_len) == napi_ok); - JS_ASSERT(schnorr_pubkey_import(ec->ctx, out, x, x_len, y, y_len), + JS_ASSERT(bip340_pubkey_import(ec->ctx, out, x, x_len, y, y_len), JS_ERR_PUBKEY); CHECK(napi_create_buffer_copy(env, @@ -9502,10 +9490,10 @@ bcrypto_schnorr_pubkey_import(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_pubkey_tweak_add(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_tweak_add(napi_env env, napi_callback_info info) { napi_value argv[3]; size_t argc = 3; - uint8_t out[SCHNORR_MAX_PUB_SIZE]; + uint8_t out[BIP340_MAX_PUB_SIZE]; const uint8_t *pub, *tweak; size_t pub_len, tweak_len; bcrypto_wei_curve_t *ec; @@ -9521,7 +9509,7 @@ bcrypto_schnorr_pubkey_tweak_add(napi_env env, napi_callback_info info) { JS_ASSERT(pub_len == ec->field_size, JS_ERR_PUBKEY_SIZE); JS_ASSERT(tweak_len == ec->scalar_size, JS_ERR_SCALAR_SIZE); - JS_ASSERT(schnorr_pubkey_tweak_add(ec->ctx, out, NULL, pub, tweak), + JS_ASSERT(bip340_pubkey_tweak_add(ec->ctx, out, NULL, pub, tweak), JS_ERR_PUBKEY); CHECK(napi_create_buffer_copy(env, @@ -9534,10 +9522,10 @@ bcrypto_schnorr_pubkey_tweak_add(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_pubkey_tweak_mul(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_tweak_mul(napi_env env, napi_callback_info info) { napi_value argv[3]; size_t argc = 3; - uint8_t out[SCHNORR_MAX_PUB_SIZE]; + uint8_t out[BIP340_MAX_PUB_SIZE]; const uint8_t *pub, *tweak; size_t pub_len, tweak_len; bcrypto_wei_curve_t *ec; @@ -9553,7 +9541,7 @@ bcrypto_schnorr_pubkey_tweak_mul(napi_env env, napi_callback_info info) { JS_ASSERT(pub_len == ec->field_size, JS_ERR_PUBKEY_SIZE); JS_ASSERT(tweak_len == ec->scalar_size, JS_ERR_SCALAR_SIZE); - JS_ASSERT(schnorr_pubkey_tweak_mul(ec->ctx, out, NULL, pub, tweak), + JS_ASSERT(bip340_pubkey_tweak_mul(ec->ctx, out, NULL, pub, tweak), JS_ERR_PUBKEY); CHECK(napi_create_buffer_copy(env, @@ -9566,10 +9554,10 @@ bcrypto_schnorr_pubkey_tweak_mul(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_pubkey_tweak_sum(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_tweak_sum(napi_env env, napi_callback_info info) { napi_value argv[3]; size_t argc = 3; - uint8_t out[SCHNORR_MAX_PUB_SIZE]; + uint8_t out[BIP340_MAX_PUB_SIZE]; int negated; const uint8_t *pub, *tweak; size_t pub_len, tweak_len; @@ -9586,7 +9574,7 @@ bcrypto_schnorr_pubkey_tweak_sum(napi_env env, napi_callback_info info) { JS_ASSERT(pub_len == ec->field_size, JS_ERR_PUBKEY_SIZE); JS_ASSERT(tweak_len == ec->scalar_size, JS_ERR_SCALAR_SIZE); - JS_ASSERT(schnorr_pubkey_tweak_add(ec->ctx, out, &negated, pub, tweak), + JS_ASSERT(bip340_pubkey_tweak_add(ec->ctx, out, &negated, pub, tweak), JS_ERR_PUBKEY); CHECK(napi_create_buffer_copy(env, @@ -9605,7 +9593,7 @@ bcrypto_schnorr_pubkey_tweak_sum(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_pubkey_tweak_check(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_tweak_check(napi_env env, napi_callback_info info) { napi_value argv[5]; size_t argc = 5; const uint8_t *pub, *tweak, *expect; @@ -9632,7 +9620,7 @@ bcrypto_schnorr_pubkey_tweak_check(napi_env env, napi_callback_info info) { goto fail; } - ok = schnorr_pubkey_tweak_add_check(ec->ctx, pub, tweak, expect, negated); + ok = bip340_pubkey_tweak_add_check(ec->ctx, pub, tweak, expect, negated); fail: CHECK(napi_get_boolean(env, ok, &result) == napi_ok); @@ -9641,10 +9629,10 @@ bcrypto_schnorr_pubkey_tweak_check(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_pubkey_combine(napi_env env, napi_callback_info info) { +bcrypto_bip340_pubkey_combine(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; - uint8_t out[SCHNORR_MAX_PUB_SIZE]; + uint8_t out[BIP340_MAX_PUB_SIZE]; uint32_t i, length; const uint8_t **pubs; size_t pub_len; @@ -9673,7 +9661,7 @@ bcrypto_schnorr_pubkey_combine(napi_env env, napi_callback_info info) { goto fail; } - ok = schnorr_pubkey_combine(ec->ctx, out, pubs, length); + ok = bip340_pubkey_combine(ec->ctx, out, pubs, length); fail: bcrypto_free((void *)pubs); @@ -9690,10 +9678,10 @@ bcrypto_schnorr_pubkey_combine(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_sign(napi_env env, napi_callback_info info) { +bcrypto_bip340_sign(napi_env env, napi_callback_info info) { napi_value argv[4]; size_t argc = 4; - uint8_t out[SCHNORR_MAX_SIG_SIZE]; + uint8_t out[BIP340_MAX_SIG_SIZE]; const uint8_t *msg, *priv, *aux; size_t msg_len, priv_len, aux_len; bcrypto_wei_curve_t *ec; @@ -9713,10 +9701,10 @@ bcrypto_schnorr_sign(napi_env env, napi_callback_info info) { if (aux_len == 0) aux = NULL; - JS_ASSERT(schnorr_sign(ec->ctx, out, msg, msg_len, priv, aux), JS_ERR_SIGN); + JS_ASSERT(bip340_sign(ec->ctx, out, msg, msg_len, priv, aux), JS_ERR_SIGN); CHECK(napi_create_buffer_copy(env, - ec->schnorr_size, + ec->bip340_size, out, NULL, &result) == napi_ok); @@ -9725,7 +9713,7 @@ bcrypto_schnorr_sign(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_verify(napi_env env, napi_callback_info info) { +bcrypto_bip340_verify(napi_env env, napi_callback_info info) { napi_value argv[4]; size_t argc = 4; const uint8_t *msg, *sig, *pub; @@ -9741,9 +9729,9 @@ bcrypto_schnorr_verify(napi_env env, napi_callback_info info) { CHECK(napi_get_buffer_info(env, argv[2], (void **)&sig, &sig_len) == napi_ok); CHECK(napi_get_buffer_info(env, argv[3], (void **)&pub, &pub_len) == napi_ok); - ok = sig_len == ec->schnorr_size + ok = sig_len == ec->bip340_size && pub_len == ec->field_size - && schnorr_verify(ec->ctx, msg, msg_len, sig, pub); + && bip340_verify(ec->ctx, msg, msg_len, sig, pub); CHECK(napi_get_boolean(env, ok, &result) == napi_ok); @@ -9751,7 +9739,7 @@ bcrypto_schnorr_verify(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_verify_batch(napi_env env, napi_callback_info info) { +bcrypto_bip340_verify_batch(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; uint32_t i, length, item_len; @@ -9802,7 +9790,7 @@ bcrypto_schnorr_verify_batch(napi_env env, napi_callback_info info) { CHECK(napi_get_buffer_info(env, items[2], (void **)&pubs[i], &pub_len) == napi_ok); - if (sig_len != ec->schnorr_size || pub_len != ec->field_size) + if (sig_len != ec->bip340_size || pub_len != ec->field_size) goto fail; } @@ -9811,7 +9799,7 @@ bcrypto_schnorr_verify_batch(napi_env env, napi_callback_info info) { CHECK(ec->scratch != NULL); - ok = schnorr_verify_batch(ec->ctx, msgs, msg_lens, sigs, + ok = bip340_verify_batch(ec->ctx, msgs, msg_lens, sigs, pubs, length, ec->scratch); fail: @@ -9824,10 +9812,10 @@ bcrypto_schnorr_verify_batch(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_derive(napi_env env, napi_callback_info info) { +bcrypto_bip340_derive(napi_env env, napi_callback_info info) { napi_value argv[3]; size_t argc = 3; - uint8_t out[SCHNORR_MAX_PUB_SIZE]; + uint8_t out[BIP340_MAX_PUB_SIZE]; const uint8_t *pub, *priv; size_t pub_len, priv_len; bcrypto_wei_curve_t *ec; @@ -9842,7 +9830,7 @@ bcrypto_schnorr_derive(napi_env env, napi_callback_info info) { JS_ASSERT(pub_len == ec->field_size, JS_ERR_PUBKEY_SIZE); JS_ASSERT(priv_len == ec->scalar_size, JS_ERR_PRIVKEY_SIZE); - JS_ASSERT(schnorr_derive(ec->ctx, out, pub, priv), JS_ERR_PUBKEY); + JS_ASSERT(bip340_derive(ec->ctx, out, pub, priv), JS_ERR_PUBKEY); CHECK(napi_create_buffer_copy(env, ec->field_size, @@ -9858,10 +9846,10 @@ bcrypto_schnorr_derive(napi_env env, napi_callback_info info) { */ static napi_value -bcrypto_schnorr_legacy_sign(napi_env env, napi_callback_info info) { +bcrypto_bipschnorr_sign(napi_env env, napi_callback_info info) { napi_value argv[3]; size_t argc = 3; - uint8_t out[SCHNORR_LEGACY_MAX_SIG_SIZE]; + uint8_t out[BIPSCHNORR_MAX_SIG_SIZE]; const uint8_t *msg, *priv; size_t msg_len, priv_len; bcrypto_wei_curve_t *ec; @@ -9874,12 +9862,12 @@ bcrypto_schnorr_legacy_sign(napi_env env, napi_callback_info info) { CHECK(napi_get_buffer_info(env, argv[2], (void **)&priv, &priv_len) == napi_ok); - JS_ASSERT(schnorr_legacy_support(ec->ctx), JS_ERR_NO_SCHNORR); + JS_ASSERT(bipschnorr_support(ec->ctx), JS_ERR_NO_SCHNORR); JS_ASSERT(priv_len == ec->scalar_size, JS_ERR_PRIVKEY_SIZE); - JS_ASSERT(schnorr_legacy_sign(ec->ctx, out, msg, msg_len, priv), JS_ERR_SIGN); + JS_ASSERT(bipschnorr_sign(ec->ctx, out, msg, msg_len, priv), JS_ERR_SIGN); CHECK(napi_create_buffer_copy(env, - ec->legacy_size, + ec->bipschnorr_size, out, NULL, &result) == napi_ok); @@ -9888,7 +9876,7 @@ bcrypto_schnorr_legacy_sign(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_legacy_verify(napi_env env, napi_callback_info info) { +bcrypto_bipschnorr_verify(napi_env env, napi_callback_info info) { napi_value argv[4]; size_t argc = 4; const uint8_t *msg, *sig, *pub; @@ -9904,10 +9892,10 @@ bcrypto_schnorr_legacy_verify(napi_env env, napi_callback_info info) { CHECK(napi_get_buffer_info(env, argv[2], (void **)&sig, &sig_len) == napi_ok); CHECK(napi_get_buffer_info(env, argv[3], (void **)&pub, &pub_len) == napi_ok); - JS_ASSERT(schnorr_legacy_support(ec->ctx), JS_ERR_NO_SCHNORR); + JS_ASSERT(bipschnorr_support(ec->ctx), JS_ERR_NO_SCHNORR); - ok = sig_len == ec->legacy_size - && schnorr_legacy_verify(ec->ctx, msg, msg_len, sig, pub, pub_len); + ok = sig_len == ec->bipschnorr_size + && bipschnorr_verify(ec->ctx, msg, msg_len, sig, pub, pub_len); CHECK(napi_get_boolean(env, ok, &result) == napi_ok); @@ -9915,7 +9903,7 @@ bcrypto_schnorr_legacy_verify(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_schnorr_legacy_verify_batch(napi_env env, napi_callback_info info) { +bcrypto_bipschnorr_verify_batch(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; uint32_t i, length, item_len; @@ -9932,7 +9920,7 @@ bcrypto_schnorr_legacy_verify_batch(napi_env env, napi_callback_info info) { CHECK(napi_get_value_external(env, argv[0], (void **)&ec) == napi_ok); CHECK(napi_get_array_length(env, argv[1], &length) == napi_ok); - JS_ASSERT(schnorr_legacy_support(ec->ctx), JS_ERR_NO_SCHNORR); + JS_ASSERT(bipschnorr_support(ec->ctx), JS_ERR_NO_SCHNORR); if (length == 0) { CHECK(napi_get_boolean(env, true, &result) == napi_ok); @@ -9969,7 +9957,7 @@ bcrypto_schnorr_legacy_verify_batch(napi_env env, napi_callback_info info) { CHECK(napi_get_buffer_info(env, items[2], (void **)&pubs[i], &pub_lens[i]) == napi_ok); - if (sig_len != ec->legacy_size) + if (sig_len != ec->bipschnorr_size) goto fail; } @@ -9978,7 +9966,7 @@ bcrypto_schnorr_legacy_verify_batch(napi_env env, napi_callback_info info) { CHECK(ec->scratch != NULL); - ok = schnorr_legacy_verify_batch(ec->ctx, msgs, msg_lens, sigs, + ok = bipschnorr_verify_batch(ec->ctx, msgs, msg_lens, sigs, pubs, pub_lens, length, ec->scratch); fail: @@ -10055,8 +10043,8 @@ bcrypto_scrypt_execute_(napi_env env, void *data) { w->error = JS_ERR_DERIVE; } - torsion_cleanse(w->pass, w->pass_len); - torsion_cleanse(w->salt, w->salt_len); + torsion_memzero(w->pass, w->pass_len); + torsion_memzero(w->salt, w->salt_len); } static void @@ -10222,7 +10210,7 @@ bcrypto_secp256k1_context_randomize(napi_env env, napi_callback_info info) { JS_ASSERT(entropy_len == 32, JS_ERR_ENTROPY_SIZE); JS_ASSERT(secp256k1_context_randomize(ec->ctx, entropy), JS_ERR_RANDOM); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return argv[0]; } @@ -10249,7 +10237,7 @@ bcrypto_secp256k1_seckey_generate(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, 32, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -10629,7 +10617,7 @@ bcrypto_secp256k1_pubkey_to_hash(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, 64, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -11484,7 +11472,7 @@ bcrypto_secp256k1_derive(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_secp256k1_schnorr_legacy_sign(napi_env env, napi_callback_info info) { +bcrypto_secp256k1_bipschnorr_sign(napi_env env, napi_callback_info info) { napi_value argv[3]; size_t argc = 3; uint8_t out[64]; @@ -11510,7 +11498,7 @@ bcrypto_secp256k1_schnorr_legacy_sign(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_secp256k1_schnorr_legacy_verify(napi_env env, napi_callback_info info) { +bcrypto_secp256k1_bipschnorr_verify(napi_env env, napi_callback_info info) { napi_value argv[4]; size_t argc = 4; const uint8_t *msg, *sig, *pub; @@ -11537,7 +11525,7 @@ bcrypto_secp256k1_schnorr_legacy_verify(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_secp256k1_schnorr_legacy_verify_batch(napi_env env, +bcrypto_secp256k1_bipschnorr_verify_batch(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; @@ -11855,7 +11843,7 @@ bcrypto_secp256k1_xonly_to_hash(napi_env env, napi_callback_info info) { CHECK(napi_create_buffer_copy(env, 64, out, NULL, &result) == napi_ok); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return result; } @@ -12170,7 +12158,7 @@ bcrypto_secp256k1_xonly_combine(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_secp256k1_schnorr_sign(napi_env env, napi_callback_info info) { +bcrypto_secp256k1_bip340_sign(napi_env env, napi_callback_info info) { napi_value argv[4]; size_t argc = 4; uint8_t out[64]; @@ -12209,7 +12197,7 @@ bcrypto_secp256k1_schnorr_sign(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_secp256k1_schnorr_verify(napi_env env, napi_callback_info info) { +bcrypto_secp256k1_bip340_verify(napi_env env, napi_callback_info info) { napi_value argv[4]; size_t argc = 4; const uint8_t *msg, *sig, *pub; @@ -12236,7 +12224,7 @@ bcrypto_secp256k1_schnorr_verify(napi_env env, napi_callback_info info) { } static napi_value -bcrypto_secp256k1_schnorr_verify_batch(napi_env env, napi_callback_info info) { +bcrypto_secp256k1_bip340_verify_batch(napi_env env, napi_callback_info info) { napi_value argv[2]; size_t argc = 2; uint32_t i, length, item_len; @@ -12645,8 +12633,8 @@ bcrypto_wei_curve_create(napi_env env, napi_callback_info info) { ec->field_size = wei_curve_field_size(ec->ctx); ec->field_bits = wei_curve_field_bits(ec->ctx); ec->sig_size = ecdsa_sig_size(ec->ctx); - ec->legacy_size = schnorr_legacy_sig_size(ec->ctx); - ec->schnorr_size = schnorr_sig_size(ec->ctx); + ec->bipschnorr_size = bipschnorr_sig_size(ec->ctx); + ec->bip340_size = bip340_sig_size(ec->ctx); CHECK(napi_create_external(env, ec, @@ -12705,7 +12693,7 @@ bcrypto_wei_curve_randomize(napi_env env, napi_callback_info info) { wei_curve_randomize(ec->ctx, entropy); - torsion_cleanse((void *)entropy, entropy_len); + torsion_memzero((void *)entropy, entropy_len); return argv[0]; } @@ -13102,36 +13090,36 @@ NAPI_MODULE_INIT() { F(salsa20_destroy), F(salsa20_derive), - /* Schnorr */ - F(schnorr_privkey_generate), - F(schnorr_privkey_verify), - F(schnorr_privkey_export), - F(schnorr_privkey_import), - F(schnorr_privkey_tweak_add), - F(schnorr_privkey_tweak_mul), - F(schnorr_privkey_invert), - F(schnorr_pubkey_create), - F(schnorr_pubkey_from_uniform), - F(schnorr_pubkey_to_uniform), - F(schnorr_pubkey_from_hash), - F(schnorr_pubkey_to_hash), - F(schnorr_pubkey_verify), - F(schnorr_pubkey_export), - F(schnorr_pubkey_import), - F(schnorr_pubkey_tweak_add), - F(schnorr_pubkey_tweak_mul), - F(schnorr_pubkey_tweak_sum), - F(schnorr_pubkey_tweak_check), - F(schnorr_pubkey_combine), - F(schnorr_sign), - F(schnorr_verify), - F(schnorr_verify_batch), - F(schnorr_derive), + /* Schnorr BIP340*/ + F(bip340_privkey_generate), + F(bip340_privkey_verify), + F(bip340_privkey_export), + F(bip340_privkey_import), + F(bip340_privkey_tweak_add), + F(bip340_privkey_tweak_mul), + F(bip340_privkey_invert), + F(bip340_pubkey_create), + F(bip340_pubkey_from_uniform), + F(bip340_pubkey_to_uniform), + F(bip340_pubkey_from_hash), + F(bip340_pubkey_to_hash), + F(bip340_pubkey_verify), + F(bip340_pubkey_export), + F(bip340_pubkey_import), + F(bip340_pubkey_tweak_add), + F(bip340_pubkey_tweak_mul), + F(bip340_pubkey_tweak_sum), + F(bip340_pubkey_tweak_check), + F(bip340_pubkey_combine), + F(bip340_sign), + F(bip340_verify), + F(bip340_verify_batch), + F(bip340_derive), /* Schnorr Legacy */ - F(schnorr_legacy_sign), - F(schnorr_legacy_verify), - F(schnorr_legacy_verify_batch), + F(bipschnorr_sign), + F(bipschnorr_verify), + F(bipschnorr_verify_batch), /* Scrypt */ F(scrypt_derive), @@ -13177,9 +13165,9 @@ NAPI_MODULE_INIT() { F(secp256k1_recover), F(secp256k1_recover_der), F(secp256k1_derive), - F(secp256k1_schnorr_legacy_sign), - F(secp256k1_schnorr_legacy_verify), - F(secp256k1_schnorr_legacy_verify_batch), + F(secp256k1_bipschnorr_sign), + F(secp256k1_bipschnorr_verify), + F(secp256k1_bipschnorr_verify_batch), F(secp256k1_xonly_seckey_export), F(secp256k1_xonly_seckey_tweak_add), F(secp256k1_xonly_create), @@ -13195,9 +13183,9 @@ NAPI_MODULE_INIT() { F(secp256k1_xonly_tweak_sum), F(secp256k1_xonly_tweak_check), F(secp256k1_xonly_combine), - F(secp256k1_schnorr_sign), - F(secp256k1_schnorr_verify), - F(secp256k1_schnorr_verify_batch), + F(secp256k1_bip340_sign), + F(secp256k1_bip340_verify), + F(secp256k1_bip340_verify_batch), F(secp256k1_xonly_derive), #endif diff --git a/node_modules/bfilter/package.json b/node_modules/bfilter/package.json index 60465636f..28111a2aa 100644 --- a/node_modules/bfilter/package.json +++ b/node_modules/bfilter/package.json @@ -1,6 +1,6 @@ { "name": "bfilter", - "version": "2.2.0", + "version": "2.3.0", "description": "Bloom filters for javascript", "keywords": [ "bloom", @@ -20,7 +20,7 @@ "test": "bmocha --reporter spec test/*-test.js" }, "dependencies": { - "bcrypto": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.4.0", + "bcrypto": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.5.0", "bsert": "git+https://github.com/chjj/bsert.git#semver:~0.0.10", "bufio": "git+https://github.com/bcoin-org/bufio.git#semver:~1.0.6", "loady": "git+https://github.com/chjj/loady.git#semver:~0.0.1" @@ -31,7 +31,7 @@ "engines": { "node": ">=8.0.0" }, - "_from": "git+https://github.com/bcoin-org/bfilter.git#semver:~2.2.0", - "_resolved": "git+https://github.com/bcoin-org/bfilter.git#6b55648c9884520c2b93226503930c78539b8406", - "_commit": "6b55648c9884520c2b93226503930c78539b8406" + "_from": "git+https://github.com/bcoin-org/bfilter.git#semver:~2.3.0", + "_resolved": "git+https://github.com/bcoin-org/bfilter.git#70e42125f877191d340e8838a1a90fabb750e680", + "_commit": "70e42125f877191d340e8838a1a90fabb750e680" } diff --git a/node_modules/blgr/README.md b/node_modules/blgr/README.md index ee762b810..f1f4e0b7d 100644 --- a/node_modules/blgr/README.md +++ b/node_modules/blgr/README.md @@ -13,6 +13,16 @@ logger.warning('world'); logger.error('!'); ``` +## Changelog + +The `shrink` property has been removed, as well as the `truncate()` function. +Instead of deleting historical information from the log file at open, logger +will now "rotate" the log file when the file size reaches `MAX_FILE_SIZE` +(default about 20 MB). At that time, the file will be rotated out and +timestamped, and a new log file will be created. When the number of archival log +files reaches `MAX_ARCHIVAL_FILES` (default 10), the oldest archival files will +be removed from disk. + ## Contribution and License Agreement If you contribute code to this project, you are implicitly allowing your code diff --git a/node_modules/blgr/lib/fs.js b/node_modules/blgr/lib/fs.js index cf01b9015..b68252513 100644 --- a/node_modules/blgr/lib/fs.js +++ b/node_modules/blgr/lib/fs.js @@ -28,3 +28,8 @@ exports.read = promisify(fs.read); exports.write = promisify(fs.write); exports.ftruncate = promisify(fs.ftruncate); exports.createWriteStream = fs.createWriteStream; +exports.mkdir = promisify(fs.mkdir); +exports.rename = promisify(fs.rename); +exports.readdir = promisify(fs.readdir); +exports.stat = promisify(fs.stat); +exports.unlink = promisify(fs.unlink); diff --git a/node_modules/blgr/lib/logger.js b/node_modules/blgr/lib/logger.js index 2eea7c854..3d37a4c43 100644 --- a/node_modules/blgr/lib/logger.js +++ b/node_modules/blgr/lib/logger.js @@ -6,6 +6,7 @@ 'use strict'; +const Path = require('path'); const assert = require('bsert'); const format = require('./format'); const fs = require('./fs'); @@ -26,14 +27,19 @@ class Logger { constructor(options) { this.level = Logger.levels.NONE; this.colors = Logger.HAS_TTY; + this.maxFileSize = Logger.MAX_FILE_SIZE; + this.maxFiles = Logger.MAX_ARCHIVAL_FILES; this.console = true; - this.shrink = true; this.closed = true; this.closing = false; this.filename = null; this.stream = null; this.contexts = Object.create(null); this.fmt = format; + this.rotating = false; + + this._fileSize = 0; + this._buffer = []; if (options) this.set(options); @@ -68,15 +74,20 @@ class Logger { this.console = options.console; } - if (options.shrink != null) { - assert(typeof options.shrink === 'boolean'); - this.shrink = options.shrink; - } - if (options.filename != null) { assert(typeof options.filename === 'string', 'Bad file.'); this.filename = options.filename; } + + if (options.maxFileSize != null) { + assert((options.maxFileSize >>> 0) === options.maxFileSize); + this.maxFileSize = options.maxFileSize; + } + + if (options.maxFiles != null) { + assert((options.maxFiles >>> 0) === options.maxFiles); + this.maxFiles = options.maxFiles; + } } /** @@ -101,8 +112,7 @@ class Logger { return; } - if (this.shrink) - await this.truncate(); + this._fileSize = await this.getSize(); this.stream = await openStream(this.filename); this.stream.once('error', this.handleError.bind(this)); @@ -137,48 +147,101 @@ class Logger { this.stream = null; } + this._fileSize = 0; + this.closed = true; } /** - * Truncate the log file to the last 20mb. + * Rotate out the current log file. * @method * @private - * @returns {Promise} + * @returns {Promise} - Returns String */ - async truncate() { + async rotate() { + if (this.rotating) + return null; + if (!this.filename) - return; + return null; if (fs.unsupported) - return; + return null; - assert(!this.stream); + this.rotating = true; - let stat; - try { - stat = await fs.stat(this.filename); - } catch (e) { - if (e.code === 'ENOENT') - return; - throw e; + await this.close(); + + // Current log file is closed. Rename it. + const ext = Path.extname(this.filename); + const base = Path.basename(this.filename, ext); + const dir = Path.dirname(this.filename); + + const rename = Path.join(dir, base + '_' + dateString() + ext); + + await fs.rename(this.filename, rename); + + await this.open(); + + while (this._buffer.length > 0) { + const msg = this._buffer.shift(); + this.stream.write(msg); + this._fileSize += msg.length; } - const maxSize = Logger.MAX_FILE_SIZE; + this.rotating = false; + this.prune(dir, base, ext); + + return rename; + } + + /** + * Remove old log files + * @method + * @private + * @param {String} dir + * @param {String} base + * @param {String} ext + * @returns {Promise} - Returns Number + */ - if (stat.size <= maxSize + (maxSize / 10)) + async prune(dir, base, ext) { + // Find all the archival files in the target directory + const files = await fs.readdir(dir); + const re = new RegExp(`${base}_.*${ext}`); + const oldFiles = files.filter(filename => re.test(filename)); + + if (oldFiles.length <= this.maxFiles) return; - this.debug('Truncating log file to %dmb.', mb(maxSize)); + // Archival files are named with year-month-day-hour-min-sec + // so they should already be in order from oldest to newest. + // But just in case readdir() isn't reliable for this... + oldFiles.sort(); + + const prune = oldFiles.slice(0, -1 * this.maxFiles); + + for (const file of prune) + await fs.unlink(Path.join(dir, file)); + } - const fd = await fs.open(this.filename, 'r+'); - const data = Buffer.allocUnsafe(maxSize); + /** + * Get the size of the current log file in bytes. + * @method + * @private + * @returns {Promise} - Returns Number + */ - await fs.read(fd, data, 0, maxSize, stat.size - maxSize); - await fs.ftruncate(fd, maxSize); - await fs.write(fd, data, 0, maxSize, 0); - await fs.close(fd); + async getSize() { + try { + const stat = await fs.stat(this.filename); + return stat.size; + } catch (e) { + if (e.code === 'ENOENT') + return 0; + throw e; + } } /** @@ -372,7 +435,7 @@ class Logger { */ log(level, module, args) { - if (this.closed) + if (this.closed && !this.rotating) return; if (this.level < level) @@ -472,10 +535,10 @@ class Logger { assert(name, 'Invalid log level.'); - if (!this.stream) + if (!this.stream && !this.rotating) return; - if (this.closing) + if (this.closing && !this.rotating) return; const date = new Date().toISOString().slice(0, -5) + 'Z'; @@ -488,7 +551,14 @@ class Logger { msg += format(args, false); msg += '\n'; - this.stream.write(msg); + if (this.rotating) { + this._buffer.push(msg); + } else { + this.stream.write(msg); + this._fileSize += msg.length; + if (this._fileSize >= this.maxFileSize) + this.rotate(); + } } /** @@ -501,7 +571,7 @@ class Logger { */ logError(level, module, err) { - if (this.closed) + if (this.closed && !this.rotating) return; if (fs.unsupported && this.console) { @@ -792,6 +862,14 @@ Logger.HAS_TTY = Boolean(process.stdout && process.stdout.isTTY); Logger.MAX_FILE_SIZE = 20 << 20; +/** + * Maximum number of archival log files to keep on disk. + * @const {Number} + * @default + */ + +Logger.MAX_ARCHIVAL_FILES = 10; + /** * Available log levels. * @enum {Number} @@ -924,6 +1002,16 @@ function closeStream(stream) { }); } +function dateString() { + // '2019-10-28T19:02:45.122Z' + let now = new Date().toJSON(); + + // '2019-10-28_19-01-15-122' + now = now.replace(/:/g,'-').replace('T','_').replace('.','-').slice(0,-1); + + return now; +} + /* * Expose */ diff --git a/node_modules/blgr/package.json b/node_modules/blgr/package.json index 3a30e788b..68e183c24 100644 --- a/node_modules/blgr/package.json +++ b/node_modules/blgr/package.json @@ -1,6 +1,6 @@ { "name": "blgr", - "version": "0.1.8", + "version": "0.2.0", "description": "Logger for node.js", "keywords": [ "log", @@ -32,7 +32,7 @@ "./lib/fs": "./lib/fs-browser.js", "./lib/inspect": "./lib/inspect-browser.js" }, - "_from": "git+https://github.com/bcoin-org/blgr.git#semver:~0.1.7", - "_resolved": "git+https://github.com/bcoin-org/blgr.git#69c49d564b96e1ca0898ed039fca2edd614cddae", - "_commit": "69c49d564b96e1ca0898ed039fca2edd614cddae" + "_from": "git+https://github.com/bcoin-org/blgr.git#semver:~0.2.0", + "_resolved": "git+https://github.com/bcoin-org/blgr.git#050cbb587a1654a078468dbb92606330fdc4d120", + "_commit": "050cbb587a1654a078468dbb92606330fdc4d120" } diff --git a/package.json b/package.json index 64c28f803..5a5d2e9dd 100644 --- a/package.json +++ b/package.json @@ -23,17 +23,17 @@ "node": ">=10.0.0" }, "dependencies": { - "bcfg": "git+https://github.com/bcoin-org/bcfg.git#semver:~0.1.6", - "bcrypto": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.4.0", + "bcfg": "git+https://github.com/bcoin-org/bcfg.git#semver:~0.1.7", + "bcrypto": "git+https://github.com/bcoin-org/bcrypto.git#semver:~5.5.0", "bcurl": "git+https://github.com/bcoin-org/bcurl.git#semver:^0.1.6", "bdb": "git+https://github.com/bcoin-org/bdb.git#semver:~1.2.1", "bdns": "git+https://github.com/bcoin-org/bdns.git#semver:~0.1.5", "bevent": "git+https://github.com/bcoin-org/bevent.git#semver:~0.1.5", "bfile": "git+https://github.com/bcoin-org/bfile.git#semver:~0.2.1", - "bfilter": "git+https://github.com/bcoin-org/bfilter.git#semver:~2.2.0", + "bfilter": "git+https://github.com/bcoin-org/bfilter.git#semver:~2.3.0", "bheep": "git+https://github.com/bcoin-org/bheep.git#semver:~0.1.5", "binet": "git+https://github.com/bcoin-org/binet.git#semver:~0.3.5", - "blgr": "git+https://github.com/bcoin-org/blgr.git#semver:~0.1.7", + "blgr": "git+https://github.com/bcoin-org/blgr.git#semver:~0.2.0", "blru": "git+https://github.com/bcoin-org/blru.git#semver:~0.1.6", "blst": "git+https://github.com/bcoin-org/blst.git#semver:~0.1.5", "bmutex": "git+https://github.com/bcoin-org/bmutex.git#semver:~0.1.6", diff --git a/test/address-test.js b/test/address-test.js index 50ce38cd7..28971c616 100644 --- a/test/address-test.js +++ b/test/address-test.js @@ -3,6 +3,7 @@ 'use strict'; +const Network = require('../lib/protocol/network'); const Address = require('../lib/primitives/address'); const Script = require('../lib/script/script'); const assert = require('bsert'); @@ -191,4 +192,60 @@ describe('Address', function() { assert(fmt.includes('Address')); assert(fmt.includes('str=')); }); + + it('should pass all BIP350 test vectors for valid bech32 and bech32m', () => { + // https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki + // #test-vectors-for-v0-v16-native-segregated-witness-addresses + const vectors = [ + ['BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4', '0014751e76e8199196d454941c45d1b3a323f1433bd6'], + ['tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7', '00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262'], + ['bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kt5nd6y', '5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6'], + ['BC1SW50QGDZ25J', '6002751e'], + ['bc1zw508d6qejxtdg4y5r3zarvaryvaxxpcs', '5210751e76e8199196d454941c45d1b3a323'], + ['tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy', '0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433'], + ['tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c', '5120000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433'], + ['bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0', '512079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'] + ]; + + for (const [addr, script] of vectors) { + const parsed = Address.fromString(addr); + const buffer = Buffer.from(script, 'hex'); + + assert(parsed.isProgram()); + + assert.strictEqual(parsed.getType(), 'witness'); + + const byte = buffer[0]; + const version = byte ? byte - 0x50 : 0; + assert.strictEqual(version, parsed.version); + + assert.bufferEqual(buffer.slice(2), parsed.hash); + } + }); + + it('should identify witness (not version 0) address', () => { + // Generated with Bitcoin Core v22.0.0 in regtest + const addresses = [ + 'bcrt1pnmrmugapastum8ztvgwcn8hvq2avmcwh2j4ssru7rtyygkpqq98q4wyd6s', + 'bcrt1plhe602p84nkfdwyllskhaga3yysclz4daly2nyxhjrhvgsjy3v7s7vepr3', + 'bcrt1pavtamvgrt3hjjrz2zfx5dknx7urxj73d2apc98smmj53ddnvptrqcunafu', + 'bcrt1p6mnhu48geradgjtss5dhcnjqn7wu8xnnpd89ncs9fhdp8lkkkmasd2u7xy', + 'bcrt1px2pjntffzxj5wfx589qvr0zetdtxc8wup82ew3xk6u5ykfzgcjyqchpcvf', + 'bcrt1pu7tmahuyvfkk8v2mdlk77d3l9f9gs6rlkhm9r8xxfweh94qmhq9sl5hm07', + 'bcrt1p83djth2ga2kjt8jpel0yd6sz3jtzz75zt372ns634z28c0f6ax3s64vzpn', + 'bcrt1pm7x6crfd3su55x5rwnj9ud57x7hs7z5a0jqlja08wn6v7gp0hczst3jdkh' + ]; + + for (const addr of addresses) { + const parsed = Address.fromString(addr); + + assert.strictEqual(parsed.version, 1); + + const network = Network.get('regtest'); + assert.strictEqual( + parsed.getPrefix(network), + parsed.version + ); + } + }); }); diff --git a/test/bech32-test.js b/test/bech32-test.js index 9fb974570..1b3ffb464 100644 --- a/test/bech32-test.js +++ b/test/bech32-test.js @@ -49,29 +49,6 @@ const validAddresses = [ 0x62 ]) ], - [ - 'bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw50' - + '8d6qejxtdg4y5r3zarvary0c5xw7k7grplx', - Buffer.from([ - 0x81, 0x28, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, - 0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6, - 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 0x1c, - 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6 - ]) - ], - [ - 'BC1SW50QA3JX3S', - Buffer.from([ - 0x90, 0x02, 0x75, 0x1e - ]) - ], - [ - 'bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj', - Buffer.from([ - 0x82, 0x10, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, - 0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23 - ]) - ], [ 'tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy', Buffer.from([ @@ -109,7 +86,7 @@ const invalidAddresses = [ function createProgram(version, program) { const data = Buffer.allocUnsafe(2 + program.length); - data[0] = version ? version + 0x80 : 0; + data[0] = version ? version + 0x50 : 0; data[1] = program.length; program.copy(data, 2); return data; diff --git a/test/bech32m-test.js b/test/bech32m-test.js new file mode 100644 index 000000000..51272293b --- /dev/null +++ b/test/bech32m-test.js @@ -0,0 +1,131 @@ +'use strict'; + +const assert = require('bsert'); +const Address = require('../lib/primitives/address'); + +// see https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki +// for test vectors, they include both the valid and invalid addresses + +const validAddresses = [ + [ + 'bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kt5nd6y', + Buffer.from([ + 0x51, 0x28, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, + 0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6, + 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 0x1c, + 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6 + ]) + ], + [ + 'BC1SW50QGDZ25J', + Buffer.from([ + 0x60, 0x02, 0x75, 0x1e + ]) + ], + [ + 'bc1zw508d6qejxtdg4y5r3zarvaryvaxxpcs', + Buffer.from([ + 0x52, 0x10, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, + 0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23 + ]) + ], + [ + 'tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c', + Buffer.from([ + 0x51, 0x20, 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62, 0x21, + 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66, 0x36, 0x2b, 0x99, 0xd5, + 0xe9, 0x1c, 0x6c, 0xe2, 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, + 0x33 + ]) + ], + [ + 'bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0', + Buffer.from([ + 0x51, 0x20, 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, 0x55, + 0xa0, 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07, 0x02, 0x9b, 0xfc, 0xdb, + 0x2d, 0xce, 0x28, 0xd9, 0x59, 0xf2, 0x81, 0x5b, 0x16, 0xf8, 0x17, + 0x98 + ]) + ] +]; + +const invalidAddresses = [ + // invalid hrp + 'tc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq5zuyut', + // invalid checksum (Bech32 instead of Bech32m) + 'bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqh2y7hd', + // invalid checksum (Bech32 instead of Bech32m) + 'tb1z0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqglt7rf', + // invalid checksum (Bech32 instead of Bech32m) + 'BC1S0XLXVLHEMJA6C4DQV22UAPCTQUPFHLXM9H8Z3K2E72Q4K9HCZ7VQ54WELL', + // invalid checksum (Bech32m instead of Bech32) + 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kemeawh', + // invalid checksum (Bech32m instead of Bech32) + 'tb1q0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq24jc47', + // invalid character in checksum + 'bc1p38j9r5y49hruaue7wxjce0updqjuyyx0kh56v8s25huc6995vvpql3jow4', + // invalid witness version + 'BC130XLXVLHEMJA6C4DQV22UAPCTQUPFHLXM9H8Z3K2E72Q4K9HCZ7VQ7ZWS8R', + // invalid program length (1 byte) + 'bc1pw5dgrnzv', + // invalid program length (41 bytes) + 'bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7v8n0nx0muaewav253zgeav', + // invalid program length for witness version 0 + 'BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P', + // mixed case + 'tb1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq47Zagq', + // zero padding of more than 4 bits + 'bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7v07qwwzcrf', + // non-zero padding in 8-to-5 conversion + 'tb1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vpggkg4j', + // empty data section + 'bc1gmk9yu' +]; + +function createProgram(version, program) { + const data = Buffer.allocUnsafe(2 + program.length); + data[0] = version ? version + 0x50 : 0; + data[1] = program.length; + program.copy(data, 2); + return data; +} + +describe('Bech32m', function() { + for (const [addr, script] of validAddresses) { + it(`should have valid address for ${addr}`, () => { + let ret = null; + let network = null; + + try { + network = 'main'; + ret = Address.fromBech32m(addr, network); + } catch (e) { + ret = null; + } + + if (ret === null) { + try { + network = 'testnet'; + ret = Address.fromBech32m(addr, network); + } catch (e) { + ret = null; + } + } + + assert(ret !== null); + + const output = createProgram(ret.version, ret.hash); + assert.bufferEqual(output, script); + + const recreate = ret.toBech32m(network); + assert.strictEqual(recreate, addr.toLowerCase()); + }); + } + + for (const addr of invalidAddresses) { + it(`should have invalid address for ${addr}`, () => { + assert.throws(() => Address.fromBech32m(addr, 'main')); + assert.throws(() => Address.fromBech32m(addr, 'testnet')); + }); + } +}); diff --git a/test/indexer-test.js b/test/indexer-test.js index b6bf5ea18..2d5d62aea 100644 --- a/test/indexer-test.js +++ b/test/indexer-test.js @@ -10,6 +10,9 @@ const Script = require('../lib/script/script'); const Opcode = require('../lib/script/opcode'); const Address = require('../lib/primitives/address'); const Block = require('../lib/primitives/block'); +const TX = require('../lib/primitives/tx'); +const Output = require('../lib/primitives/output'); +const Input = require('../lib/primitives/input'); const Chain = require('../lib/blockchain/chain'); const WorkerPool = require('../lib/workers/workerpool'); const Miner = require('../lib/mining/miner'); @@ -55,6 +58,12 @@ const vectors = [ addr: '2Muy8nSQaMsMFAZwPyiXSEMTVFJv9iYuhwT', amount: 0.11, label: 'p2sh' + }, + // Same data part as version 0 p2wsh address but different witness version (1) + { + addr: 'bcrt1p2nj8e2nhmsa4hl9qw3xas7l5n2547h5uhlj47nc3pqfxaeq5rtjs0l3rl5', + amount: 0.22, + label: 'p2tr' } ]; @@ -239,7 +248,44 @@ describe('Indexer', function() { assert.equal(called, false); }); - it('should not index transaction w/ invalid address', async () => { + it('should not index tx w/ invalid address (witness v0)', async () => { + const indexer = new AddrIndexer({ + blocks: {}, + chain: {} + }); + + const ops = []; + + indexer.put = (key, value) => ops.push([key, value]); + indexer.del = (key, value) => ops.push([key, value]); + + // Create a witness program version 0 with + // 10 byte data push (BIP141 limits v0 to either 20 or 32). + const script = new Script(); + script.push(Opcode.fromSmall(0)); + script.push(Opcode.fromData(Buffer.alloc(10))); + script.compile(); + + const tx = new TX({ + inputs: [ + new Input() + ], + outputs: [ + new Output({script}) + ] + });; + + const entry = {height: 323549}; + const block = {txs: [tx]}; + const view = {}; + + indexer.indexBlock(entry, block, view); + indexer.unindexBlock(entry, block, view); + + assert.equal(ops.length, 0); + }); + + it('should not index tx w/ invalid address (witness v1)', async () => { const indexer = new AddrIndexer({ blocks: {}, chain: {} @@ -251,10 +297,47 @@ describe('Indexer', function() { indexer.del = (key, value) => ops.push([key, value]); // Create a witness program version 1 with - // 40 byte data push. + // 50 byte data push (40 is the BIP141 maximum). const script = new Script(); script.push(Opcode.fromSmall(1)); - script.push(Opcode.fromData(Buffer.alloc(40))); + script.push(Opcode.fromData(Buffer.alloc(50))); + script.compile(); + + const tx = new TX({ + inputs: [ + new Input() + ], + outputs: [ + new Output({script}) + ] + });; + + const entry = {height: 323549}; + const block = {txs: [tx]}; + const view = {}; + + indexer.indexBlock(entry, block, view); + indexer.unindexBlock(entry, block, view); + + assert.equal(ops.length, 0); + }); + + it('should index tx w/ valid address (witness v0)', async () => { + const indexer = new AddrIndexer({ + blocks: {}, + chain: {} + }); + + const ops = []; + + indexer.put = (key, value) => ops.push([key, value]); + indexer.del = (key, value) => ops.push([key, value]); + + // Create a witness program version 0 with + // 20 byte data push. + const script = new Script(); + script.push(Opcode.fromSmall(0)); + script.push(Opcode.fromData(Buffer.alloc(20))); script.compile(); const addr = Address.fromScript(script); @@ -270,10 +353,10 @@ describe('Indexer', function() { indexer.indexBlock(entry, block, view); indexer.unindexBlock(entry, block, view); - assert.equal(ops.length, 0); + assert.equal(ops.length, 6); }); - it('should index transaction w/ valid address', async () => { + it('should index tx w/ valid address (witness v1)', async () => { const indexer = new AddrIndexer({ blocks: {}, chain: {} @@ -284,10 +367,10 @@ describe('Indexer', function() { indexer.put = (key, value) => ops.push([key, value]); indexer.del = (key, value) => ops.push([key, value]); - // Create a witness program version 0 with + // Create a witness program version 1 with // 20 byte data push. const script = new Script(); - script.push(Opcode.fromSmall(0)); + script.push(Opcode.fromSmall(1)); script.push(Opcode.fromData(Buffer.alloc(20))); script.compile(); const addr = Address.fromScript(script); @@ -307,6 +390,40 @@ describe('Indexer', function() { assert.equal(ops.length, 6); }); + it('should index tx w/ valid address (witness v1, taproot)', async () => { + const indexer = new AddrIndexer({ + blocks: {}, + chain: {} + }); + + const ops = []; + + indexer.put = (key, value) => ops.push([key, value]); + indexer.del = (key, value) => ops.push([key, value]); + + // Create a witness program version 1 with + // 32 byte data push. + const script = new Script(); + script.push(Opcode.fromSmall(1)); + script.push(Opcode.fromData(Buffer.alloc(32))); + script.compile(); + const addr = Address.fromScript(script); + + const tx = { + getAddresses: () => [addr], + hash: () => Buffer.alloc(32) + }; + + const entry = {height: 323549}; + const block = {txs: [tx]}; + const view = {}; + + indexer.indexBlock(entry, block, view); + indexer.unindexBlock(entry, block, view); + + assert.equal(ops.length, 6); + }); + it('should error with limits', async () => { const indexer = new AddrIndexer({ blocks: {}, @@ -922,7 +1039,7 @@ describe('Indexer', function() { } } - await forValue(node.mempool.map, 'size', 20); + await forValue(node.mempool.map, 'size', 25); }); after(async () => { diff --git a/test/mempool-test.js b/test/mempool-test.js index 26b627cd1..be0dd998e 100644 --- a/test/mempool-test.js +++ b/test/mempool-test.js @@ -786,36 +786,74 @@ describe('Mempool', function() { }); describe('AddrIndexer', function () { - it('will not get key for witness program v1', function() { + it('will get key for witness program v0', function() { + const addrindex = new AddrIndexer(); + + // Create a witness program version 0 with + // 32 byte data push. + const script = new Script(); + script.push(Opcode.fromSmall(0)); + script.push(Opcode.fromData(Buffer.alloc(32))); + script.compile(); + const addr = Address.fromScript(script); + + const key = addrindex.getKey(addr); + + assert.bufferEqual(key, Buffer.from('00' + '00'.repeat(32), 'hex')); + }); + + it('will get key for witness program v1', function() { const addrindex = new AddrIndexer(); // Create a witness program version 1 with - // 40 byte data push. + // 32 byte data push. const script = new Script(); script.push(Opcode.fromSmall(1)); - script.push(Opcode.fromData(Buffer.alloc(40))); + script.push(Opcode.fromData(Buffer.alloc(32))); script.compile(); const addr = Address.fromScript(script); const key = addrindex.getKey(addr); - assert.strictEqual(key, null); + assert.bufferEqual(key, Buffer.from('01' + '00'.repeat(32), 'hex')); }); - it('will get key for witness program v0', function() { + it('will get key for witness program v15', function() { const addrindex = new AddrIndexer(); - // Create a witness program version 0 with + // Create a witness program version 15 with // 32 byte data push. const script = new Script(); - script.push(Opcode.fromSmall(0)); + script.push(Opcode.fromSmall(15)); script.push(Opcode.fromData(Buffer.alloc(32))); script.compile(); const addr = Address.fromScript(script); const key = addrindex.getKey(addr); - assert.bufferEqual(key, Buffer.from('0a' + '00'.repeat(32), 'hex')); + assert.bufferEqual(key, Buffer.from('0f' + '00'.repeat(32), 'hex')); + }); + + it('will get key for P2PKH', function() { + const addrindex = new AddrIndexer(); + + const script = Script.fromPubkeyhash(Buffer.alloc(20)); + const addr = Address.fromScript(script); + + const key = addrindex.getKey(addr); + + assert.bufferEqual(key, Buffer.from('80' + '00'.repeat(20), 'hex')); + }); + + it('will get key for P2SH', function() { + const addrindex = new AddrIndexer(); + + const script = Script.fromScripthash(Buffer.alloc(20)); + const addr = Address.fromScript(script); + + const key = addrindex.getKey(addr); + + assert.bufferEqual(key, Buffer.from('85' + '00'.repeat(20), 'hex')); }); });