From c8c6f5aaed72f2733a08546c66eeab7fab689a70 Mon Sep 17 00:00:00 2001 From: yisibl Date: Fri, 31 Dec 2021 19:49:01 +0800 Subject: [PATCH 1/2] docs: [argon2]improve documentation and update TS definition files --- packages/argon2/README.md | 59 +++++++++++++++++++++++++++++++++----- packages/argon2/index.d.ts | 44 ++++++++++++++++++++++++---- packages/argon2/src/lib.rs | 45 +++++++++++++++++++++++------ 3 files changed, 127 insertions(+), 21 deletions(-) diff --git a/packages/argon2/README.md b/packages/argon2/README.md index 8d952a1b..e971b7fe 100644 --- a/packages/argon2/README.md +++ b/packages/argon2/README.md @@ -3,7 +3,29 @@ ![](https://github.com/napi-rs/node-rs/workflows/CI/badge.svg) ![](https://img.shields.io/npm/dm/@node-rs/argon2.svg?sanitize=true) -[argon2](https://crates.io/crates/argon2) binding for Node.js. +[RustCrypto: Argon2](https://crates.io/crates/argon2) binding for Node.js. + +Argon2 is a [key derivation function](https://en.wikipedia.org/wiki/Key_derivation_function) that was selected as the winner of the [Password Hashing Competition(PHC)](https://password-hashing.net) in July 2015. + +Argon2 summarizes the state of the art in the design of memory-hard functions and can be used to hash passwords for credential storage, key derivation, or other applications. + +It has a simple design aimed at the highest memory filling rate and effective use of multiple computing units, while still providing defense against tradeoff attacks (by exploiting the cache and memory organization of the recent processors). + +## Features + +- Faster performance. +- No node-gyp and postinstall. +- Cross-platform support, including [Apple M1](https://www.apple.com/newsroom/2020/11/apple-unleashes-m1/). +- Smaller file size after npm installation(476K vs [node-argon2](https://github.com/ranisalt/node-argon2) 3.7M). +- `@node-rs/argon2` supports all three algorithms: + + - Argon2i: Optimizes against GPU cracking attacks but vulnerable to side-channels. + Accesses the memory array in a password dependent order, reducing the possibility of time–memory tradeoff (TMTO) attacks. + - Argon2d: Optimized to resist side-channel attacks. + Accesses the memory array in a password independent order, increasing the possibility of time-memory tradeoff (TMTO) attacks. + - **Argon2id**: default value, this is the default algorithm for normative recommendations. + Hybrid that mixes Argon2i and Argon2d passes. + Uses the Argon2i approach for the first half pass over memory and Argon2d approach for subsequent passes. This effectively places it in the “middle” between the other two: it doesn’t provide as good TMTO/GPU cracking resistance as Argon2d, nor as good of side-channel resistance as Argon2i, but overall provides the most well-rounded approach to both classes of attacks. ## Support matrix @@ -23,6 +45,10 @@ | Android armv7 | ✓ | ✓ | ✓ | ✓ | | FreeBSD x64 | ✓ | ✓ | ✓ | ✓ | +# Benchmarks + +See [benchmark/](benchmark/argon2.js). + ## API ```typescript @@ -32,25 +58,44 @@ export const enum Algorithm { Argon2id = 2, } export const enum Version { + /** Version 16 (0x10 in hex) */ V0x10 = 0, + /** + * Default value + * Version 19 (0x13 in hex, default) + */ V0x13 = 1, } export interface Options { /** - * Memory size, expressed in kilobytes, between 1 and (2^32)-1. - * Value is an integer in decimal (1 to 10 digits). + * The amount of memory to be used by the hash function, in kilobytes. Each thread will have a memory pool of this size. Note that large values for highly concurrent usage will cause starvation and thrashing if your system memory gets full. + * + * Value is an integer in decimal (1 to 10 digits), between 1 and (2^32)-1. + * + * The default value is 4096, meaning a pool of 4 MiB per thread. */ memoryCost?: number | undefined | null /** - * Number of iterations, between 1 and (2^32)-1. - * Value is an integer in decimal (1 to 10 digits). + * The time cost is the amount of passes (iterations) used by the hash function. It increases hash strength at the cost of time required to compute. + * + * Value is an integer in decimal (1 to 10 digits), between 1 and (2^32)-1. + * + * The default value is 3. */ timeCost?: number | undefined | null /** - * Degree of parallelism, between 1 and 255. - * Value is an integer in decimal (1 to 3 digits). + * The hash length is the length of the hash function output in bytes. Note that the resulting hash is encoded with Base 64, so the digest will be ~1/3 longer. + * + * The default value is 32, which produces raw hashes of 32 bytes or digests of 43 characters. */ outputLen?: number | undefined | null + /** + * The amount of threads to compute the hash on. Each thread has a memory pool with memoryCost size. Note that changing it also changes the resulting hash. + * + * Value is an integer in decimal (1 to 3 digits), between 1 and 255. + * + * The default value is 1, meaning a single thread is used. + */ parallelism?: number | undefined | null algorithm?: Algorithm | undefined | null version?: Version | undefined | null diff --git a/packages/argon2/index.d.ts b/packages/argon2/index.d.ts index ae9df7f7..64466169 100644 --- a/packages/argon2/index.d.ts +++ b/packages/argon2/index.d.ts @@ -10,30 +10,62 @@ export class ExternalObject { } } export const enum Algorithm { + /** + * Optimizes against GPU cracking attacks but vulnerable to side-channels. + * Accesses the memory array in a password dependent order, reducing the possibility of time–memory tradeoff (TMTO) attacks. + */ Argon2d = 0, + /** + * Optimized to resist side-channel attacks. + * Accesses the memory array in a password independent order, increasing the possibility of time-memory tradeoff (TMTO) attacks. + */ Argon2i = 1, + /** + * Default value, this is the default algorithm for normative recommendations. + * Hybrid that mixes Argon2i and Argon2d passes. + * Uses the Argon2i approach for the first half pass over memory and Argon2d approach for subsequent passes. This effectively places it in the “middle” between the other two: it doesn’t provide as good TMTO/GPU cracking resistance as Argon2d, nor as good of side-channel resistance as Argon2i, but overall provides the most well-rounded approach to both classes of attacks. + */ Argon2id = 2, } export const enum Version { + /** Version 16 (0x10 in hex) */ V0x10 = 0, + /** + * Default value + * Version 19 (0x13 in hex, default) + */ V0x13 = 1, } export interface Options { /** - * Memory size, expressed in kilobytes, between 1 and (2^32)-1. - * Value is an integer in decimal (1 to 10 digits). + * The amount of memory to be used by the hash function, in kilobytes. Each thread will have a memory pool of this size. Note that large values for highly concurrent usage will cause starvation and thrashing if your system memory gets full. + * + * Value is an integer in decimal (1 to 10 digits), between 1 and (2^32)-1. + * + * The default value is 4096, meaning a pool of 4 MiB per thread. */ memoryCost?: number | undefined | null /** - * Number of iterations, between 1 and (2^32)-1. - * Value is an integer in decimal (1 to 10 digits). + * The time cost is the amount of passes (iterations) used by the hash function. It increases hash strength at the cost of time required to compute. + * + * Value is an integer in decimal (1 to 10 digits), between 1 and (2^32)-1. + * + * The default value is 3. */ timeCost?: number | undefined | null /** - * Degree of parallelism, between 1 and 255. - * Value is an integer in decimal (1 to 3 digits). + * The hash length is the length of the hash function output in bytes. Note that the resulting hash is encoded with Base 64, so the digest will be ~1/3 longer. + * + * The default value is 32, which produces raw hashes of 32 bytes or digests of 43 characters. */ outputLen?: number | undefined | null + /** + * The amount of threads to compute the hash on. Each thread has a memory pool with memoryCost size. Note that changing it also changes the resulting hash. + * + * Value is an integer in decimal (1 to 3 digits), between 1 and 255. + * + * The default value is 1, meaning a single thread is used. + */ parallelism?: number | undefined | null algorithm?: Algorithm | undefined | null version?: Version | undefined | null diff --git a/packages/argon2/src/lib.rs b/packages/argon2/src/lib.rs index 391fb021..fa1c4c2d 100644 --- a/packages/argon2/src/lib.rs +++ b/packages/argon2/src/lib.rs @@ -1,16 +1,26 @@ #![deny(clippy::all)] +use napi::bindgen_prelude::*; +use napi_derive::napi; + use argon2::{ password_hash::{rand_core::OsRng, PasswordHasher, PasswordVerifier, SaltString}, Argon2, }; -use napi::bindgen_prelude::*; -use napi_derive::napi; #[napi] pub enum Algorithm { + /// Optimizes against GPU cracking attacks but vulnerable to side-channels. + /// Accesses the memory array in a password dependent order, reducing the possibility of time–memory tradeoff (TMTO) attacks. Argon2d, + + /// Optimized to resist side-channel attacks. + /// Accesses the memory array in a password independent order, increasing the possibility of time-memory tradeoff (TMTO) attacks. Argon2i, + + /// Default value, this is the default algorithm for normative recommendations. + /// Hybrid that mixes Argon2i and Argon2d passes. + /// Uses the Argon2i approach for the first half pass over memory and Argon2d approach for subsequent passes. This effectively places it in the “middle” between the other two: it doesn’t provide as good TMTO/GPU cracking resistance as Argon2d, nor as good of side-channel resistance as Argon2i, but overall provides the most well-rounded approach to both classes of attacks. Argon2id, } @@ -27,7 +37,11 @@ impl Algorithm { #[napi] pub enum Version { + /// Version 16 (0x10 in hex) V0x10, + + /// Default value + /// Version 19 (0x13 in hex) V0x13, } @@ -44,15 +58,30 @@ impl Version { #[napi(object)] #[derive(Default)] pub struct Options { - /// Memory size, expressed in kilobytes, between 1 and (2^32)-1. - /// Value is an integer in decimal (1 to 10 digits). + /// The amount of memory to be used by the hash function, in kilobytes. Each thread will have a memory pool of this size. Note that large values for highly concurrent usage will cause starvation and thrashing if your system memory gets full. + /// + /// Value is an integer in decimal (1 to 10 digits), between 1 and (2^32)-1. + /// + /// The default value is 4096, meaning a pool of 4 MiB per thread. pub memory_cost: Option, - /// Number of iterations, between 1 and (2^32)-1. - /// Value is an integer in decimal (1 to 10 digits). + + /// The time cost is the amount of passes (iterations) used by the hash function. It increases hash strength at the cost of time required to compute. + /// + /// Value is an integer in decimal (1 to 10 digits), between 1 and (2^32)-1. + /// + /// The default value is 3. pub time_cost: Option, - /// Degree of parallelism, between 1 and 255. - /// Value is an integer in decimal (1 to 3 digits). + + /// The hash length is the length of the hash function output in bytes. Note that the resulting hash is encoded with Base 64, so the digest will be ~1/3 longer. + /// + /// The default value is 32, which produces raw hashes of 32 bytes or digests of 43 characters. pub output_len: Option, + + /// The amount of threads to compute the hash on. Each thread has a memory pool with memoryCost size. Note that changing it also changes the resulting hash. + /// + /// Value is an integer in decimal (1 to 3 digits), between 1 and 255. + /// + /// The default value is 1, meaning a single thread is used. pub parallelism: Option, pub algorithm: Option, pub version: Option, From beb451190e9b5e6e41e549eccc95b2120b465f3a Mon Sep 17 00:00:00 2001 From: yisibl Date: Fri, 31 Dec 2021 20:19:20 +0800 Subject: [PATCH 2/2] chore: add keywords and description in package.json --- packages/argon2/npm/android-arm-eabi/package.json | 12 ++++++++++++ packages/argon2/npm/android-arm64/package.json | 12 ++++++++++++ packages/argon2/npm/darwin-arm64/package.json | 12 ++++++++++++ packages/argon2/npm/darwin-x64/package.json | 12 ++++++++++++ packages/argon2/npm/freebsd-x64/package.json | 12 ++++++++++++ packages/argon2/npm/linux-arm-gnueabihf/package.json | 12 ++++++++++++ packages/argon2/npm/linux-arm64-gnu/package.json | 12 ++++++++++++ packages/argon2/npm/linux-arm64-musl/package.json | 12 ++++++++++++ packages/argon2/npm/linux-x64-gnu/package.json | 12 ++++++++++++ packages/argon2/npm/linux-x64-musl/package.json | 12 ++++++++++++ packages/argon2/npm/win32-arm64-msvc/package.json | 12 ++++++++++++ packages/argon2/npm/win32-ia32-msvc/package.json | 12 ++++++++++++ packages/argon2/npm/win32-x64-msvc/package.json | 12 ++++++++++++ packages/argon2/package.json | 12 ++++++++++++ 14 files changed, 168 insertions(+) diff --git a/packages/argon2/npm/android-arm-eabi/package.json b/packages/argon2/npm/android-arm-eabi/package.json index 5c28cdb1..60aca18e 100644 --- a/packages/argon2/npm/android-arm-eabi/package.json +++ b/packages/argon2/npm/android-arm-eabi/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.android-arm-eabi.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/npm/android-arm64/package.json b/packages/argon2/npm/android-arm64/package.json index 09fb1eb3..76a3cfc9 100644 --- a/packages/argon2/npm/android-arm64/package.json +++ b/packages/argon2/npm/android-arm64/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.android-arm64.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/npm/darwin-arm64/package.json b/packages/argon2/npm/darwin-arm64/package.json index a0b357c9..fde0397c 100644 --- a/packages/argon2/npm/darwin-arm64/package.json +++ b/packages/argon2/npm/darwin-arm64/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.darwin-arm64.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/npm/darwin-x64/package.json b/packages/argon2/npm/darwin-x64/package.json index b6fbf23e..bd3d2387 100644 --- a/packages/argon2/npm/darwin-x64/package.json +++ b/packages/argon2/npm/darwin-x64/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.darwin-x64.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/npm/freebsd-x64/package.json b/packages/argon2/npm/freebsd-x64/package.json index 3f8455af..bc97e9c4 100644 --- a/packages/argon2/npm/freebsd-x64/package.json +++ b/packages/argon2/npm/freebsd-x64/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.freebsd-x64.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/npm/linux-arm-gnueabihf/package.json b/packages/argon2/npm/linux-arm-gnueabihf/package.json index b3f373a0..9b10f92e 100644 --- a/packages/argon2/npm/linux-arm-gnueabihf/package.json +++ b/packages/argon2/npm/linux-arm-gnueabihf/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.linux-arm-gnueabihf.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/npm/linux-arm64-gnu/package.json b/packages/argon2/npm/linux-arm64-gnu/package.json index f51f729e..374565ab 100644 --- a/packages/argon2/npm/linux-arm64-gnu/package.json +++ b/packages/argon2/npm/linux-arm64-gnu/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.linux-arm64-gnu.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/npm/linux-arm64-musl/package.json b/packages/argon2/npm/linux-arm64-musl/package.json index 8524e160..cb56a9b9 100644 --- a/packages/argon2/npm/linux-arm64-musl/package.json +++ b/packages/argon2/npm/linux-arm64-musl/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.linux-arm64-musl.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/npm/linux-x64-gnu/package.json b/packages/argon2/npm/linux-x64-gnu/package.json index ebc2d737..ea28cbed 100644 --- a/packages/argon2/npm/linux-x64-gnu/package.json +++ b/packages/argon2/npm/linux-x64-gnu/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.linux-x64-gnu.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/npm/linux-x64-musl/package.json b/packages/argon2/npm/linux-x64-musl/package.json index 7b843dd2..663c28fa 100644 --- a/packages/argon2/npm/linux-x64-musl/package.json +++ b/packages/argon2/npm/linux-x64-musl/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.linux-x64-musl.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/npm/win32-arm64-msvc/package.json b/packages/argon2/npm/win32-arm64-msvc/package.json index 54baf728..ae974f6f 100644 --- a/packages/argon2/npm/win32-arm64-msvc/package.json +++ b/packages/argon2/npm/win32-arm64-msvc/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.win32-arm64-msvc.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/npm/win32-ia32-msvc/package.json b/packages/argon2/npm/win32-ia32-msvc/package.json index 83dc8c5c..0513e0cb 100644 --- a/packages/argon2/npm/win32-ia32-msvc/package.json +++ b/packages/argon2/npm/win32-ia32-msvc/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.win32-ia32-msvc.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/npm/win32-x64-msvc/package.json b/packages/argon2/npm/win32-x64-msvc/package.json index c47159fb..a6459524 100644 --- a/packages/argon2/npm/win32-x64-msvc/package.json +++ b/packages/argon2/npm/win32-x64-msvc/package.json @@ -11,6 +11,18 @@ "files": [ "argon2.win32-x64-msvc.node" ], + "description": "RustCrypto: Argon2 binding for Node.js", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/packages/argon2/package.json b/packages/argon2/package.json index 0e770b75..723da24e 100644 --- a/packages/argon2/package.json +++ b/packages/argon2/package.json @@ -1,8 +1,20 @@ { "name": "@node-rs/argon2", "version": "1.0.1", + "description": "RustCrypto: Argon2 binding for Node.js", "main": "index.js", "types": "index.d.ts", + "keywords": [ + "argon2", + "argon2-password", + "crypto", + "password", + "encryption", + "hashing", + "hash", + "secure", + "verify" + ], "napi": { "name": "argon2", "triples": {