@pezkuwi/wasm-crypto 7.5.8 → 7.5.10

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.
Files changed (69) hide show
  1. package/LICENSE +201 -0
  2. package/bundle-pezkuwi-wasm-crypto.js +777 -0
  3. package/bundle.d.ts +37 -0
  4. package/bundle.js +165 -0
  5. package/cjs/bundle.d.ts +37 -0
  6. package/cjs/bundle.js +171 -0
  7. package/cjs/index.js +5 -0
  8. package/cjs/init.js +21 -0
  9. package/cjs/initNone.js +20 -0
  10. package/cjs/initOnlyAsm.js +20 -0
  11. package/cjs/initOnlyWasm.js +20 -0
  12. package/cjs/initWasmAsm.js +20 -0
  13. package/cjs/package.json +3 -0
  14. package/cjs/packageDetect.js +10 -0
  15. package/cjs/packageInfo.js +4 -0
  16. package/index.d.ts +2 -0
  17. package/index.js +2 -0
  18. package/{src/init.ts → init.d.ts} +2 -11
  19. package/init.js +17 -0
  20. package/initNone.d.ts +10 -0
  21. package/{src/initNone.ts → initNone.js} +4 -10
  22. package/initOnlyAsm.d.ts +10 -0
  23. package/{src/initOnlyAsm.ts → initOnlyAsm.js} +4 -10
  24. package/initOnlyWasm.d.ts +10 -0
  25. package/{src/initOnlyWasm.ts → initOnlyWasm.js} +4 -10
  26. package/initWasmAsm.d.ts +10 -0
  27. package/{src/initWasmAsm.ts → initWasmAsm.js} +4 -10
  28. package/package.json +163 -17
  29. package/packageDetect.d.ts +1 -0
  30. package/{src/packageDetect.ts → packageDetect.js} +0 -8
  31. package/packageInfo.d.ts +6 -0
  32. package/packageInfo.js +1 -0
  33. package/Cargo.toml +0 -50
  34. package/Xargo.toml +0 -2
  35. package/build/bundle.d.ts +0 -37
  36. package/src/bundle.ts +0 -247
  37. package/src/index.ts +0 -6
  38. package/src/lib.rs +0 -24
  39. package/src/mod.ts +0 -4
  40. package/src/packageInfo.ts +0 -6
  41. package/src/rs/.editorconfig +0 -10
  42. package/src/rs/bip39.rs +0 -139
  43. package/src/rs/ed25519.rs +0 -142
  44. package/src/rs/hashing.rs +0 -322
  45. package/src/rs/secp256k1.rs +0 -150
  46. package/src/rs/sr25519.rs +0 -331
  47. package/src/rs/vrf.rs +0 -144
  48. package/test/all/bip39.js +0 -86
  49. package/test/all/ed25519.js +0 -84
  50. package/test/all/hashing.js +0 -138
  51. package/test/all/index.js +0 -126
  52. package/test/all/secp256k1.js +0 -105
  53. package/test/all/sr25519.js +0 -211
  54. package/test/all/vrf.js +0 -74
  55. package/test/asm.js +0 -10
  56. package/test/deno.ts +0 -37
  57. package/test/jest.spec.ts +0 -24
  58. package/test/loader-build.js +0 -39
  59. package/test/wasm.js +0 -8
  60. package/tsconfig.build.json +0 -19
  61. package/tsconfig.spec.json +0 -16
  62. /package/{build → cjs}/index.d.ts +0 -0
  63. /package/{build → cjs}/init.d.ts +0 -0
  64. /package/{build → cjs}/initNone.d.ts +0 -0
  65. /package/{build → cjs}/initOnlyAsm.d.ts +0 -0
  66. /package/{build → cjs}/initOnlyWasm.d.ts +0 -0
  67. /package/{build → cjs}/initWasmAsm.d.ts +0 -0
  68. /package/{build → cjs}/packageDetect.d.ts +0 -0
  69. /package/{build → cjs}/packageInfo.d.ts +0 -0
