From 0ca764133e3bfe20714a4fdbb7109a22a2a37ea6 Mon Sep 17 00:00:00 2001 From: Matthew Zipkin Date: Mon, 11 Oct 2021 11:47:49 -0400 Subject: [PATCH 1/8] pkg: update deps: bcrypto, blgr, bcfg --- CHANGELOG.md | 7 + lib/node/node.js | 4 +- node_modules/bcfg/lib/config.js | 1 + node_modules/bcfg/package.json | 8 +- .../deps/torsion/include/torsion/aead.h | 9 +- .../deps/torsion/include/torsion/cipher.h | 224 +- .../deps/torsion/include/torsion/common.h | 11 +- .../deps/torsion/include/torsion/drbg.h | 22 +- .../deps/torsion/include/torsion/dsa.h | 8 +- .../deps/torsion/include/torsion/ecc.h | 455 +-- .../deps/torsion/include/torsion/encoding.h | 22 +- .../deps/torsion/include/torsion/hash.h | 144 +- .../deps/torsion/include/torsion/ies.h | 6 +- .../deps/torsion/include/torsion/kdf.h | 21 +- .../deps/torsion/include/torsion/mac.h | 38 +- .../deps/torsion/include/torsion/rand.h | 18 +- .../deps/torsion/include/torsion/rsa.h | 21 +- .../deps/torsion/include/torsion/stream.h | 18 +- .../deps/torsion/include/torsion/util.h | 20 +- node_modules/bcrypto/deps/torsion/src/aead.c | 57 +- node_modules/bcrypto/deps/torsion/src/asn1.h | 38 +- node_modules/bcrypto/deps/torsion/src/bf.h | 39 + node_modules/bcrypto/deps/torsion/src/bio.h | 216 +- .../bcrypto/deps/torsion/src/cipher.c | 1553 +++++---- node_modules/bcrypto/deps/torsion/src/drbg.c | 53 +- node_modules/bcrypto/deps/torsion/src/dsa.c | 66 +- node_modules/bcrypto/deps/torsion/src/ecc.c | 607 ++-- .../bcrypto/deps/torsion/src/encoding.c | 171 +- .../deps/torsion/src/entropy/entropy.h | 30 +- .../bcrypto/deps/torsion/src/entropy/env.c | 20 +- .../bcrypto/deps/torsion/src/entropy/hw.c | 426 ++- .../bcrypto/deps/torsion/src/entropy/sys.c | 88 +- node_modules/bcrypto/deps/torsion/src/hash.c | 832 ++--- node_modules/bcrypto/deps/torsion/src/ies.c | 4 +- .../bcrypto/deps/torsion/src/internal.c | 14 +- .../bcrypto/deps/torsion/src/internal.h | 89 +- node_modules/bcrypto/deps/torsion/src/kdf.c | 84 +- node_modules/bcrypto/deps/torsion/src/mac.c | 316 +- node_modules/bcrypto/deps/torsion/src/mpi.c | 2948 +++++++++-------- node_modules/bcrypto/deps/torsion/src/mpi.h | 771 +++-- node_modules/bcrypto/deps/torsion/src/rand.c | 94 +- node_modules/bcrypto/deps/torsion/src/rsa.c | 143 +- .../bcrypto/deps/torsion/src/stream.c | 130 +- node_modules/bcrypto/deps/torsion/src/tls.h | 100 +- node_modules/bcrypto/deps/torsion/src/util.c | 35 +- node_modules/bcrypto/lib/bcrypto.js | 2 +- .../bcrypto/lib/encoding/bech32-browser.js | 3 +- node_modules/bcrypto/lib/encoding/bech32.js | 7 +- .../bcrypto/lib/encoding/bech32m-browser.js | 10 + node_modules/bcrypto/lib/encoding/bech32m.js | 15 + node_modules/bcrypto/lib/js/bech32.js | 541 +-- node_modules/bcrypto/lib/native/bech32.js | 83 +- node_modules/bcrypto/lib/native/binding.js | 65 +- node_modules/bcrypto/lib/native/ecdsa.js | 6 +- .../lib/native/schnorr-libsecp256k1.js | 6 +- .../bcrypto/lib/native/schnorr-torsion.js | 48 +- .../lib/native/secp256k1-libsecp256k1.js | 6 +- node_modules/bcrypto/package.json | 8 +- node_modules/bcrypto/src/bcrypto.c | 484 ++- node_modules/bfilter/package.json | 10 +- node_modules/blgr/README.md | 10 + node_modules/blgr/lib/fs.js | 5 + node_modules/blgr/lib/logger.js | 158 +- node_modules/blgr/package.json | 8 +- package.json | 8 +- 65 files changed, 6387 insertions(+), 5077 deletions(-) create mode 100644 node_modules/bcrypto/deps/torsion/src/bf.h create mode 100644 node_modules/bcrypto/lib/encoding/bech32m-browser.js create mode 100644 node_modules/bcrypto/lib/encoding/bech32m.js diff --git a/CHANGELOG.md b/CHANGELOG.md index aa4f02c9e..ba9e925a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Bcoin release notes & changelog +## unreleased + +- 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/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/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", From 1d9cceedf8e3ddbf8607e49528670e2e209b6c55 Mon Sep 17 00:00:00 2001 From: pradyuman Date: Fri, 3 Sep 2021 20:31:47 +0530 Subject: [PATCH 2/8] address, network: support for bech32m --- lib/primitives/address.js | 103 ++++++++++++++++++++++++++++++++++---- lib/protocol/network.js | 12 +++++ lib/protocol/networks.js | 12 +++-- test/bech32-test.js | 23 --------- 4 files changed, 112 insertions(+), 38 deletions(-) diff --git a/lib/primitives/address.js b/lib/primitives/address.js index a036d175d..ab66ddbc1 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'); @@ -148,12 +149,17 @@ class Address { case Address.types.SCRIPTHASH: return prefixes.scripthash; case Address.types.WITNESS: - if (this.hash.length === 20) + if (this.version === 0) { + if (this.hash.length === 20) return prefixes.witnesspubkeyhash; - if (this.hash.length === 32) - return prefixes.witnessscripthash; - + if (this.hash.length === 32) + return prefixes.witnessscripthash; + } + if (this.version === 1) { + if (this.hash.length === 32) + return prefixes.taproot; + } break; } @@ -223,7 +229,7 @@ class Address { const version = this.version; const hash = this.hash; - assert(version !== -1, + assert(version === 0, 'Cannot convert non-program address to bech32.'); network = Network.get(network); @@ -233,6 +239,29 @@ 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 bech32 address to bech32m'); + network = Network.get(network); + + const hrp = network.addressPrefix.bech32; + + return bech32m.encode(hrp, version, hash); + } + /** * Inject properties from string. * @private @@ -253,7 +282,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 +310,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); } @@ -386,6 +423,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 > 1 to bech32'); + // make sure HRP is correct. Network.fromBech32(hrp, network); @@ -404,6 +447,42 @@ 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 > 0, + 'Cannot convert non-program address 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,11 @@ 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) { - assert(hash.length === 20 || hash.length === 32, - 'Witness program hash is the wrong size.'); + if (type === Address.types.WITNESS) { + if (version === 0) { + assert(hash.length === 20 || hash.length === 32, + 'Witness version 0 program hash is the wrong size.'); + } } assert(hash.length >= 2 && hash.length <= 40, 'Hash is the wrong size.'); } diff --git a/lib/protocol/network.js b/lib/protocol/network.js index e3d9f0895..d2f5ecd37 100644 --- a/lib/protocol/network.js +++ b/lib/protocol/network.js @@ -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, 'bech32(m) address'); + } + /** * Convert the network to a string. * @returns {String} @@ -425,6 +436,7 @@ function cmpAddress(network, prefix) { case prefixes.scripthash: case prefixes.witnesspubkeyhash: case prefixes.witnessscripthash: + case prefixes.taproot: return true; } diff --git a/lib/protocol/networks.js b/lib/protocol/networks.js index 421a93680..7b9f99aba 100644 --- a/lib/protocol/networks.js +++ b/lib/protocol/networks.js @@ -435,7 +435,8 @@ main.addressPrefix = { scripthash: 0x05, witnesspubkeyhash: 0x06, witnessscripthash: 0x0a, - bech32: 'bc' + bech32: 'bc', + taproot: 0x0b }; /** @@ -690,7 +691,8 @@ testnet.addressPrefix = { scripthash: 0xc4, witnesspubkeyhash: 0x03, witnessscripthash: 0x28, - bech32: 'tb' + bech32: 'tb', + taproot: 0x29 }; testnet.requireStandard = false; @@ -852,7 +854,8 @@ regtest.addressPrefix = { scripthash: 0xc4, witnesspubkeyhash: 0x03, witnessscripthash: 0x28, - bech32: 'bcrt' + bech32: 'bcrt', + taproot: 0x29 }; regtest.requireStandard = false; @@ -1022,7 +1025,8 @@ simnet.addressPrefix = { scripthash: 0x7b, witnesspubkeyhash: 0x19, witnessscripthash: 0x28, - bech32: 'sb' + bech32: 'sb', + taproot: 0x29 }; simnet.requireStandard = false; diff --git a/test/bech32-test.js b/test/bech32-test.js index 9fb974570..5b36ae691 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([ From a8ec8e64b4250ee093a2b914535110ac4f686191 Mon Sep 17 00:00:00 2001 From: RajWorking Date: Mon, 13 Sep 2021 17:24:08 +0545 Subject: [PATCH 3/8] test: bech32m --- test/bech32m-test.js | 131 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 test/bech32m-test.js diff --git a/test/bech32m-test.js b/test/bech32m-test.js new file mode 100644 index 000000000..ba8603cb3 --- /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 + 0x80 : 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')); + }); + } +}); From 6ffe0fdbbd0e5814082376d7168a7d9a58e06dc0 Mon Sep 17 00:00:00 2001 From: Matthew Zipkin Date: Mon, 11 Oct 2021 12:28:29 -0400 Subject: [PATCH 4/8] test: fix witness version / opcode offset in bech32 tests --- test/bech32-test.js | 2 +- test/bech32m-test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/bech32-test.js b/test/bech32-test.js index 5b36ae691..1b3ffb464 100644 --- a/test/bech32-test.js +++ b/test/bech32-test.js @@ -86,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 index ba8603cb3..51272293b 100644 --- a/test/bech32m-test.js +++ b/test/bech32m-test.js @@ -84,7 +84,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; From 5b00a1f67db7c5e10264c0a0ed5ab5d4fe6c3359 Mon Sep 17 00:00:00 2001 From: Matthew Zipkin Date: Mon, 11 Oct 2021 14:38:52 -0400 Subject: [PATCH 5/8] network, address: cleanup bech32m parsing and test taproot addresses --- lib/primitives/address.js | 41 +++++++++++----------------- lib/protocol/network.js | 8 +++--- test/address-test.js | 57 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 30 deletions(-) diff --git a/lib/primitives/address.js b/lib/primitives/address.js index ab66ddbc1..1fb4d0189 100644 --- a/lib/primitives/address.js +++ b/lib/primitives/address.js @@ -229,9 +229,12 @@ class Address { const version = this.version; const hash = this.hash; - assert(version === 0, + 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; @@ -254,7 +257,8 @@ class Address { 'Cannot convert non-program address to bech32m.'); assert(version !== 0, - 'Cannot convert bech32 address to bech32m'); + 'Cannot convert version 0 program to bech32m address.'); + network = Network.get(network); const hrp = network.addressPrefix.bech32; @@ -427,7 +431,7 @@ class Address { 'Cannot convert non-program address to bech32'); assert(version === 0, - 'Cannot convert program version > 1 to bech32'); + 'Cannot convert program version > 0 to bech32'); // make sure HRP is correct. Network.fromBech32(hrp, network); @@ -462,8 +466,11 @@ class Address { const [hrp, version, hash] = bech32m.decode(data); + assert(version !== -1, + 'Cannot convert non-program address to bech32m'); + assert(version > 0, - 'Cannot convert non-program address to bech32m.'); + 'Cannot convert program version 0 to bech32m.'); // make sure HRP is correct. Network.fromBech32m(hrp, network); @@ -666,11 +673,9 @@ class Address { } else { assert(type === Address.types.WITNESS, 'Wrong version (non-witness).'); assert(version >= 0 && version <= 16, 'Bad program version.'); - if (type === Address.types.WITNESS) { - if (version === 0) { - assert(hash.length === 20 || hash.length === 32, - 'Witness version 0 program hash is the wrong size.'); - } + if (version === 0) { + assert(hash.length === 20 || hash.length === 32, + 'Witness version 0 program hash is the wrong size.'); } assert(hash.length >= 2 && hash.length <= 40, 'Hash is the wrong size.'); } @@ -859,21 +864,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 @@ -888,8 +878,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; @@ -920,6 +908,7 @@ class Address { return Address.types.SCRIPTHASH; case prefixes.witnesspubkeyhash: case prefixes.witnessscripthash: + case prefixes.taproot: return Address.types.WITNESS; default: throw new Error('Unknown address prefix.'); diff --git a/lib/protocol/network.js b/lib/protocol/network.js index d2f5ecd37..fa45475ee 100644 --- a/lib/protocol/network.js +++ b/lib/protocol/network.js @@ -323,16 +323,16 @@ 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, 'bech32(m) address'); - } + static fromBech32m(hrp, network) { + return Network.by(hrp, cmpBech32, network, 'bech32m address'); + } /** * Convert the network to a string. diff --git a/test/address-test.js b/test/address-test.js index 50ce38cd7..3b0db5f5f 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 taproot addresses', () => { + // 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), + network.addressPrefix.taproot + ); + } + }); }); From 06a5b2fb6068f44e75d85433188ce1ebc0118a65 Mon Sep 17 00:00:00 2001 From: Matthew Zipkin Date: Tue, 12 Oct 2021 17:52:45 -0400 Subject: [PATCH 6/8] bcoin-cli: fix hash/address handling in getTX() --- bin/bcoin-cli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From a40cb6360b66f2f0de729186b685e40a65557045 Mon Sep 17 00:00:00 2001 From: Matthew Zipkin Date: Wed, 13 Oct 2021 21:21:43 -0400 Subject: [PATCH 7/8] address: remove witness prefixes. Co-authored-by: Nodari Chkuaselidze --- lib/primitives/address.js | 59 ++++++++---------- lib/protocol/network.js | 9 +-- lib/protocol/networks.js | 20 ++---- test/address-test.js | 4 +- test/indexer-test.js | 125 +++++++++++++++++++++++++++++++++++--- test/mempool-test.js | 54 +++++++++++++--- 6 files changed, 197 insertions(+), 74 deletions(-) diff --git a/lib/primitives/address.js b/lib/primitives/address.js index 1fb4d0189..b7fa0e631 100644 --- a/lib/primitives/address.js +++ b/lib/primitives/address.js @@ -132,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; @@ -148,19 +165,6 @@ class Address { return prefixes.pubkeyhash; case Address.types.SCRIPTHASH: return prefixes.scripthash; - case Address.types.WITNESS: - if (this.version === 0) { - if (this.hash.length === 20) - return prefixes.witnesspubkeyhash; - - if (this.hash.length === 32) - return prefixes.witnessscripthash; - } - if (this.version === 1) { - if (this.hash.length === 32) - return prefixes.taproot; - } - break; } return -1; @@ -190,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.'); @@ -337,7 +341,7 @@ class Address { } /** - * Inject properties from serialized data. + * Decode base58. * @private * @param {Buffer} data * @throws Parse error @@ -347,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); } /** @@ -906,10 +899,6 @@ class Address { return Address.types.PUBKEYHASH; case prefixes.scripthash: return Address.types.SCRIPTHASH; - case prefixes.witnesspubkeyhash: - case prefixes.witnessscripthash: - case prefixes.taproot: - return Address.types.WITNESS; default: throw new Error('Unknown address prefix.'); } diff --git a/lib/protocol/network.js b/lib/protocol/network.js index fa45475ee..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'); } /** @@ -428,15 +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: - case prefixes.taproot: return true; } diff --git a/lib/protocol/networks.js b/lib/protocol/networks.js index 7b9f99aba..603392ea7 100644 --- a/lib/protocol/networks.js +++ b/lib/protocol/networks.js @@ -433,10 +433,7 @@ main.keyPrefix = { main.addressPrefix = { pubkeyhash: 0x00, scripthash: 0x05, - witnesspubkeyhash: 0x06, - witnessscripthash: 0x0a, - bech32: 'bc', - taproot: 0x0b + bech32: 'bc' }; /** @@ -689,10 +686,7 @@ testnet.keyPrefix = { testnet.addressPrefix = { pubkeyhash: 0x6f, scripthash: 0xc4, - witnesspubkeyhash: 0x03, - witnessscripthash: 0x28, - bech32: 'tb', - taproot: 0x29 + bech32: 'tb' }; testnet.requireStandard = false; @@ -852,10 +846,7 @@ regtest.keyPrefix = { regtest.addressPrefix = { pubkeyhash: 0x6f, scripthash: 0xc4, - witnesspubkeyhash: 0x03, - witnessscripthash: 0x28, - bech32: 'bcrt', - taproot: 0x29 + bech32: 'bcrt' }; regtest.requireStandard = false; @@ -1023,10 +1014,7 @@ simnet.keyPrefix = { simnet.addressPrefix = { pubkeyhash: 0x3f, scripthash: 0x7b, - witnesspubkeyhash: 0x19, - witnessscripthash: 0x28, - bech32: 'sb', - taproot: 0x29 + bech32: 'sb' }; simnet.requireStandard = false; diff --git a/test/address-test.js b/test/address-test.js index 3b0db5f5f..28971c616 100644 --- a/test/address-test.js +++ b/test/address-test.js @@ -223,7 +223,7 @@ describe('Address', function() { } }); - it('should identify taproot addresses', () => { + it('should identify witness (not version 0) address', () => { // Generated with Bitcoin Core v22.0.0 in regtest const addresses = [ 'bcrt1pnmrmugapastum8ztvgwcn8hvq2avmcwh2j4ssru7rtyygkpqq98q4wyd6s', @@ -244,7 +244,7 @@ describe('Address', function() { const network = Network.get('regtest'); assert.strictEqual( parsed.getPrefix(network), - network.addressPrefix.taproot + parsed.version ); } }); diff --git a/test/indexer-test.js b/test/indexer-test.js index b6bf5ea18..2d2013790 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'); @@ -239,7 +242,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 +291,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 +347,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 +361,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 +384,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: {}, 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')); }); }); From d6a13b01854f100a39c536bebf4d61aeacfd638e Mon Sep 17 00:00:00 2001 From: Matthew Zipkin Date: Thu, 14 Oct 2021 10:41:40 -0400 Subject: [PATCH 8/8] indexer: test and document witness version collisions --- CHANGELOG.md | 12 ++++++++++++ test/indexer-test.js | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba9e925a9..1937d96cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ ## 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 diff --git a/test/indexer-test.js b/test/indexer-test.js index 2d2013790..2d5d62aea 100644 --- a/test/indexer-test.js +++ b/test/indexer-test.js @@ -58,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' } ]; @@ -1033,7 +1039,7 @@ describe('Indexer', function() { } } - await forValue(node.mempool.map, 'size', 20); + await forValue(node.mempool.map, 'size', 25); }); after(async () => {