@pezkuwi/wasm-crypto 7.5.12 → 7.5.15

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 (122) hide show
  1. package/Cargo.toml +50 -0
  2. package/Xargo.toml +2 -0
  3. package/build/README.md +29 -0
  4. package/build/bundle-pezkuwi-wasm-crypto.js +2092 -0
  5. package/build/bundle.d.ts +40 -0
  6. package/build/bundle.js +505 -0
  7. package/build/cjs/bundle.d.ts +40 -0
  8. package/build/cjs/bundle.js +544 -0
  9. package/{index.d.ts → build/cjs/index.d.ts} +0 -1
  10. package/build/cjs/index.js +4 -0
  11. package/build/cjs/init.js +21 -0
  12. package/build/cjs/initNone.js +20 -0
  13. package/build/cjs/initOnlyAsm.js +20 -0
  14. package/build/cjs/initOnlyWasm.js +20 -0
  15. package/build/cjs/initWasmAsm.js +20 -0
  16. package/build/cjs/packageInfo.js +4 -0
  17. package/build/index.d.ts +1 -0
  18. package/build/index.js +1 -0
  19. package/build/init.d.ts +16 -0
  20. package/build/init.js +17 -0
  21. package/build/initNone.d.ts +10 -0
  22. package/build/initNone.js +17 -0
  23. package/build/initOnlyAsm.d.ts +10 -0
  24. package/build/initOnlyAsm.js +17 -0
  25. package/build/initOnlyWasm.d.ts +10 -0
  26. package/build/initOnlyWasm.js +17 -0
  27. package/build/initWasmAsm.d.ts +10 -0
  28. package/build/initWasmAsm.js +17 -0
  29. package/build/package.json +208 -0
  30. package/build/packageDetect.d.ts +1 -0
  31. package/build/packageDetect.js +8 -0
  32. package/build/packageInfo.d.ts +6 -0
  33. package/build/packageInfo.js +1 -0
  34. package/build-deno/README.md +25 -0
  35. package/build-deno/bundle.ts +597 -0
  36. package/build-deno/index.ts +2 -0
  37. package/build-deno/init.ts +23 -0
  38. package/build-deno/initNone.ts +21 -0
  39. package/build-deno/initOnlyAsm.ts +21 -0
  40. package/build-deno/initOnlyWasm.ts +21 -0
  41. package/build-deno/initWasmAsm.ts +21 -0
  42. package/build-deno/mod.ts +2 -0
  43. package/build-deno/packageDetect.ts +12 -0
  44. package/build-deno/packageInfo.ts +3 -0
  45. package/build-deno/rs/.editorconfig +10 -0
  46. package/build-tsc/bundle.d.ts +40 -0
  47. package/{cjs → build-tsc}/index.d.ts +0 -1
  48. package/build-tsc-cjs/bundle.js +544 -0
  49. package/{cjs → build-tsc-cjs}/index.js +0 -1
  50. package/build-tsc-cjs/packageDetect.js +10 -0
  51. package/{cjs → build-tsc-cjs}/packageInfo.js +1 -1
  52. package/build-tsc-esm/bundle.js +505 -0
  53. package/{index.js → build-tsc-esm/index.js} +0 -1
  54. package/{packageInfo.js → build-tsc-esm/packageInfo.js} +1 -1
  55. package/package.json +89 -87
  56. package/src/bundle.ts +613 -0
  57. package/src/index.ts +5 -0
  58. package/src/init.ts +25 -0
  59. package/src/initNone.ts +23 -0
  60. package/src/initOnlyAsm.ts +23 -0
  61. package/src/initOnlyWasm.ts +23 -0
  62. package/src/initWasmAsm.ts +23 -0
  63. package/src/lib.rs +24 -0
  64. package/src/mod.ts +4 -0
  65. package/src/packageDetect.ts +16 -0
  66. package/src/packageInfo.ts +6 -0
  67. package/src/rs/.editorconfig +10 -0
  68. package/src/rs/bip39.rs +139 -0
  69. package/src/rs/ed25519.rs +142 -0
  70. package/src/rs/hashing.rs +322 -0
  71. package/src/rs/secp256k1.rs +150 -0
  72. package/src/rs/sr25519.rs +331 -0
  73. package/src/rs/vrf.rs +144 -0
  74. package/test/all/bip39.js +86 -0
  75. package/test/all/ed25519.js +84 -0
  76. package/test/all/hashing.js +138 -0
  77. package/test/all/index.js +126 -0
  78. package/test/all/secp256k1.js +105 -0
  79. package/test/all/sr25519.js +211 -0
  80. package/test/all/vrf.js +74 -0
  81. package/test/asm.js +10 -0
  82. package/test/deno.ts +38 -0
  83. package/test/jest.spec.ts +25 -0
  84. package/test/loader-build.js +39 -0
  85. package/test/wasm.js +8 -0
  86. package/tsconfig.build.json +19 -0
  87. package/tsconfig.build.tsbuildinfo +1 -0
  88. package/tsconfig.spec.json +16 -0
  89. package/tsconfig.spec.tsbuildinfo +1 -0
  90. package/bundle-pezkuwi-wasm-crypto.js +0 -777
  91. package/bundle.d.ts +0 -37
  92. package/bundle.js +0 -165
  93. package/cjs/bundle.d.ts +0 -37
  94. package/cjs/bundle.js +0 -171
  95. /package/{LICENSE → build/LICENSE} +0 -0
  96. /package/{init.d.ts → build/cjs/init.d.ts} +0 -0
  97. /package/{initNone.d.ts → build/cjs/initNone.d.ts} +0 -0
  98. /package/{initOnlyAsm.d.ts → build/cjs/initOnlyAsm.d.ts} +0 -0
  99. /package/{initOnlyWasm.d.ts → build/cjs/initOnlyWasm.d.ts} +0 -0
  100. /package/{initWasmAsm.d.ts → build/cjs/initWasmAsm.d.ts} +0 -0
  101. /package/{cjs → build/cjs}/package.json +0 -0
  102. /package/{packageDetect.d.ts → build/cjs/packageDetect.d.ts} +0 -0
  103. /package/{cjs → build/cjs}/packageDetect.js +0 -0
  104. /package/{packageInfo.d.ts → build/cjs/packageInfo.d.ts} +0 -0
  105. /package/{cjs → build-tsc}/init.d.ts +0 -0
  106. /package/{cjs → build-tsc}/initNone.d.ts +0 -0
  107. /package/{cjs → build-tsc}/initOnlyAsm.d.ts +0 -0
  108. /package/{cjs → build-tsc}/initOnlyWasm.d.ts +0 -0
  109. /package/{cjs → build-tsc}/initWasmAsm.d.ts +0 -0
  110. /package/{cjs → build-tsc}/packageDetect.d.ts +0 -0
  111. /package/{cjs → build-tsc}/packageInfo.d.ts +0 -0
  112. /package/{cjs → build-tsc-cjs}/init.js +0 -0
  113. /package/{cjs → build-tsc-cjs}/initNone.js +0 -0
  114. /package/{cjs → build-tsc-cjs}/initOnlyAsm.js +0 -0
  115. /package/{cjs → build-tsc-cjs}/initOnlyWasm.js +0 -0
  116. /package/{cjs → build-tsc-cjs}/initWasmAsm.js +0 -0
  117. /package/{init.js → build-tsc-esm/init.js} +0 -0
  118. /package/{initNone.js → build-tsc-esm/initNone.js} +0 -0
  119. /package/{initOnlyAsm.js → build-tsc-esm/initOnlyAsm.js} +0 -0
  120. /package/{initOnlyWasm.js → build-tsc-esm/initOnlyWasm.js} +0 -0
  121. /package/{initWasmAsm.js → build-tsc-esm/initWasmAsm.js} +0 -0
  122. /package/{packageDetect.js → build-tsc-esm/packageDetect.js} +0 -0