package/src/bundle.ts DELETED
@@ -1,247 +0,0 @@
1
- // Copyright 2019-2026 @pezkuwi/wasm-crypto authors & contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- import type { WasmCryptoInstance } from '@pezkuwi/wasm-crypto-init/types';
5
-
6
- import { bridge, initBridge } from './init.js';
7
-
8
- export { packageInfo } from './packageInfo.js';
9
- export { bridge };
10
-
11
- // Removes the first parameter (expected as WasmCryptoInstance) and leaves the
12
- // rest of the parameters in-tack. This allows us to dynamically create a function
13
- // return from the withWasm helper
14
- type PopFirst<T extends unknown[]> =
15
- T extends [WasmCryptoInstance, ...infer N]
16
- ? N
17
- : [];
18
-
19
- /**
20
- * @internal
21
- * @description
22
- * This create an extenal interface function from the signature, all the while checking
23
- * the actual bridge wasm interface to ensure it has been initialized.
24
- *
25
- * This means that we can call it
26
- *
27
- * withWasm(wasm: WasmCryptoInstance, a: number, b: string) => Uint8Array
28
- *
29
- * and in this case it will create an interface function with the signarure
30
- *
31
- * (a: number, b: string) => Uint8Array
32
- */
33
- function withWasm <T, F extends (wasm: WasmCryptoInstance, ...params: never[]) => T> (fn: F): (...params: PopFirst<Parameters<F>>) => ReturnType<F> {
34
- return (...params: PopFirst<Parameters<F>>): ReturnType<F> => {
35
- if (!bridge.wasm) {
36
- throw new Error('The WASM interface has not been initialized. Ensure that you wait for the initialization Promise with waitReady() from @pezkuwi/wasm-crypto (or cryptoWaitReady() from @pezkuwi/util-crypto) before attempting to use WASM-only interfaces.');
37
- }
38
-
39
- return fn(bridge.wasm, ...params) as ReturnType<F>;
40
- };
41
- }
42
-
43
- export const bip39Generate = /*#__PURE__*/ withWasm((wasm, words: 12 | 15 | 18 | 21 | 24): string => {
44
- wasm.ext_bip39_generate(8, words);
45
-
46
- return bridge.resultString();
47
- });
48
-
49
- export const bip39ToEntropy = /*#__PURE__*/ withWasm((wasm, phrase: string): Uint8Array => {
50
- wasm.ext_bip39_to_entropy(8, ...bridge.allocString(phrase));
51
-
52
- return bridge.resultU8a();
53
- });
54
-
55
- export const bip39ToMiniSecret = /*#__PURE__*/ withWasm((wasm, phrase: string, password: string): Uint8Array => {
56
- wasm.ext_bip39_to_mini_secret(8, ...bridge.allocString(phrase), ...bridge.allocString(password));
57
-
58
- return bridge.resultU8a();
59
- });
60
-
61
- export const bip39ToSeed = /*#__PURE__*/ withWasm((wasm, phrase: string, password: string): Uint8Array => {
62
- wasm.ext_bip39_to_seed(8, ...bridge.allocString(phrase), ...bridge.allocString(password));
63
-
64
- return bridge.resultU8a();
65
- });
66
-
67
- export const bip39Validate = /*#__PURE__*/ withWasm((wasm, phrase: string): boolean => {
68
- const ret = wasm.ext_bip39_validate(...bridge.allocString(phrase));
69
-
70
- return ret !== 0;
71
- });
72
-
73
- export const ed25519KeypairFromSeed = /*#__PURE__*/ withWasm((wasm, seed: Uint8Array): Uint8Array => {
74
- wasm.ext_ed_from_seed(8, ...bridge.allocU8a(seed));
75
-
76
- return bridge.resultU8a();
77
- });
78
-
79
- export const ed25519Sign = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array, seckey: Uint8Array, message: Uint8Array): Uint8Array => {
80
- wasm.ext_ed_sign(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(seckey), ...bridge.allocU8a(message));
81
-
82
- return bridge.resultU8a();
83
- });
84
-
85
- export const ed25519Verify = /*#__PURE__*/ withWasm((wasm, signature: Uint8Array, message: Uint8Array, pubkey: Uint8Array): boolean => {
86
- const ret = wasm.ext_ed_verify(...bridge.allocU8a(signature), ...bridge.allocU8a(message), ...bridge.allocU8a(pubkey));
87
-
88
- return ret !== 0;
89
- });
90
-
91
- export const secp256k1FromSeed = /*#__PURE__*/ withWasm((wasm, seckey: Uint8Array): Uint8Array => {
92
- wasm.ext_secp_from_seed(8, ...bridge.allocU8a(seckey));
93
-
94
- return bridge.resultU8a();
95
- });
96
-
97
- export const secp256k1Compress = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array): Uint8Array => {
98
- wasm.ext_secp_pub_compress(8, ...bridge.allocU8a(pubkey));
99
-
100
- return bridge.resultU8a();
101
- });
102
-
103
- export const secp256k1Expand = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array): Uint8Array => {
104
- wasm.ext_secp_pub_expand(8, ...bridge.allocU8a(pubkey));
105
-
106
- return bridge.resultU8a();
107
- });
108
-
109
- export const secp256k1Recover = /*#__PURE__*/ withWasm((wasm, msgHash: Uint8Array, sig: Uint8Array, recovery: number): Uint8Array => {
110
- wasm.ext_secp_recover(8, ...bridge.allocU8a(msgHash), ...bridge.allocU8a(sig), recovery);
111
-
112
- return bridge.resultU8a();
113
- });
114
-
115
- export const secp256k1Sign = /*#__PURE__*/ withWasm((wasm, msgHash: Uint8Array, seckey: Uint8Array): Uint8Array => {
116
- wasm.ext_secp_sign(8, ...bridge.allocU8a(msgHash), ...bridge.allocU8a(seckey));
117
-
118
- return bridge.resultU8a();
119
- });
120
-
121
- export const sr25519DeriveKeypairHard = /*#__PURE__*/ withWasm((wasm, pair: Uint8Array, cc: Uint8Array): Uint8Array => {
122
- wasm.ext_sr_derive_keypair_hard(8, ...bridge.allocU8a(pair), ...bridge.allocU8a(cc));
123
-
124
- return bridge.resultU8a();
125
- });
126
-
127
- export const sr25519DeriveKeypairSoft = /*#__PURE__*/ withWasm((wasm, pair: Uint8Array, cc: Uint8Array): Uint8Array => {
128
- wasm.ext_sr_derive_keypair_soft(8, ...bridge.allocU8a(pair), ...bridge.allocU8a(cc));
129
-
130
- return bridge.resultU8a();
131
- });
132
-
133
- export const sr25519DerivePublicSoft = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array, cc: Uint8Array): Uint8Array => {
134
- wasm.ext_sr_derive_public_soft(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(cc));
135
-
136
- return bridge.resultU8a();
137
- });
138
-
139
- export const sr25519KeypairFromSeed = /*#__PURE__*/ withWasm((wasm, seed: Uint8Array): Uint8Array => {
140
- wasm.ext_sr_from_seed(8, ...bridge.allocU8a(seed));
141
-
142
- return bridge.resultU8a();
143
- });
144
-
145
- export const sr25519Sign = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array, secret: Uint8Array, message: Uint8Array): Uint8Array => {
146
- wasm.ext_sr_sign(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(secret), ...bridge.allocU8a(message));
147
-
148
- return bridge.resultU8a();
149
- });
150
-
151
- export const sr25519Verify = /*#__PURE__*/ withWasm((wasm, signature: Uint8Array, message: Uint8Array, pubkey: Uint8Array): boolean => {
152
- const ret = wasm.ext_sr_verify(...bridge.allocU8a(signature), ...bridge.allocU8a(message), ...bridge.allocU8a(pubkey));
153
-
154
- return ret !== 0;
155
- });
156
-
157
- export const sr25519Agree = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array, secret: Uint8Array): Uint8Array => {
158
- wasm.ext_sr_agree(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(secret));
159
-
160
- return bridge.resultU8a();
161
- });
162
-
163
- export const vrfSign = /*#__PURE__*/ withWasm((wasm, secret: Uint8Array, context: Uint8Array, message: Uint8Array, extra: Uint8Array): Uint8Array => {
164
- wasm.ext_vrf_sign(8, ...bridge.allocU8a(secret), ...bridge.allocU8a(context), ...bridge.allocU8a(message), ...bridge.allocU8a(extra));
165
-
166
- return bridge.resultU8a();
167
- });
168
-
169
- export const vrfVerify = /*#__PURE__*/ withWasm((wasm, pubkey: Uint8Array, context: Uint8Array, message: Uint8Array, extra: Uint8Array, outAndProof: Uint8Array): boolean => {
170
- const ret = wasm.ext_vrf_verify(...bridge.allocU8a(pubkey), ...bridge.allocU8a(context), ...bridge.allocU8a(message), ...bridge.allocU8a(extra), ...bridge.allocU8a(outAndProof));
171
-
172
- return ret !== 0;
173
- });
174
-
175
- export const blake2b = /*#__PURE__*/ withWasm((wasm, data: Uint8Array, key: Uint8Array, size: number): Uint8Array => {
176
- wasm.ext_blake2b(8, ...bridge.allocU8a(data), ...bridge.allocU8a(key), size);
177
-
178
- return bridge.resultU8a();
179
- });
180
-
181
- export const hmacSha256 = /*#__PURE__*/ withWasm((wasm, key: Uint8Array, data: Uint8Array): Uint8Array => {
182
- wasm.ext_hmac_sha256(8, ...bridge.allocU8a(key), ...bridge.allocU8a(data));
183
-
184
- return bridge.resultU8a();
185
- });
186
-
187
- export const hmacSha512 = /*#__PURE__*/ withWasm((wasm, key: Uint8Array, data: Uint8Array): Uint8Array => {
188
- wasm.ext_hmac_sha512(8, ...bridge.allocU8a(key), ...bridge.allocU8a(data));
189
-
190
- return bridge.resultU8a();
191
- });
192
-
193
- export const keccak256 = /*#__PURE__*/ withWasm((wasm, data: Uint8Array): Uint8Array => {
194
- wasm.ext_keccak256(8, ...bridge.allocU8a(data));
195
-
196
- return bridge.resultU8a();
197
- });
198
-
199
- export const keccak512 = /*#__PURE__*/ withWasm((wasm, data: Uint8Array): Uint8Array => {
200
- wasm.ext_keccak512(8, ...bridge.allocU8a(data));
201
-
202
- return bridge.resultU8a();
203
- });
204
-
205
- export const pbkdf2 = /*#__PURE__*/ withWasm((wasm, data: Uint8Array, salt: Uint8Array, rounds: number): Uint8Array => {
206
- wasm.ext_pbkdf2(8, ...bridge.allocU8a(data), ...bridge.allocU8a(salt), rounds);
207
-
208
- return bridge.resultU8a();
209
- });
210
-
211
- export const scrypt = /*#__PURE__*/ withWasm((wasm, password: Uint8Array, salt: Uint8Array, log2n: number, r: number, p: number): Uint8Array => {
212
- wasm.ext_scrypt(8, ...bridge.allocU8a(password), ...bridge.allocU8a(salt), log2n, r, p);
213
-
214
- return bridge.resultU8a();
215
- });
216
-
217
- export const sha256 = /*#__PURE__*/ withWasm((wasm, data: Uint8Array): Uint8Array => {
218
- wasm.ext_sha256(8, ...bridge.allocU8a(data));
219
-
220
- return bridge.resultU8a();
221
- });
222
-
223
- export const sha512 = /*#__PURE__*/ withWasm((wasm, data: Uint8Array): Uint8Array => {
224
- wasm.ext_sha512(8, ...bridge.allocU8a(data));
225
-
226
- return bridge.resultU8a();
227
- });
228
-
229
- export const twox = /*#__PURE__*/ withWasm((wasm, data: Uint8Array, rounds: number) => {
230
- wasm.ext_twox(8, ...bridge.allocU8a(data), rounds);
231
-
232
- return bridge.resultU8a();
233
- });
234
-
235
- export function isReady (): boolean {
236
- return !!bridge.wasm;
237
- }
238
-
239
- export async function waitReady (): Promise<boolean> {
240
- try {
241
- const wasm = await initBridge();
242
-
243
- return !!wasm;
244
- } catch {
245
- return false;
246
- }
247
- }
package/src/index.ts DELETED
@@ -1,6 +0,0 @@
1
- // Copyright 2019-2026 @pezkuwi/wasm-crypto authors & contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- import './packageDetect.js';
5
-
6
- export * from './bundle.js';
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
@@ -1,4 +0,0 @@
1
- // Copyright 2019-2026 @pezkuwi/wasm-crypto authors & contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- export * from './index.js';
@@ -1,6 +0,0 @@
1
- // Copyright 2017-2026 @pezkuwi/wasm-crypto authors & contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- // Do not edit, auto-generated by @pezkuwi/dev
5
-
6
- export const packageInfo = { name: '@pezkuwi/wasm-crypto', path: 'auto', type: 'auto', version: '7.5.4' };
@@ -1,10 +0,0 @@
1
- root = true
2
- [*]
3
- indent_style=tab
4
- indent_size=tab
5
- tab_width=4
6
- end_of_line=lf
7
- charset=utf-8
8
- trim_trailing_whitespace=true
9
- max_line_length=100
10
- insert_final_newline=true
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
- }