mirror of
https://github.com/cosmos/cosmjs.git
synced 2025-03-10 21:49:15 +00:00
Add custom argon2 Wasm implementation
This commit is contained in:
parent
79b147b644
commit
d3c8a276e1
@ -36,7 +36,7 @@
|
||||
"test-safari": "yarn pack-web && karma start --single-run --browsers Safari",
|
||||
"test": "yarn build-or-skip && yarn test-node",
|
||||
"coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet",
|
||||
"build": "rm -rf ./build && tsc",
|
||||
"build": "rm -rf ./build && tsc && cp -R src/pkg2 build",
|
||||
"build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build",
|
||||
"pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js"
|
||||
},
|
||||
|
@ -129,15 +129,15 @@ describe("Libsodium", () => {
|
||||
// 8 bytes
|
||||
await Argon2id.execute(password, fromHex("aabbccddeeff0011"), options)
|
||||
.then(() => fail("Argon2id with invalid salt length must not resolve"))
|
||||
.catch((e) => expect(e).toMatch(/invalid salt length/));
|
||||
.catch((e) => expect(e).toMatch(/invalid salt length/i));
|
||||
// 15 bytes
|
||||
await Argon2id.execute(password, fromHex("aabbccddeeff001122334455667788"), options)
|
||||
.then(() => fail("Argon2id with invalid salt length must not resolve"))
|
||||
.catch((e) => expect(e).toMatch(/invalid salt length/));
|
||||
.catch((e) => expect(e).toMatch(/invalid salt length/i));
|
||||
// 17 bytes
|
||||
await Argon2id.execute(password, fromHex("aabbccddeeff00112233445566778899aa"), options)
|
||||
.then(() => fail("Argon2id with invalid salt length must not resolve"))
|
||||
.catch((e) => expect(e).toMatch(/invalid salt length/));
|
||||
.catch((e) => expect(e).toMatch(/invalid salt length/i));
|
||||
// 32 bytes
|
||||
await Argon2id.execute(
|
||||
password,
|
||||
@ -145,7 +145,7 @@ describe("Libsodium", () => {
|
||||
options,
|
||||
)
|
||||
.then(() => fail("Argon2id with invalid salt length must not resolve"))
|
||||
.catch((e) => expect(e).toMatch(/invalid salt length/));
|
||||
.catch((e) => expect(e).toMatch(/invalid salt length/i));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
import { isNonNullObject } from "@cosmjs/utils";
|
||||
import sodium from "libsodium-wrappers";
|
||||
|
||||
import argon2id from "./pkg2";
|
||||
|
||||
export interface Argon2idOptions {
|
||||
/** Output length in bytes */
|
||||
readonly outputLength: number;
|
||||
@ -39,15 +41,21 @@ export class Argon2id {
|
||||
salt: Uint8Array,
|
||||
options: Argon2idOptions,
|
||||
): Promise<Uint8Array> {
|
||||
await sodium.ready;
|
||||
return sodium.crypto_pwhash(
|
||||
options.outputLength,
|
||||
password,
|
||||
salt, // libsodium only supports 16 byte salts and will throw when you don't respect that
|
||||
options.opsLimit,
|
||||
options.memLimitKib * 1024,
|
||||
sodium.crypto_pwhash_ALG_ARGON2ID13,
|
||||
);
|
||||
// await sodium.ready;
|
||||
// return sodium.crypto_pwhash(
|
||||
// options.outputLength,
|
||||
// password,
|
||||
// salt, // libsodium only supports 16 byte salts and will throw when you don't respect that
|
||||
// options.opsLimit,
|
||||
// options.memLimitKib * 1024,
|
||||
// sodium.crypto_pwhash_ALG_ARGON2ID13,
|
||||
// );
|
||||
if (salt.length !== 16) {
|
||||
throw new Error(
|
||||
"Invalid salt length. Only 16 bytes is supported for compatibility with previous libsodium-based implementation. Feel free to raise an issue if you need something else.",
|
||||
);
|
||||
}
|
||||
return argon2id.hash(password, salt, options.outputLength, options.memLimitKib, options.opsLimit);
|
||||
}
|
||||
}
|
||||
|
||||
|
17
packages/crypto/src/pkg2/index.d.ts
vendored
Normal file
17
packages/crypto/src/pkg2/index.d.ts
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* @param {string} password
|
||||
* @param {Uint8Array} salt
|
||||
* @param {number} output_length
|
||||
* @param {number} memory_cost
|
||||
* @param {number} time_cost
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function hash(
|
||||
password: string,
|
||||
salt: Uint8Array,
|
||||
output_length: number,
|
||||
memory_cost: number,
|
||||
time_cost: number,
|
||||
): Uint8Array;
|
169
packages/crypto/src/pkg2/index.js
Normal file
169
packages/crypto/src/pkg2/index.js
Normal file
File diff suppressed because one or more lines are too long
4
packages/crypto/src/pkg2/package.json
Normal file
4
packages/crypto/src/pkg2/package.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts"
|
||||
}
|
3
wasm/argon2id/.cargo/config
Normal file
3
wasm/argon2id/.cargo/config
Normal file
@ -0,0 +1,3 @@
|
||||
[alias]
|
||||
wasm = "build --release --target wasm32-unknown-unknown"
|
||||
wasm-debug = "build --target wasm32-unknown-unknown"
|
3
wasm/argon2id/.gitignore
vendored
Normal file
3
wasm/argon2id/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
pkg/
|
||||
pkg2/
|
||||
target/
|
210
wasm/argon2id/Cargo.lock
generated
Normal file
210
wasm/argon2id/Cargo.lock
generated
Normal file
@ -0,0 +1,210 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "argon2"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0a21e93ce9e91fcd0e01744e4f205fb9192f82915646a7e880dfef0ab4a38d8"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"blake2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "argon2id"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"argon2",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b"
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b94ba84325db59637ffc528bbe8c7f86c02c57cff5c0e2b9b00f9a851f42f309"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03588e54c62ae6d763e2a80090d50353b785795361b4ff5b3bf0a5097fc31c0b"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
"generic-array",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
12
wasm/argon2id/Cargo.toml
Normal file
12
wasm/argon2id/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "argon2id"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
argon2 = { version = "0.3.2", default-features = false, features = ["alloc"] }
|
||||
wasm-bindgen = { version = "0.2.78" }
|
24
wasm/argon2id/src/lib.rs
Normal file
24
wasm/argon2id/src/lib.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use argon2::{Algorithm, Argon2, Params, Version};
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn hash(
|
||||
password: &str,
|
||||
salt: &[u8],
|
||||
output_length: usize,
|
||||
memory_cost: u32,
|
||||
time_cost: u32,
|
||||
) -> Result<Vec<u8>, JsValue> {
|
||||
let threads = 1;
|
||||
|
||||
let params =
|
||||
Params::new(memory_cost, time_cost, threads, Some(output_length)).map_err(|e| e.to_string())?;
|
||||
let argon2 = Argon2::new(Algorithm::Argon2id, Version::V0x13, params);
|
||||
|
||||
let mut out = vec![0; output_length];
|
||||
argon2
|
||||
.hash_password_into(password.as_bytes(), salt, &mut out[..])
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok(out)
|
||||
}
|
33
wasm/build_argon2id.sh
Executable file
33
wasm/build_argon2id.sh
Executable file
@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
set -o errexit -o nounset -o pipefail
|
||||
command -v shellcheck >/dev/null && shellcheck "$0"
|
||||
|
||||
gnused="$(command -v gsed || echo sed)"
|
||||
|
||||
(
|
||||
cd argon2id
|
||||
wasm-pack build --target nodejs
|
||||
|
||||
# Prettify before inlining the big Wasm blob to keep this fast and bytes list compact
|
||||
yarn prettier --write 'pkg/*.{js,ts}'
|
||||
|
||||
echo "Wasm blob built:"
|
||||
ls -l pkg/argon2id_bg.wasm
|
||||
|
||||
BYTES=$(python3 <<HEREDOC
|
||||
with open("pkg/argon2id_bg.wasm", "rb") as f:
|
||||
bytes = [str(byte[0]) for byte in iter(lambda: f.read(1), b'')]
|
||||
print("const bytes = new Uint8Array([" + ",".join(bytes) + "]);")
|
||||
HEREDOC
|
||||
)
|
||||
"$gnused" -i \
|
||||
-e "s/^const { TextDecoder, TextEncoder } =.*$//" \
|
||||
-e "s/^const path =.*$//" \
|
||||
-e "s/^const bytes =.*$/$BYTES/" \
|
||||
pkg/argon2id.js
|
||||
mkdir -p pkg2
|
||||
cp pkg/argon2id.js pkg2/index.js
|
||||
cp pkg/argon2id.d.ts pkg2/index.d.ts
|
||||
echo '{ "main": "index.js", "types": "index.d.ts" }' | jq > pkg2/package.json
|
||||
cp -R pkg2 ../../packages/crypto/src/
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user