cml_crypto_wasm/
lib.rs

1use wasm_bindgen::prelude::{wasm_bindgen, JsError};
2
3use cml_crypto::RawBytesEncoding;
4
5pub mod emip3;
6
7#[wasm_bindgen]
8pub struct Bip32PrivateKey(cml_crypto::Bip32PrivateKey);
9
10#[wasm_bindgen]
11impl Bip32PrivateKey {
12    /// derive this private key with the given index.
13    ///
14    /// # Security considerations
15    ///
16    /// * hard derivation index cannot be soft derived with the public key
17    ///
18    /// # Hard derivation vs Soft derivation
19    ///
20    /// If you pass an index below 0x80000000 then it is a soft derivation.
21    /// The advantage of soft derivation is that it is possible to derive the
22    /// public key too. I.e. derivation the private key with a soft derivation
23    /// index and then retrieving the associated public key is equivalent to
24    /// deriving the public key associated to the parent private key.
25    ///
26    /// Hard derivation index does not allow public key derivation.
27    ///
28    /// This is why deriving the private key should not fail while deriving
29    /// the public key may fail (if the derivation index is invalid).
30    ///
31    pub fn derive(&self, index: u32) -> Self {
32        Self(self.0.derive(index))
33    }
34
35    /// 128-byte xprv a key format in Cardano that some software still uses or requires
36    /// the traditional 96-byte xprv is simply encoded as
37    /// prv | chaincode
38    /// however, because some software may not know how to compute a public key from a private key,
39    /// the 128-byte inlines the public key in the following format
40    /// prv | pub | chaincode
41    /// so be careful if you see the term "xprv" as it could refer to either one
42    /// our library does not require the pub (instead we compute the pub key when needed)
43    pub fn from_128_xprv(bytes: &[u8]) -> Result<Bip32PrivateKey, JsError> {
44        cml_crypto::Bip32PrivateKey::from_128_xprv(bytes)
45            .map(Self)
46            .map_err(Into::into)
47    }
48    /// see from_128_xprv
49    pub fn to_128_xprv(&self) -> Vec<u8> {
50        self.0.to_128_xprv()
51    }
52
53    pub fn generate_ed25519_bip32() -> Bip32PrivateKey {
54        Self(cml_crypto::Bip32PrivateKey::generate_ed25519_bip32())
55    }
56
57    pub fn to_raw_key(&self) -> PrivateKey {
58        self.0.to_raw_key().into()
59    }
60
61    pub fn to_public(&self) -> Bip32PublicKey {
62        Bip32PublicKey(self.0.to_public())
63    }
64
65    pub fn from_raw_bytes(bytes: &[u8]) -> Result<Bip32PrivateKey, JsError> {
66        cml_crypto::Bip32PrivateKey::from_raw_bytes(bytes)
67            .map(Self)
68            .map_err(Into::into)
69    }
70
71    pub fn to_raw_bytes(&self) -> Vec<u8> {
72        self.0.to_raw_bytes().to_vec()
73    }
74
75    pub fn from_bech32(bech32_str: &str) -> Result<Bip32PrivateKey, JsError> {
76        cml_crypto::Bip32PrivateKey::from_bech32(bech32_str)
77            .map(Self)
78            .map_err(Into::into)
79    }
80
81    pub fn to_bech32(&self) -> String {
82        self.0.to_bech32()
83    }
84
85    pub fn from_bip39_entropy(entropy: &[u8], password: &[u8]) -> Self {
86        Self(cml_crypto::Bip32PrivateKey::from_bip39_entropy(
87            entropy, password,
88        ))
89    }
90
91    pub fn chaincode(&self) -> Vec<u8> {
92        self.0.chaincode()
93    }
94}
95
96impl From<cml_crypto::Bip32PrivateKey> for Bip32PrivateKey {
97    fn from(inner: cml_crypto::Bip32PrivateKey) -> Self {
98        Self(inner)
99    }
100}
101
102impl From<Bip32PrivateKey> for cml_crypto::Bip32PrivateKey {
103    fn from(wrapper: Bip32PrivateKey) -> Self {
104        wrapper.0
105    }
106}
107
108impl AsRef<cml_crypto::Bip32PrivateKey> for Bip32PrivateKey {
109    fn as_ref(&self) -> &cml_crypto::Bip32PrivateKey {
110        &self.0
111    }
112}
113
114#[wasm_bindgen]
115#[derive(Clone)]
116pub struct Bip32PublicKey(cml_crypto::Bip32PublicKey);
117
118#[wasm_bindgen]
119impl Bip32PublicKey {
120    /// derive this public key with the given index.
121    ///
122    /// # Errors
123    ///
124    /// If the index is not a soft derivation index (< 0x80000000) then
125    /// calling this method will fail.
126    ///
127    /// # Security considerations
128    ///
129    /// * hard derivation index cannot be soft derived with the public key
130    ///
131    /// # Hard derivation vs Soft derivation
132    ///
133    /// If you pass an index below 0x80000000 then it is a soft derivation.
134    /// The advantage of soft derivation is that it is possible to derive the
135    /// public key too. I.e. derivation the private key with a soft derivation
136    /// index and then retrieving the associated public key is equivalent to
137    /// deriving the public key associated to the parent private key.
138    ///
139    /// Hard derivation index does not allow public key derivation.
140    ///
141    /// This is why deriving the private key should not fail while deriving
142    /// the public key may fail (if the derivation index is invalid).
143    ///
144    pub fn derive(&self, index: u32) -> Result<Bip32PublicKey, JsError> {
145        self.0.derive(index).map(Self).map_err(Into::into)
146    }
147
148    pub fn to_raw_key(&self) -> PublicKey {
149        PublicKey(self.0.to_raw_key())
150    }
151
152    pub fn from_raw_bytes(bytes: &[u8]) -> Result<Bip32PublicKey, JsError> {
153        cml_crypto::Bip32PublicKey::from_raw_bytes(bytes)
154            .map(Self)
155            .map_err(Into::into)
156    }
157
158    pub fn to_raw_bytes(&self) -> Vec<u8> {
159        self.0.to_raw_bytes().to_vec()
160    }
161
162    pub fn from_bech32(bech32_str: &str) -> Result<Bip32PublicKey, JsError> {
163        cml_crypto::Bip32PublicKey::from_bech32(bech32_str)
164            .map(Self)
165            .map_err(Into::into)
166    }
167
168    pub fn to_bech32(&self) -> String {
169        self.0.to_bech32()
170    }
171
172    pub fn chaincode(&self) -> Vec<u8> {
173        self.0.chaincode()
174    }
175}
176
177impl From<cml_crypto::Bip32PublicKey> for Bip32PublicKey {
178    fn from(inner: cml_crypto::Bip32PublicKey) -> Self {
179        Self(inner)
180    }
181}
182
183impl From<Bip32PublicKey> for cml_crypto::Bip32PublicKey {
184    fn from(wrapper: Bip32PublicKey) -> Self {
185        wrapper.0
186    }
187}
188
189impl AsRef<cml_crypto::Bip32PublicKey> for Bip32PublicKey {
190    fn as_ref(&self) -> &cml_crypto::Bip32PublicKey {
191        &self.0
192    }
193}
194
195#[wasm_bindgen]
196pub struct PrivateKey(cml_crypto::PrivateKey);
197
198#[wasm_bindgen]
199impl PrivateKey {
200    pub fn to_public(&self) -> PublicKey {
201        PublicKey(self.0.to_public())
202    }
203
204    pub fn generate_ed25519() -> Self {
205        Self(cml_crypto::PrivateKey::generate_ed25519())
206    }
207
208    pub fn generate_ed25519extended() -> Self {
209        Self(cml_crypto::PrivateKey::generate_ed25519extended())
210    }
211
212    /// Get private key from its bech32 representation
213    /// ```javascript
214    /// PrivateKey.from_bech32(&#39;ed25519_sk1ahfetf02qwwg4dkq7mgp4a25lx5vh9920cr5wnxmpzz9906qvm8qwvlts0&#39;);
215    /// ```
216    /// For an extended 25519 key
217    /// ```javascript
218    /// PrivateKey.from_bech32(&#39;ed25519e_sk1gqwl4szuwwh6d0yk3nsqcc6xxc3fpvjlevgwvt60df59v8zd8f8prazt8ln3lmz096ux3xvhhvm3ca9wj2yctdh3pnw0szrma07rt5gl748fp&#39;);
219    /// ```
220    pub fn from_bech32(bech32_str: &str) -> Result<PrivateKey, JsError> {
221        cml_crypto::PrivateKey::from_bech32(bech32_str)
222            .map(Self)
223            .map_err(Into::into)
224    }
225
226    pub fn to_bech32(&self) -> String {
227        self.0.to_bech32()
228    }
229
230    pub fn to_raw_bytes(&self) -> Vec<u8> {
231        self.0.to_raw_bytes().to_vec()
232    }
233
234    pub fn from_extended_bytes(bytes: &[u8]) -> Result<PrivateKey, JsError> {
235        cml_crypto::PrivateKey::from_extended_bytes(bytes)
236            .map(Self)
237            .map_err(Into::into)
238    }
239
240    pub fn from_normal_bytes(bytes: &[u8]) -> Result<PrivateKey, JsError> {
241        cml_crypto::PrivateKey::from_normal_bytes(bytes)
242            .map(Self)
243            .map_err(Into::into)
244    }
245
246    pub fn sign(&self, message: &[u8]) -> Ed25519Signature {
247        Ed25519Signature(self.0.sign(message))
248    }
249}
250
251impl From<cml_crypto::PrivateKey> for PrivateKey {
252    fn from(inner: cml_crypto::PrivateKey) -> Self {
253        Self(inner)
254    }
255}
256
257impl From<PrivateKey> for cml_crypto::PrivateKey {
258    fn from(wrapper: PrivateKey) -> Self {
259        wrapper.0
260    }
261}
262
263impl AsRef<cml_crypto::PrivateKey> for PrivateKey {
264    fn as_ref(&self) -> &cml_crypto::PrivateKey {
265        &self.0
266    }
267}
268
269/// ED25519 key used as public key
270#[wasm_bindgen]
271#[derive(Clone)]
272pub struct PublicKey(cml_crypto::PublicKey);
273
274#[wasm_bindgen]
275impl PublicKey {
276    /// Get public key from its bech32 representation
277    /// Example:
278    /// ```javascript
279    /// const pkey = PublicKey.from_bech32(&#39;ed25519_pk1dgaagyh470y66p899txcl3r0jaeaxu6yd7z2dxyk55qcycdml8gszkxze2&#39;);
280    /// ```
281    pub fn from_bech32(bech32_str: &str) -> Result<PublicKey, JsError> {
282        cml_crypto::PublicKey::from_bech32(bech32_str)
283            .map(Self)
284            .map_err(Into::into)
285    }
286
287    pub fn to_bech32(&self) -> String {
288        self.0.to_bech32()
289    }
290
291    pub fn to_raw_bytes(&self) -> Vec<u8> {
292        self.0.to_raw_bytes().to_vec()
293    }
294
295    pub fn from_bytes(bytes: &[u8]) -> Result<PublicKey, JsError> {
296        cml_crypto::PublicKey::from_raw_bytes(bytes)
297            .map(Self)
298            .map_err(Into::into)
299    }
300
301    pub fn verify(&self, data: &[u8], signature: &Ed25519Signature) -> bool {
302        self.0.verify(data, &signature.0)
303    }
304
305    pub fn hash(&self) -> Ed25519KeyHash {
306        Ed25519KeyHash(self.0.hash())
307    }
308}
309
310impl From<cml_crypto::PublicKey> for PublicKey {
311    fn from(inner: cml_crypto::PublicKey) -> Self {
312        Self(inner)
313    }
314}
315
316impl From<PublicKey> for cml_crypto::PublicKey {
317    fn from(wrapper: PublicKey) -> Self {
318        wrapper.0
319    }
320}
321
322impl AsRef<cml_crypto::PublicKey> for PublicKey {
323    fn as_ref(&self) -> &cml_crypto::PublicKey {
324        &self.0
325    }
326}
327
328macro_rules! impl_signature {
329    ($name:ident) => {
330        #[wasm_bindgen]
331        #[derive(Debug, Clone)]
332        pub struct $name(cml_crypto::$name);
333
334        #[wasm_bindgen]
335        impl $name {
336            pub fn to_bech32(&self) -> String {
337                self.0.to_bech32()
338            }
339
340            pub fn from_bech32(bech32_str: &str) -> Result<$name, wasm_bindgen::JsError> {
341                cml_crypto::$name::from_bech32(bech32_str)
342                    .map(Into::into)
343                    .map(Self)
344                    .map_err(Into::into)
345            }
346        }
347
348        cml_core_wasm::impl_raw_bytes_api!(cml_crypto::$name, $name);
349
350        impl From<cml_crypto::$name> for $name {
351            fn from(inner: cml_crypto::$name) -> Self {
352                Self(inner)
353            }
354        }
355
356        impl From<$name> for cml_crypto::$name {
357            fn from(wrapper: $name) -> cml_crypto::$name {
358                wrapper.0
359            }
360        }
361
362        impl AsRef<cml_crypto::$name> for $name {
363            fn as_ref(&self) -> &cml_crypto::$name {
364                &self.0
365            }
366        }
367    };
368}
369
370impl_signature!(Ed25519Signature);
371
372#[macro_export]
373macro_rules! impl_hash_type_ext {
374    ($rust_name:ty, $wasm_name:ident) => {
375        #[wasm_bindgen::prelude::wasm_bindgen]
376        #[derive(Debug, Clone)]
377        pub struct $wasm_name($rust_name);
378
379        #[wasm_bindgen::prelude::wasm_bindgen]
380        impl $wasm_name {
381            pub fn to_bech32(
382                &self,
383                prefix: &str,
384            ) -> Result<String, wasm_bindgen::prelude::JsError> {
385                self.0.to_bech32(prefix).map_err(Into::into)
386            }
387
388            pub fn from_bech32(
389                bech32_str: &str,
390            ) -> Result<$wasm_name, wasm_bindgen::prelude::JsError> {
391                <$rust_name>::from_bech32(bech32_str)
392                    .map(Into::into)
393                    .map(Self)
394                    .map_err(Into::into)
395            }
396        }
397
398        impl From<$rust_name> for $wasm_name {
399            fn from(inner: $rust_name) -> Self {
400                Self(inner)
401            }
402        }
403
404        impl From<$wasm_name> for $rust_name {
405            fn from(wrapper: $wasm_name) -> $rust_name {
406                wrapper.0
407            }
408        }
409
410        impl AsRef<$rust_name> for $wasm_name {
411            fn as_ref(&self) -> &$rust_name {
412                &self.0
413            }
414        }
415
416        cml_core_wasm::impl_raw_bytes_api!($rust_name, $wasm_name);
417    };
418}
419
420macro_rules! impl_hash_type {
421    ($name:ident) => {
422        impl_hash_type_ext!(cml_crypto::$name, $name);
423    };
424}
425
426impl_hash_type!(Ed25519KeyHash);
427impl_hash_type!(ScriptHash);
428// TransactionHash is either a hash of the tx CBOR or a hash of a redeem address (genesis)
429impl_hash_type!(TransactionHash);
430impl_hash_type!(GenesisDelegateHash);
431impl_hash_type!(GenesisHash);
432impl_hash_type!(AuxiliaryDataHash);
433impl_hash_type!(PoolMetadataHash);
434impl_hash_type!(VRFKeyHash);
435impl_hash_type!(BlockBodyHash);
436impl_hash_type!(BlockHeaderHash);
437impl_hash_type!(DatumHash);
438impl_hash_type!(ScriptDataHash);
439// We might want to make these two vkeys normal classes later but for now it's just arbitrary bytes for us (used in block parsing)
440impl_hash_type!(VRFVkey);
441impl_hash_type!(KESVkey);
442impl_hash_type!(NonceHash);
443impl_hash_type!(AnchorDocHash);
444
445#[wasm_bindgen]
446#[derive(Clone)]
447pub struct LegacyDaedalusPrivateKey(cml_crypto::LegacyDaedalusPrivateKey);
448
449#[wasm_bindgen]
450impl LegacyDaedalusPrivateKey {
451    pub fn chaincode(&self) -> Vec<u8> {
452        self.0.chaincode()
453    }
454}
455
456impl From<cml_crypto::LegacyDaedalusPrivateKey> for LegacyDaedalusPrivateKey {
457    fn from(native: cml_crypto::LegacyDaedalusPrivateKey) -> Self {
458        Self(native)
459    }
460}
461
462impl From<LegacyDaedalusPrivateKey> for cml_crypto::LegacyDaedalusPrivateKey {
463    fn from(wasm: LegacyDaedalusPrivateKey) -> Self {
464        wasm.0
465    }
466}
467
468impl AsRef<cml_crypto::LegacyDaedalusPrivateKey> for LegacyDaedalusPrivateKey {
469    fn as_ref(&self) -> &cml_crypto::LegacyDaedalusPrivateKey {
470        &self.0
471    }
472}