@pezkuwi/wasm-crypto 7.5.9 → 7.5.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/bundle-pezkuwi-wasm-crypto.js +777 -0
- package/bundle.d.ts +37 -0
- package/bundle.js +165 -0
- package/cjs/bundle.d.ts +37 -0
- package/cjs/bundle.js +171 -0
- package/cjs/index.js +5 -0
- package/cjs/init.js +21 -0
- package/cjs/initNone.js +20 -0
- package/cjs/initOnlyAsm.js +20 -0
- package/cjs/initOnlyWasm.js +20 -0
- package/cjs/initWasmAsm.js +20 -0
- package/cjs/package.json +3 -0
- package/cjs/packageDetect.js +10 -0
- package/cjs/packageInfo.js +4 -0
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/{src/init.ts → init.d.ts} +2 -11
- package/init.js +17 -0
- package/initNone.d.ts +10 -0
- package/{src/initNone.ts → initNone.js} +4 -10
- package/initOnlyAsm.d.ts +10 -0
- package/{src/initOnlyAsm.ts → initOnlyAsm.js} +4 -10
- package/initOnlyWasm.d.ts +10 -0
- package/{src/initOnlyWasm.ts → initOnlyWasm.js} +4 -10
- package/initWasmAsm.d.ts +10 -0
- package/{src/initWasmAsm.ts → initWasmAsm.js} +4 -10
- package/package.json +162 -16
- package/packageDetect.d.ts +1 -0
- package/{src/packageDetect.ts → packageDetect.js} +0 -8
- package/packageInfo.d.ts +6 -0
- package/packageInfo.js +1 -0
- package/Cargo.toml +0 -50
- package/Xargo.toml +0 -2
- package/build/bundle.d.ts +0 -37
- package/src/bundle.ts +0 -247
- package/src/index.ts +0 -6
- package/src/lib.rs +0 -24
- package/src/mod.ts +0 -4
- package/src/packageInfo.ts +0 -6
- package/src/rs/.editorconfig +0 -10
- package/src/rs/bip39.rs +0 -139
- package/src/rs/ed25519.rs +0 -142
- package/src/rs/hashing.rs +0 -322
- package/src/rs/secp256k1.rs +0 -150
- package/src/rs/sr25519.rs +0 -331
- package/src/rs/vrf.rs +0 -144
- package/test/all/bip39.js +0 -86
- package/test/all/ed25519.js +0 -84
- package/test/all/hashing.js +0 -138
- package/test/all/index.js +0 -126
- package/test/all/secp256k1.js +0 -105
- package/test/all/sr25519.js +0 -211
- package/test/all/vrf.js +0 -74
- package/test/asm.js +0 -10
- package/test/deno.ts +0 -37
- package/test/jest.spec.ts +0 -24
- package/test/loader-build.js +0 -39
- package/test/wasm.js +0 -8
- package/tsconfig.build.json +0 -19
- package/tsconfig.spec.json +0 -16
- /package/{build → cjs}/index.d.ts +0 -0
- /package/{build → cjs}/init.d.ts +0 -0
- /package/{build → cjs}/initNone.d.ts +0 -0
- /package/{build → cjs}/initOnlyAsm.d.ts +0 -0
- /package/{build → cjs}/initOnlyWasm.d.ts +0 -0
- /package/{build → cjs}/initWasmAsm.d.ts +0 -0
- /package/{build → cjs}/packageDetect.d.ts +0 -0
- /package/{build → cjs}/packageInfo.d.ts +0 -0
package/src/index.ts
DELETED
package/src/lib.rs
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
// Use `wee_alloc` as the global allocator.
|
|
5
|
-
#[global_allocator]
|
|
6
|
-
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
|
7
|
-
|
|
8
|
-
#[path = "rs/bip39.rs"]
|
|
9
|
-
pub mod bip39;
|
|
10
|
-
|
|
11
|
-
#[path = "rs/ed25519.rs"]
|
|
12
|
-
pub mod ed25519;
|
|
13
|
-
|
|
14
|
-
#[path = "rs/hashing.rs"]
|
|
15
|
-
pub mod hashing;
|
|
16
|
-
|
|
17
|
-
#[path = "rs/secp256k1.rs"]
|
|
18
|
-
pub mod secp256k1;
|
|
19
|
-
|
|
20
|
-
#[path = "rs/sr25519.rs"]
|
|
21
|
-
pub mod sr25519;
|
|
22
|
-
|
|
23
|
-
#[path = "rs/vrf.rs"]
|
|
24
|
-
pub mod vrf;
|
package/src/mod.ts
DELETED
package/src/packageInfo.ts
DELETED
package/src/rs/.editorconfig
DELETED
package/src/rs/bip39.rs
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
use bip39::{Mnemonic, MnemonicType, Language, Seed};
|
|
5
|
-
use hmac::Hmac;
|
|
6
|
-
use pbkdf2::pbkdf2;
|
|
7
|
-
use sha2::Sha512;
|
|
8
|
-
use wasm_bindgen::prelude::*;
|
|
9
|
-
|
|
10
|
-
/// Generate a bip39 phrase
|
|
11
|
-
///
|
|
12
|
-
/// words: number of words, either 12, 15, 18 21 or 24
|
|
13
|
-
///
|
|
14
|
-
/// Returns the bip 39 phrase
|
|
15
|
-
#[wasm_bindgen]
|
|
16
|
-
pub fn ext_bip39_generate(words: u32) -> String {
|
|
17
|
-
match MnemonicType::for_word_count(words as usize) {
|
|
18
|
-
Ok(p) => Mnemonic::new(p, Language::English)
|
|
19
|
-
.into_phrase(),
|
|
20
|
-
_ => panic!("Invalid count provided.")
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/// Create entropy from a bip39 phrase
|
|
25
|
-
///
|
|
26
|
-
/// * phrase: mnemonic phrase
|
|
27
|
-
///
|
|
28
|
-
/// Returns the entropy
|
|
29
|
-
#[wasm_bindgen]
|
|
30
|
-
pub fn ext_bip39_to_entropy(phrase: &str) -> Vec<u8> {
|
|
31
|
-
match Mnemonic::from_phrase(phrase, Language::English) {
|
|
32
|
-
Ok(m) => m
|
|
33
|
-
.entropy()
|
|
34
|
-
.to_vec(),
|
|
35
|
-
_ => panic!("Invalid phrase provided.")
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/// Create a mini-secret from a bip39 phrase
|
|
40
|
-
///
|
|
41
|
-
/// * phrase: mnemonic phrase
|
|
42
|
-
///
|
|
43
|
-
/// Returns the 32-byte mini-secret via entropy
|
|
44
|
-
#[wasm_bindgen]
|
|
45
|
-
pub fn ext_bip39_to_mini_secret(phrase: &str, password: &str) -> Vec<u8> {
|
|
46
|
-
match Mnemonic::from_phrase(phrase, Language::English) {
|
|
47
|
-
Ok(m) => {
|
|
48
|
-
let mut res = [0u8; 64];
|
|
49
|
-
let mut seed = vec![];
|
|
50
|
-
|
|
51
|
-
seed.extend_from_slice(b"mnemonic");
|
|
52
|
-
seed.extend_from_slice(password.as_bytes());
|
|
53
|
-
|
|
54
|
-
pbkdf2::<Hmac<Sha512>>(m.entropy(), &seed, 2048, &mut res);
|
|
55
|
-
|
|
56
|
-
res[..32].to_vec()
|
|
57
|
-
},
|
|
58
|
-
_ => panic!("Invalid phrase provided.")
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/// Creates a BTC/ETH compatible seed from a bip-39 phrase
|
|
63
|
-
///
|
|
64
|
-
/// @phrase: mnemonic phrase
|
|
65
|
-
///
|
|
66
|
-
/// Returns a 32-byte seed
|
|
67
|
-
#[wasm_bindgen]
|
|
68
|
-
pub fn ext_bip39_to_seed(phrase: &str, password: &str) -> Vec<u8> {
|
|
69
|
-
match Mnemonic::from_phrase(phrase, Language::English) {
|
|
70
|
-
Ok(m) => Seed::new(&m, password)
|
|
71
|
-
.as_bytes()[..32]
|
|
72
|
-
.to_vec(),
|
|
73
|
-
_ => panic!("Invalid phrase provided.")
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/// Validates a bip39 phrase
|
|
78
|
-
///
|
|
79
|
-
/// * phrase: mnemonic phrase
|
|
80
|
-
///
|
|
81
|
-
/// Returns the true/false
|
|
82
|
-
#[wasm_bindgen]
|
|
83
|
-
pub fn ext_bip39_validate(phrase: &str) -> bool {
|
|
84
|
-
match Mnemonic::validate(phrase, Language::English) {
|
|
85
|
-
Ok(_) => true,
|
|
86
|
-
_ => false
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
#[cfg(test)]
|
|
91
|
-
pub mod tests {
|
|
92
|
-
use hex_literal::hex;
|
|
93
|
-
use super::*;
|
|
94
|
-
|
|
95
|
-
#[test]
|
|
96
|
-
fn can_bip39_entropy() {
|
|
97
|
-
let phrase = "legal winner thank year wave sausage worth useful legal winner thank yellow";
|
|
98
|
-
let entropy = hex!("7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f");
|
|
99
|
-
let res = ext_bip39_to_entropy(phrase);
|
|
100
|
-
|
|
101
|
-
assert_eq!(res, entropy);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
#[test]
|
|
105
|
-
fn can_bip39_mini_secret() {
|
|
106
|
-
let phrase = "legal winner thank year wave sausage worth useful legal winner thank yellow";
|
|
107
|
-
let password = "Substrate";
|
|
108
|
-
let mini = hex!("4313249608fe8ac10fd5886c92c4579007272cb77c21551ee5b8d60b78041685");
|
|
109
|
-
let res = ext_bip39_to_mini_secret(phrase, password);
|
|
110
|
-
|
|
111
|
-
assert_eq!(res[..], mini[..]);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
#[test]
|
|
115
|
-
fn can_bip39_seed() {
|
|
116
|
-
let phrase = "seed sock milk update focus rotate barely fade car face mechanic mercy";
|
|
117
|
-
let seed = hex!("3c121e20de068083b49c2315697fb59a2d9e8643c24e5ea7628132c58969a027");
|
|
118
|
-
let res = ext_bip39_to_seed(phrase, "");
|
|
119
|
-
|
|
120
|
-
assert_eq!(res[..], seed[..]);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
#[test]
|
|
124
|
-
fn can_bip39_generate() {
|
|
125
|
-
let phrase = ext_bip39_generate(12);
|
|
126
|
-
let is_valid = ext_bip39_validate(&phrase);
|
|
127
|
-
|
|
128
|
-
assert!(is_valid);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
#[test]
|
|
132
|
-
fn can_bip39_validate() {
|
|
133
|
-
let is_valid = ext_bip39_validate("seed sock milk update focus rotate barely fade car face mechanic mercy");
|
|
134
|
-
let is_invalid = ext_bip39_validate("wine photo extra cushion basket dwarf humor cloud truck job boat submit");
|
|
135
|
-
|
|
136
|
-
assert_eq!(is_valid, true);
|
|
137
|
-
assert_eq!(is_invalid, false);
|
|
138
|
-
}
|
|
139
|
-
}
|
package/src/rs/ed25519.rs
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
use std::convert::TryFrom;
|
|
5
|
-
use ed25519_dalek::{Keypair, PublicKey, SecretKey, Signature, Signer as _, Verifier as _};
|
|
6
|
-
use wasm_bindgen::prelude::*;
|
|
7
|
-
|
|
8
|
-
/// Keypair helper function
|
|
9
|
-
fn new_from_seed(seed: &[u8]) -> Keypair {
|
|
10
|
-
match SecretKey::from_bytes(seed) {
|
|
11
|
-
Ok(secret) => {
|
|
12
|
-
let public: PublicKey = (&secret).into();
|
|
13
|
-
|
|
14
|
-
Keypair { secret: secret, public: public }
|
|
15
|
-
},
|
|
16
|
-
_ => panic!("Invalid seed provided.")
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/// Generate a key pair.
|
|
21
|
-
///
|
|
22
|
-
/// * seed: UIntArray with 32 element
|
|
23
|
-
///
|
|
24
|
-
/// returned vector is the concatenation of first the seed (32 bytes)
|
|
25
|
-
/// followed by the public key (32) bytes, as the full secret keys.
|
|
26
|
-
#[wasm_bindgen]
|
|
27
|
-
pub fn ext_ed_from_seed(seed: &[u8]) -> Vec<u8> {
|
|
28
|
-
new_from_seed(seed)
|
|
29
|
-
.to_bytes()
|
|
30
|
-
.to_vec()
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/// Sign a message
|
|
34
|
-
///
|
|
35
|
-
/// The combination of both public and private key must be provided.
|
|
36
|
-
/// This is effectively equivalent to a keypair.
|
|
37
|
-
///
|
|
38
|
-
/// * _: UIntArray with 32 element (was pubkey, now ignored)
|
|
39
|
-
/// * private: UIntArray with 64 element
|
|
40
|
-
/// * message: Arbitrary length UIntArray
|
|
41
|
-
///
|
|
42
|
-
/// * returned vector is the signature consisting of 64 bytes.
|
|
43
|
-
#[wasm_bindgen]
|
|
44
|
-
pub fn ext_ed_sign(_: &[u8], seckey: &[u8], message: &[u8]) -> Vec<u8> {
|
|
45
|
-
// https://github.com/MystenLabs/ed25519-unsafe-libs
|
|
46
|
-
// we never use the provided pubkey
|
|
47
|
-
new_from_seed(seckey)
|
|
48
|
-
.sign(message)
|
|
49
|
-
.to_bytes()
|
|
50
|
-
.to_vec()
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/// Verify a message and its corresponding against a public key;
|
|
54
|
-
///
|
|
55
|
-
/// * signature: UIntArray with 64 element
|
|
56
|
-
/// * message: Arbitrary length UIntArray
|
|
57
|
-
/// * pubkey: UIntArray with 32 element
|
|
58
|
-
#[wasm_bindgen]
|
|
59
|
-
pub fn ext_ed_verify(signature: &[u8], message: &[u8], pubkey: &[u8]) -> bool {
|
|
60
|
-
match (Signature::try_from(signature), PublicKey::from_bytes(pubkey)) {
|
|
61
|
-
(Ok(s), Ok(k)) => k
|
|
62
|
-
.verify(message, &s)
|
|
63
|
-
.is_ok(),
|
|
64
|
-
_ => false
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
#[cfg(test)]
|
|
69
|
-
pub mod tests {
|
|
70
|
-
extern crate rand;
|
|
71
|
-
|
|
72
|
-
use hex_literal::hex;
|
|
73
|
-
use super::*;
|
|
74
|
-
use ed25519_dalek::{SIGNATURE_LENGTH, KEYPAIR_LENGTH, SECRET_KEY_LENGTH};
|
|
75
|
-
|
|
76
|
-
fn generate_random_seed() -> Vec<u8> {
|
|
77
|
-
(0..32).map(|_| rand::random::<u8>() ).collect()
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
#[test]
|
|
81
|
-
fn can_new_keypair() {
|
|
82
|
-
let seed = generate_random_seed();
|
|
83
|
-
let keypair = ext_ed_from_seed(seed.as_slice());
|
|
84
|
-
|
|
85
|
-
assert!(keypair.len() == KEYPAIR_LENGTH);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
#[test]
|
|
89
|
-
fn creates_pair_from_known() {
|
|
90
|
-
let seed = b"12345678901234567890123456789012";
|
|
91
|
-
let expected = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee");
|
|
92
|
-
let keypair = ext_ed_from_seed(seed);
|
|
93
|
-
let public = &keypair[SECRET_KEY_LENGTH..KEYPAIR_LENGTH];
|
|
94
|
-
|
|
95
|
-
assert_eq!(public, expected);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
#[test]
|
|
99
|
-
fn can_sign_message() {
|
|
100
|
-
let seed = generate_random_seed();
|
|
101
|
-
let keypair = ext_ed_from_seed(seed.as_slice());
|
|
102
|
-
let private = &keypair[0..SECRET_KEY_LENGTH];
|
|
103
|
-
let public = &keypair[SECRET_KEY_LENGTH..KEYPAIR_LENGTH];
|
|
104
|
-
let message = b"this is a message";
|
|
105
|
-
let signature = ext_ed_sign(public, private, message);
|
|
106
|
-
|
|
107
|
-
assert!(signature.len() == SIGNATURE_LENGTH);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
#[test]
|
|
111
|
-
fn can_verify_message() {
|
|
112
|
-
let seed = generate_random_seed();
|
|
113
|
-
let keypair = ext_ed_from_seed(seed.as_slice());
|
|
114
|
-
let private = &keypair[0..SECRET_KEY_LENGTH];
|
|
115
|
-
let public = &keypair[SECRET_KEY_LENGTH..KEYPAIR_LENGTH];
|
|
116
|
-
let message = b"this is a message";
|
|
117
|
-
let signature = ext_ed_sign(public, private, message);
|
|
118
|
-
let is_valid = ext_ed_verify(&signature[..], message, public);
|
|
119
|
-
|
|
120
|
-
assert!(is_valid);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
#[test]
|
|
124
|
-
fn can_verify_known() {
|
|
125
|
-
let public = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee");
|
|
126
|
-
let message = b"this is a message";
|
|
127
|
-
let signature = hex!("90588f3f512496f2dd40571d162e8182860081c74e2085316e7c4396918f07da412ee029978e4dd714057fe973bd9e7d645148bf7b66680d67c93227cde95202");
|
|
128
|
-
let is_valid = ext_ed_verify(&signature, message, &public);
|
|
129
|
-
|
|
130
|
-
assert!(is_valid);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
#[test]
|
|
134
|
-
fn can_verify_known_wrong() {
|
|
135
|
-
let public = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee");
|
|
136
|
-
let message = b"this is a message";
|
|
137
|
-
let signature = &[0u8; 64];
|
|
138
|
-
let is_valid = ext_ed_verify(signature, message, &public);
|
|
139
|
-
|
|
140
|
-
assert_eq!(is_valid, false);
|
|
141
|
-
}
|
|
142
|
-
}
|
package/src/rs/hashing.rs
DELETED
|
@@ -1,322 +0,0 @@
|
|
|
1
|
-
// Copyright 2019-2025 @pezkuwi/wasm-crypto authors & contributors
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
use blake2_rfc::blake2b::blake2b;
|
|
5
|
-
use byteorder::{ByteOrder, LittleEndian};
|
|
6
|
-
use hmac::{Hmac, Mac};
|
|
7
|
-
use pbkdf2::pbkdf2;
|
|
8
|
-
use scrypt::{ScryptParams, scrypt};
|
|
9
|
-
use sha2::{Digest, Sha256, Sha512};
|
|
10
|
-
use tiny_keccak::{Hasher, Keccak};
|
|
11
|
-
use twox_hash::XxHash;
|
|
12
|
-
use wasm_bindgen::prelude::*;
|
|
13
|
-
|
|
14
|
-
/// blake2b hash for the specified input
|
|
15
|
-
///
|
|
16
|
-
/// * data: Arbitrary data to be hashed
|
|
17
|
-
/// * key: Key to add to the hashing (normally empty)
|
|
18
|
-
/// * size: Size in bytes of the resulting output
|
|
19
|
-
///
|
|
20
|
-
/// Returns a vector with the hash result
|
|
21
|
-
#[wasm_bindgen]
|
|
22
|
-
pub fn ext_blake2b(data: &[u8], key: &[u8], size: u32) -> Vec<u8> {
|
|
23
|
-
// we cast to usize here - due to the WASM, we'd rather have u32 inputs
|
|
24
|
-
blake2b(size as usize, key, data)
|
|
25
|
-
.as_bytes()
|
|
26
|
-
.to_vec()
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/// hmac with sha256
|
|
30
|
-
#[wasm_bindgen]
|
|
31
|
-
pub fn ext_hmac_sha256(key: &[u8], data: &[u8]) -> Vec<u8> {
|
|
32
|
-
match Hmac::<Sha256>::new_varkey(key) {
|
|
33
|
-
Ok(mut m) => {
|
|
34
|
-
m.input(data);
|
|
35
|
-
|
|
36
|
-
m
|
|
37
|
-
.result()
|
|
38
|
-
.code()
|
|
39
|
-
.to_vec()
|
|
40
|
-
},
|
|
41
|
-
_ => panic!("Invalid key provided.")
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/// hmac with sha512
|
|
46
|
-
#[wasm_bindgen]
|
|
47
|
-
pub fn ext_hmac_sha512(key: &[u8], data: &[u8]) -> Vec<u8> {
|
|
48
|
-
match Hmac::<Sha512>::new_varkey(key) {
|
|
49
|
-
Ok(mut m) => {
|
|
50
|
-
m.input(data);
|
|
51
|
-
|
|
52
|
-
m
|
|
53
|
-
.result()
|
|
54
|
-
.code()
|
|
55
|
-
.to_vec()
|
|
56
|
-
},
|
|
57
|
-
_ => panic!("Invalid key provided.")
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/// Create a keccak256 hash for the specified input
|
|
63
|
-
///
|
|
64
|
-
// * data: Arbitrary data to be hashed
|
|
65
|
-
///
|
|
66
|
-
/// Returns the hash as a vector
|
|
67
|
-
#[wasm_bindgen]
|
|
68
|
-
pub fn ext_keccak256(data: &[u8]) -> Vec<u8> {
|
|
69
|
-
let mut keccak = Keccak::v256();
|
|
70
|
-
let mut res = [0u8; 32];
|
|
71
|
-
|
|
72
|
-
keccak.update(data);
|
|
73
|
-
keccak.finalize(&mut res);
|
|
74
|
-
|
|
75
|
-
res.to_vec()
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/// Create a keccak512 hash for the specified input
|
|
79
|
-
///
|
|
80
|
-
// * data: Arbitrary data to be hashed
|
|
81
|
-
///
|
|
82
|
-
/// Returns the hash as a vector
|
|
83
|
-
#[wasm_bindgen]
|
|
84
|
-
pub fn ext_keccak512(data: &[u8]) -> Vec<u8> {
|
|
85
|
-
let mut keccak = Keccak::v512();
|
|
86
|
-
let mut res = [0u8; 64];
|
|
87
|
-
|
|
88
|
-
keccak.update(data);
|
|
89
|
-
keccak.finalize(&mut res);
|
|
90
|
-
|
|
91
|
-
res.to_vec()
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/// pbkdf2 kdf from an input, salt for the number of specified rounds
|
|
95
|
-
///
|
|
96
|
-
/// * data: Arbitrary data to be hashed
|
|
97
|
-
/// * salt: Salt for this hash
|
|
98
|
-
/// * rounds: The number of rounds to perform
|
|
99
|
-
///
|
|
100
|
-
/// Returns a vector with the hashed result
|
|
101
|
-
#[wasm_bindgen]
|
|
102
|
-
pub fn ext_pbkdf2(data: &[u8], salt: &[u8], rounds: u32) -> Vec<u8> {
|
|
103
|
-
// As per RFC 2898 [https://datatracker.ietf.org/doc/html/rfc2898], the number of rounds must be greater than 0
|
|
104
|
-
if rounds == 0 {
|
|
105
|
-
panic!("PBKDF2 rounds must be greater than 0");
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
let mut res = [0u8; 64];
|
|
109
|
-
|
|
110
|
-
// we cast to usize here - due to the WASM, we'd rather have u32 inputs
|
|
111
|
-
pbkdf2::<Hmac::<Sha512>>(data, salt, rounds as usize, &mut res);
|
|
112
|
-
|
|
113
|
-
res.to_vec()
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/// scrypt kdf from input, salt and config
|
|
117
|
-
///
|
|
118
|
-
/// * password: Password to hash
|
|
119
|
-
/// * salt: Salt for this hash
|
|
120
|
-
/// * log2_n: log2(n)
|
|
121
|
-
/// * r: r
|
|
122
|
-
/// * p: p
|
|
123
|
-
///
|
|
124
|
-
/// Returns vector with the hashed result
|
|
125
|
-
#[wasm_bindgen]
|
|
126
|
-
pub fn ext_scrypt(password: &[u8], salt: &[u8], log2_n: u8, r: u32, p: u32) -> Vec<u8> {
|
|
127
|
-
// As per RFC 7914 [https://datatracker.ietf.org/doc/html/rfc7914.html], the cost parameter N (2 ^ log2_n) must be larger than 1
|
|
128
|
-
if log2_n == 0 {
|
|
129
|
-
panic!("Scrypt cost parameter N must be larger than 1, log2_n must be at least 1");
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
match ScryptParams::new(log2_n, r, p) {
|
|
133
|
-
Ok(p) => {
|
|
134
|
-
let mut res = [0u8; 64];
|
|
135
|
-
|
|
136
|
-
match scrypt(password, salt, &p, &mut res) {
|
|
137
|
-
Ok(_) => res.to_vec(),
|
|
138
|
-
_ => panic!("Invalid scrypt hash.")
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
_ => panic!("Invalid scrypt params.")
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/// sha256 hash for the specified input
|
|
147
|
-
///
|
|
148
|
-
/// * data: Arbitrary data to be hashed
|
|
149
|
-
///
|
|
150
|
-
/// Returns a vector with the hash result
|
|
151
|
-
#[wasm_bindgen]
|
|
152
|
-
pub fn ext_sha256(data: &[u8]) -> Vec<u8> {
|
|
153
|
-
let mut hasher = Sha256::new();
|
|
154
|
-
|
|
155
|
-
hasher.input(data);
|
|
156
|
-
|
|
157
|
-
hasher
|
|
158
|
-
.result()
|
|
159
|
-
.to_vec()
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/// sha512 hash for the specified input
|
|
163
|
-
///
|
|
164
|
-
/// * data: Arbitrary data to be hashed
|
|
165
|
-
///
|
|
166
|
-
/// Returns a vector with the hash result
|
|
167
|
-
#[wasm_bindgen]
|
|
168
|
-
pub fn ext_sha512(data: &[u8]) -> Vec<u8> {
|
|
169
|
-
let mut hasher = Sha512::new();
|
|
170
|
-
|
|
171
|
-
hasher.input(data);
|
|
172
|
-
|
|
173
|
-
hasher
|
|
174
|
-
.result()
|
|
175
|
-
.to_vec()
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/// twox hash for the specified input and rounds
|
|
179
|
-
///
|
|
180
|
-
/// * data: Arbitrary data to be hashed
|
|
181
|
-
/// * rounds: Number of 8-byte rounds to add to the output
|
|
182
|
-
///
|
|
183
|
-
/// Returns a vector with the hash result
|
|
184
|
-
#[wasm_bindgen]
|
|
185
|
-
pub fn ext_twox(data: &[u8], rounds: u32) -> Vec<u8> {
|
|
186
|
-
use ::std::hash::Hasher;
|
|
187
|
-
let mut res = vec![];
|
|
188
|
-
let mut buf = [0u8; 8];
|
|
189
|
-
|
|
190
|
-
for round in 0..rounds {
|
|
191
|
-
// we cast to u64 here - due to the WASM, we'd rather have u32 inputs
|
|
192
|
-
let mut hasher = XxHash::with_seed(round as u64);
|
|
193
|
-
|
|
194
|
-
hasher.write(data);
|
|
195
|
-
LittleEndian::write_u64(&mut buf, hasher.finish());
|
|
196
|
-
res.extend_from_slice(&buf);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
res
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
#[cfg(test)]
|
|
203
|
-
pub mod tests {
|
|
204
|
-
use hex_literal::hex;
|
|
205
|
-
use super::*;
|
|
206
|
-
|
|
207
|
-
#[test]
|
|
208
|
-
fn can_blake2b() {
|
|
209
|
-
let data = b"abc";
|
|
210
|
-
let expected_32 = hex!("bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319");
|
|
211
|
-
let expected_64 = hex!("ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923");
|
|
212
|
-
let hash_32 = ext_blake2b(data, &[], 32);
|
|
213
|
-
let hash_64 = ext_blake2b(data, &[], 64);
|
|
214
|
-
|
|
215
|
-
assert_eq!(hash_32[..], expected_32[..]);
|
|
216
|
-
assert_eq!(hash_64[..], expected_64[..]);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
#[test]
|
|
220
|
-
fn can_keccak256() {
|
|
221
|
-
let data = b"test value";
|
|
222
|
-
let expected = hex!("2d07364b5c231c56ce63d49430e085ea3033c750688ba532b24029124c26ca5e");
|
|
223
|
-
let hash = ext_keccak256(data);
|
|
224
|
-
|
|
225
|
-
assert_eq!(hash[..], expected[..]);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
#[test]
|
|
229
|
-
fn can_hmac_sha256() {
|
|
230
|
-
let key = b"secret";
|
|
231
|
-
let data = b"some message";
|
|
232
|
-
let expected = hex!("f28a70b41263840e5c059a0a733336e0957efba87902aa8cca11441d4b0c96d7");
|
|
233
|
-
let hash = ext_hmac_sha256(key, data);
|
|
234
|
-
|
|
235
|
-
assert_eq!(hash[..], expected[..]);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
#[test]
|
|
239
|
-
fn can_hmac_sha512() {
|
|
240
|
-
let key = b"secret";
|
|
241
|
-
let data = b"some message";
|
|
242
|
-
let expected = hex!("295832e97ed77be75a9fa98029497e4a722c4b9a2f21b39d34f1befa931a39ec520fd24711d6f5c03501384ea66b83066a01a82c57a0460f8cd1f471fcce5841");
|
|
243
|
-
let hash = ext_hmac_sha512(key, data);
|
|
244
|
-
|
|
245
|
-
assert_eq!(hash[..], expected[..]);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
#[test]
|
|
249
|
-
fn can_keccak512() {
|
|
250
|
-
let data = b"test";
|
|
251
|
-
let expected = hex!("1e2e9fc2002b002d75198b7503210c05a1baac4560916a3c6d93bcce3a50d7f00fd395bf1647b9abb8d1afcc9c76c289b0c9383ba386a956da4b38934417789e");
|
|
252
|
-
let hash = ext_keccak512(data);
|
|
253
|
-
|
|
254
|
-
assert_eq!(hash[..], expected[..]);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
#[test]
|
|
258
|
-
fn can_pbkdf2() {
|
|
259
|
-
let salt = b"this is a salt";
|
|
260
|
-
let data = b"hello world";
|
|
261
|
-
let expected = hex!("5fcbe04f05300a3ecc5c35d18ea0b78f3f6853d2ae5f3fca374f69a7d1f78b5def5c60dae1a568026c7492511e0c53521e8bb6e03a650e1263265fee92722270");
|
|
262
|
-
let hash = ext_pbkdf2(data, salt, 2048);
|
|
263
|
-
|
|
264
|
-
assert_eq!(hash[..], expected[..]);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
#[test]
|
|
268
|
-
#[should_panic(expected = "PBKDF2 rounds must be greater than 0")]
|
|
269
|
-
fn pbkdf2_zero_rounds_panics() {
|
|
270
|
-
let salt = b"this is a salt";
|
|
271
|
-
let data = b"hello world";
|
|
272
|
-
ext_pbkdf2(data, salt, 0);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
#[test]
|
|
276
|
-
fn can_scrypt() {
|
|
277
|
-
let password = b"password";
|
|
278
|
-
let salt = b"salt";
|
|
279
|
-
let expected = hex!("745731af4484f323968969eda289aeee005b5903ac561e64a5aca121797bf7734ef9fd58422e2e22183bcacba9ec87ba0c83b7a2e788f03ce0da06463433cda6");
|
|
280
|
-
let hash = ext_scrypt(password, salt, 14, 8, 1);
|
|
281
|
-
|
|
282
|
-
assert_eq!(hash[..], expected[..]);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
#[test]
|
|
286
|
-
#[should_panic(expected = "Scrypt cost parameter N must be larger than 1, log2_n must be at least 1")]
|
|
287
|
-
fn scrypt_zero_log2_n_panics() {
|
|
288
|
-
let password = b"password";
|
|
289
|
-
let salt = b"salt";
|
|
290
|
-
ext_scrypt(password, salt, 0, 8, 1);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
#[test]
|
|
294
|
-
fn can_sha256() {
|
|
295
|
-
let data = b"hello world";
|
|
296
|
-
let expected = hex!("b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9");
|
|
297
|
-
let hash = ext_sha256(data);
|
|
298
|
-
|
|
299
|
-
assert_eq!(hash[..], expected[..]);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
#[test]
|
|
303
|
-
fn can_sha512() {
|
|
304
|
-
let data = b"hello world";
|
|
305
|
-
let expected = hex!("309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f");
|
|
306
|
-
let hash = ext_sha512(data);
|
|
307
|
-
|
|
308
|
-
assert_eq!(hash[..], expected[..]);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
#[test]
|
|
312
|
-
fn can_twox() {
|
|
313
|
-
let data = b"abc";
|
|
314
|
-
let expected_64 = hex!("990977adf52cbc44");
|
|
315
|
-
let expected_256 = hex!("990977adf52cbc440889329981caa9bef7da5770b2b8a05303b75d95360dd62b");
|
|
316
|
-
let hash_64 = ext_twox(data, 1);
|
|
317
|
-
let hash_256 = ext_twox(data, 4);
|
|
318
|
-
|
|
319
|
-
assert_eq!(hash_64[..], expected_64[..]);
|
|
320
|
-
assert_eq!(hash_256[..], expected_256[..]);
|
|
321
|
-
}
|
|
322
|
-
}
|