Skip to content

Commit 5c632b0

Browse files
authored
Merge pull request #35 from napi-rs/argon2
Argon2
2 parents acd4acd + 6adc51d commit 5c632b0

File tree

40 files changed

+969
-2
lines changed

40 files changed

+969
-2
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
*.debug text eol=lf merge=union
1111

1212
# Generated codes
13+
packages/argon2/index.js linguist-detectable=false
14+
packages/argon2/index.d.ts linguist-detectable=false
1315
packages/bcrypt/index.js linguist-detectable=false
1416
packages/bcrypt/index.d.ts linguist-detectable=false
1517
packages/crc32/index.js linguist-detectable=false

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ cargo-features = ["strip"]
33
[workspace]
44
members = [
55
"./crates/alloc",
6+
"./packages/argon2",
67
"./packages/bcrypt",
78
"./packages/crc32",
89
"./packages/deno-lint",

packages/argon2/.npmignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
target
2+
Cargo.lock
3+
.cargo
4+
.github
5+
npm
6+
.eslintrc
7+
.prettierignore
8+
rustfmt.toml
9+
yarn.lock
10+
*.node

packages/argon2/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
edition = "2021"
3+
name = "node-rs_argon2"
4+
version = "0.0.0"
5+
6+
[lib]
7+
crate-type = ["cdylib"]
8+
9+
[dependencies]
10+
argon2 = {version = "0.3", features = ["parallel"]}
11+
napi = {version = "2", default-features = false, features = ["napi3"]}
12+
napi-derive = {version = "2", default-features = false, features = ["type-def"]}
13+
rand = {version = "0.8", features = ["nightly", "simd_support"]}
14+
15+
[build-dependencies]
16+
napi-build = "1"

packages/argon2/README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# `@node-rs/argon2`
2+
3+
![](https://github.com/napi-rs/node-rs/workflows/CI/badge.svg)
4+
![](https://img.shields.io/npm/dm/@node-rs/argon2.svg?sanitize=true)
5+
6+
[argon2](https://crates.io/crates/argon2) binding for Node.js.
7+
8+
## Support matrix
9+
10+
| | node12 | node14 | node16 | node17 |
11+
| ------------------- | ------ | ------ | ------ | ------ |
12+
| Windows x64 |||||
13+
| Windows x32 |||||
14+
| Windows arm64 |||||
15+
| macOS x64 |||||
16+
| macOS arm64(m chip) |||||
17+
| Linux x64 gnu |||||
18+
| Linux x64 musl |||||
19+
| Linux arm gnu |||||
20+
| Linux arm64 gnu |||||
21+
| Linux arm64 musl |||||
22+
| Android arm64 |||||
23+
| Android armv7 |||||
24+
| FreeBSD x64 |||||
25+
26+
## API
27+
28+
```typescript
29+
export const enum Algorithm {
30+
Argon2d = 0,
31+
Argon2i = 1,
32+
Argon2id = 2,
33+
}
34+
export const enum Version {
35+
V0x10 = 0,
36+
V0x13 = 1,
37+
}
38+
export interface Options {
39+
/**
40+
* Memory size, expressed in kilobytes, between 1 and (2^32)-1.
41+
* Value is an integer in decimal (1 to 10 digits).
42+
*/
43+
memoryCost?: number | undefined | null
44+
/**
45+
* Number of iterations, between 1 and (2^32)-1.
46+
* Value is an integer in decimal (1 to 10 digits).
47+
*/
48+
timeCost?: number | undefined | null
49+
/**
50+
* Degree of parallelism, between 1 and 255.
51+
* Value is an integer in decimal (1 to 3 digits).
52+
*/
53+
outputLen?: number | undefined | null
54+
parallelism?: number | undefined | null
55+
algorithm?: Algorithm | undefined | null
56+
version?: Version | undefined | null
57+
secret?: Buffer | undefined | null
58+
}
59+
export function hash(
60+
password: string | Buffer,
61+
options?: Options | undefined | null,
62+
abortSignal?: AbortSignal | undefined | null,
63+
): Promise<string>
64+
export function verify(
65+
hashed: string | Buffer,
66+
password: string | Buffer,
67+
options?: Options | undefined | null,
68+
abortSignal?: AbortSignal | undefined | null,
69+
): Promise<boolean>
70+
```
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { randomBytes } from 'crypto'
2+
3+
import test from 'ava'
4+
5+
import { Algorithm, hash, verify, Version } from '../index.js'
6+
7+
test('should be able to hash string', async (t) => {
8+
await t.notThrowsAsync(() => hash('whatever'))
9+
await t.notThrowsAsync(() =>
10+
hash('whatever', {
11+
secret: randomBytes(32),
12+
}),
13+
)
14+
})
15+
16+
test('should be able to verify hashed string', async (t) => {
17+
const PASSWORD = 'Argon2_is_the_best_algorithm_ever'
18+
t.true(await verify(await hash(PASSWORD), PASSWORD))
19+
t.true(
20+
await verify(
21+
await hash(PASSWORD, {
22+
algorithm: Algorithm.Argon2d,
23+
}),
24+
PASSWORD,
25+
),
26+
)
27+
t.true(
28+
await verify(
29+
await hash(PASSWORD, {
30+
algorithm: Algorithm.Argon2i,
31+
}),
32+
PASSWORD,
33+
),
34+
)
35+
const secret = randomBytes(32)
36+
t.true(
37+
await verify(
38+
await hash(PASSWORD, {
39+
algorithm: Algorithm.Argon2d,
40+
version: Version.V0x10,
41+
secret,
42+
}),
43+
PASSWORD,
44+
{
45+
secret,
46+
},
47+
),
48+
)
49+
})
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const { cpus } = require('os')
2+
3+
const nodeArgon2 = require('argon2')
4+
const { Suite } = require('benchmark')
5+
const chalk = require('chalk')
6+
7+
const { hash, verify, Algorithm } = require('../index')
8+
9+
const PASSWORD = '$v=19$m=4096,t=3,p=1$fyLYvmzgpBjDTP6QSypj3g$pb1Q3Urv1amxuFft0rGwKfEuZPhURRDV7TJqcBnwlGo'
10+
const CORES = cpus().length
11+
12+
const suite = new Suite('Hash with all cores')
13+
14+
suite
15+
.add(
16+
'@node-rs/argon',
17+
async (deferred) => {
18+
await hash(PASSWORD, {
19+
algorithm: Algorithm.Argon2id,
20+
parallelism: CORES,
21+
})
22+
deferred.resolve()
23+
},
24+
{ defer: true },
25+
)
26+
.add(
27+
'node-argon',
28+
async (deferred) => {
29+
await nodeArgon2.hash(PASSWORD, { type: nodeArgon2.argon2id, parallelism: CORES })
30+
deferred.resolve()
31+
},
32+
{
33+
defer: true,
34+
},
35+
)
36+
.on('cycle', function (event) {
37+
console.info(String(event.target))
38+
})
39+
.on('complete', function () {
40+
console.info(`${this.name} bench suite: Fastest is ${chalk.green(this.filter('fastest').map('name'))}`)
41+
})
42+
.run()

packages/argon2/build.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
extern crate napi_build;
2+
3+
fn main() {
4+
napi_build::setup();
5+
}

packages/argon2/index.d.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/* tslint:disable */
2+
/* eslint-disable */
3+
4+
/* auto-generated by NAPI-RS */
5+
6+
export class ExternalObject<T> {
7+
readonly '': {
8+
readonly '': unique symbol
9+
[K: symbol]: T
10+
}
11+
}
12+
export const enum Algorithm {
13+
Argon2d = 0,
14+
Argon2i = 1,
15+
Argon2id = 2,
16+
}
17+
export const enum Version {
18+
V0x10 = 0,
19+
V0x13 = 1,
20+
}
21+
export interface Options {
22+
/**
23+
* Memory size, expressed in kilobytes, between 1 and (2^32)-1.
24+
* Value is an integer in decimal (1 to 10 digits).
25+
*/
26+
memoryCost?: number | undefined | null
27+
/**
28+
* Number of iterations, between 1 and (2^32)-1.
29+
* Value is an integer in decimal (1 to 10 digits).
30+
*/
31+
timeCost?: number | undefined | null
32+
/**
33+
* Degree of parallelism, between 1 and 255.
34+
* Value is an integer in decimal (1 to 3 digits).
35+
*/
36+
outputLen?: number | undefined | null
37+
parallelism?: number | undefined | null
38+
algorithm?: Algorithm | undefined | null
39+
version?: Version | undefined | null
40+
secret?: Buffer | undefined | null
41+
}
42+
export function hash(
43+
password: string | Buffer,
44+
options?: Options | undefined | null,
45+
abortSignal?: AbortSignal | undefined | null,
46+
): Promise<string>
47+
export function verify(
48+
hashed: string | Buffer,
49+
password: string | Buffer,
50+
options?: Options | undefined | null,
51+
abortSignal?: AbortSignal | undefined | null,
52+
): Promise<boolean>

0 commit comments

Comments
 (0)