@@ -0,0 +1,23 @@
1
+ // Copyright 2019-2026 @pezkuwi/wasm-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { createWasm } from '@pezkuwi/wasm-crypto-init/asm';
5
+
6
+ import { initBridge } from './init.js';
7
+
8
+ /**
9
+ * @name initWasm
10
+ * @description
11
+ * For historic purposes and for tighter control on init, specifically performing
12
+ * a WASM initialization with only ASM.js
13
+ *
14
+ * Generally should not be used unless you want explicit control over which
15
+ * interfaces are initialized.
16
+ */
17
+ export async function initWasm (): Promise<void> {
18
+ await initBridge(createWasm);
19
+ }
20
+
21
+ initWasm().catch((): void => {
22
+ // cannot happen, initWasm doesn't throw
23
+ });
@@ -0,0 +1,23 @@
1
+ // Copyright 2019-2026 @pezkuwi/wasm-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { createWasm } from '@pezkuwi/wasm-crypto-init/wasm';
5
+
6
+ import { initBridge } from './init.js';
7
+
8
+ /**
9
+ * @name initWasm
10
+ * @description
11
+ * For historic purposes and for tighter control on init, specifically performing
12
+ * a WASM initialization with only WASM (generally the default for most platforms)
13
+ *
14
+ * Generally should not be used unless you want explicit control over which
15
+ * interfaces are initialized.
16
+ */
17
+ export async function initWasm (): Promise<void> {
18
+ await initBridge(createWasm);
19
+ }
20
+
21
+ initWasm().catch((): void => {
22
+ // cannot happen, initWasm doesn't throw
23
+ });
@@ -0,0 +1,23 @@
1
+ // Copyright 2019-2026 @pezkuwi/wasm-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { createWasm } from '@pezkuwi/wasm-crypto-init/both';
5
+
6
+ import { initBridge } from './init.js';
7
+
8
+ /**
9
+ * @name initWasm
10
+ * @description
11
+ * For historic purposes and for tighter control on init, specifically performing
12
+ * a WASM initialization with ASM and an ASM.js fallback
13
+ *
14
+ * Generally should not be used unless you want explicit control over which
15
+ * interfaces are initialized.
16
+ */
17
+ export async function initWasm (): Promise<void> {
18
+ await initBridge(createWasm);
19
+ }
20
+
21
+ initWasm().catch((): void => {
22
+ // cannot happen, initWasm doesn't throw
23
+ });
package/src/lib.rs ADDED
@@ -0,0 +1,24 @@
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 ADDED
@@ -0,0 +1,4 @@
1
+ // Copyright 2019-2026 @pezkuwi/wasm-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export * from './index.js';
@@ -0,0 +1,16 @@
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
+ // (packageInfo imports will be kept as-is, user-editable)
6
+
7
+ import { detectPackage } from '@pezkuwi/util';
8
+ import { packageInfo as bridgeInfo } from '@pezkuwi/wasm-bridge/packageInfo';
9
+ import { packageInfo as asmInfo } from '@pezkuwi/wasm-crypto-asmjs/packageInfo';
10
+ import { packageInfo as initInfo } from '@pezkuwi/wasm-crypto-init/packageInfo';
11
+ import { packageInfo as wasmInfo } from '@pezkuwi/wasm-crypto-wasm/packageInfo';
12
+ import { packageInfo as utilInfo } from '@pezkuwi/wasm-util/packageInfo';
13
+
14
+ import { packageInfo } from './packageInfo.js';
15
+
16
+ detectPackage(packageInfo, null, [asmInfo, bridgeInfo, initInfo, utilInfo, wasmInfo]);
@@ -0,0 +1,6 @@
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.15' };
@@ -0,0 +1,10 @@
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
@@ -0,0 +1,139 @@
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
+ }
@@ -0,0 +1,142 @@
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
+ }