bsv_wasm/ecies/
ecies_ciphertext.rs1use crate::{CipherKeys, PublicKey};
2#[cfg(target_arch = "wasm32")]
3use wasm_bindgen::{prelude::*, throw_str};
4
5use crate::BSVErrors;
6
7#[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-ecies"), wasm_bindgen)]
8pub struct ECIESCiphertext {
9 pub(crate) public_key_bytes: Option<Vec<u8>>,
10 pub(crate) ciphertext_bytes: Vec<u8>,
11 pub(crate) hmac_bytes: Vec<u8>,
12 pub(crate) keys: Option<CipherKeys>,
13}
14
15const PUB_KEY_OFFSET: u8 = 4;
16const PUB_KEY_END: u8 = PUB_KEY_OFFSET + 33;
17
18impl ECIESCiphertext {
19 pub(crate) fn extract_public_key_impl(&self) -> Result<PublicKey, BSVErrors> {
20 let bytes = self.public_key_bytes.clone().ok_or_else(|| BSVErrors::ECIESError("No public key exists in this ciphertext".into()))?;
21 PublicKey::from_bytes_impl(&bytes)
22 }
23
24 pub(crate) fn from_bytes_impl(buffer: &[u8], has_pub_key: bool) -> Result<ECIESCiphertext, BSVErrors> {
25 let pub_key = match has_pub_key {
26 true => {
27 let pub_key_buf = &buffer[PUB_KEY_OFFSET as usize..PUB_KEY_END as usize];
28 PublicKey::from_bytes_impl(pub_key_buf)?;
29 Some(pub_key_buf.to_vec())
30 }
31 false => None,
32 };
33
34 let hmac = &buffer[buffer.len() - 32..buffer.len()];
35 let ciphertext = match has_pub_key {
36 true => &buffer[PUB_KEY_END as usize..buffer.len() - 32],
37 false => &buffer[4..buffer.len() - 32],
38 };
39
40 Ok(ECIESCiphertext {
41 public_key_bytes: pub_key,
42 hmac_bytes: hmac.into(),
43 ciphertext_bytes: ciphertext.into(),
44 keys: None,
45 })
46 }
47}
48
49#[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-ecies"), wasm_bindgen)]
50impl ECIESCiphertext {
51 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-ecies"), wasm_bindgen(js_name = getCiphertext))]
52 pub fn get_ciphertext(&self) -> Vec<u8> {
53 self.ciphertext_bytes.clone()
54 }
55
56 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-ecies"), wasm_bindgen(js_name = getHMAC))]
57 pub fn get_hmac(&self) -> Vec<u8> {
58 self.hmac_bytes.clone()
59 }
60
61 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-ecies"), wasm_bindgen(js_name = getCipherKeys))]
62 pub fn get_cipher_keys(&self) -> Option<CipherKeys> {
63 self.keys.clone()
64 }
65
66 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-ecies"), wasm_bindgen(js_name = toBytes))]
67 pub fn to_bytes(&self) -> Vec<u8> {
68 let mut buffer = vec![];
69 buffer.extend_from_slice(b"BIE1");
70 if let Some(bytes) = self.public_key_bytes.clone() {
71 buffer.extend_from_slice(&bytes);
72 }
73 buffer.extend_from_slice(&self.ciphertext_bytes);
74 buffer.extend_from_slice(&self.hmac_bytes);
75
76 buffer
77 }
78}
79
80#[cfg(target_arch = "wasm32")]
81#[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-ecies"), wasm_bindgen)]
82impl ECIESCiphertext {
83 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-ecies"), wasm_bindgen(js_name = extractPublicKey))]
84 pub fn extract_public_key(&self) -> Result<PublicKey, JsValue> {
85 self.extract_public_key_impl().map_err(|e| JsValue::from_str(&e.to_string()))
86 }
87
88 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-ecies"), wasm_bindgen(js_name = fromBytes))]
89 pub fn from_bytes(buffer: &[u8], has_pub_key: bool) -> Result<ECIESCiphertext, JsValue> {
90 ECIESCiphertext::from_bytes_impl(buffer, has_pub_key).map_err(|e| JsValue::from_str(&e.to_string()))
91 }
92}
93
94#[cfg(not(target_arch = "wasm32"))]
95impl ECIESCiphertext {
96 pub fn extract_public_key(&self) -> Result<PublicKey, BSVErrors> {
97 self.extract_public_key_impl()
98 }
99
100 pub fn from_bytes(buffer: &[u8], has_pub_key: bool) -> Result<ECIESCiphertext, BSVErrors> {
101 ECIESCiphertext::from_bytes_impl(buffer, has_pub_key)
102 }
103}