rgp_web/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use wasm_bindgen::prelude::*;
4
5#[wasm_bindgen]
6pub struct FingerprintResult {
7    fingerprint: Vec<u8>,
8    verifier: Vec<u8>,
9}
10
11#[wasm_bindgen]
12impl FingerprintResult {
13    #[wasm_bindgen(getter)]
14    pub fn fingerprint(&self) -> Vec<u8> {
15        self.fingerprint.clone()
16    }
17    #[wasm_bindgen(getter)]
18    pub fn verifier(&self) -> Vec<u8> {
19        self.verifier.clone()
20    }
21}
22
23#[wasm_bindgen]
24pub fn generate_fingerprint() -> FingerprintResult {
25    let (fingerprint, verifier) = rgp::generate_fingerprint();
26
27    FingerprintResult {
28        fingerprint: fingerprint.into(),
29        verifier: verifier.into(),
30    }
31}
32
33#[wasm_bindgen]
34pub struct DhKeysResult {
35    private: Vec<u8>,
36    public: Vec<u8>,
37}
38
39#[wasm_bindgen]
40impl DhKeysResult {
41    #[wasm_bindgen(getter)]
42    pub fn private(&self) -> Vec<u8> {
43        self.private.clone()
44    }
45    #[wasm_bindgen(getter)]
46    pub fn public(&self) -> Vec<u8> {
47        self.public.clone()
48    }
49}
50
51#[wasm_bindgen]
52pub fn generate_dh_keys() -> DhKeysResult {
53    let (private, public) = rgp::generate_dh_keys();
54
55    DhKeysResult {
56        private: private.into(),
57        public: public.into(),
58    }
59}
60
61#[wasm_bindgen]
62pub fn encrypt_dh(
63    fingerprint: Vec<u8>,
64    content: Vec<u8>,
65    private_key: Vec<u8>,
66    public_keys: Vec<u8>,
67) -> Result<Vec<u8>, String> {
68    let fixed_fingerprint: [u8; 32] = match fingerprint.try_into() {
69        Ok(f) => f,
70        Err(_) => return Err("failed to convert fingerprint to 32 len array".into()),
71    };
72
73    let fixed_private_key: [u8; 32] = match private_key.try_into() {
74        Ok(f) => f,
75        Err(_) => return Err("failed to convert private_key to 32 len array".into()),
76    };
77
78    let mut fixed_public_keys = vec![];
79
80    for public_key in public_keys.chunks_exact(32) {
81        let fixed_public_key: [u8; 32] = match public_key.try_into() {
82            Ok(f) => f,
83            Err(_) => return Err("failed to convert public_key to 32 len array".into()),
84        };
85
86        fixed_public_keys.push(fixed_public_key);
87    }
88
89    let encrypted_content = match rgp::encrypt(
90        fixed_fingerprint,
91        content.clone(),
92        rgp::Encrypt::Dh(fixed_private_key, &fixed_public_keys, None),
93    ) {
94        Ok((encrypted_content, _)) => encrypted_content,
95        Err(err) => return Ok(err.into()),
96    };
97
98    Ok(encrypted_content)
99}
100
101#[wasm_bindgen]
102pub fn decrypt_dh(
103    position: usize,
104    mut encrypted_content: Vec<u8>,
105    verifier: Vec<u8>,
106    public_key: Vec<u8>,
107    private_key: Vec<u8>,
108) -> Result<Vec<u8>, String> {
109    let fixed_verifier: [u8; 32] = match verifier.try_into() {
110        Ok(f) => f,
111        Err(_) => return Err("failed to convert verifier to 32 len array".into()),
112    };
113
114    let fixed_public_key: [u8; 32] = match public_key.try_into() {
115        Ok(f) => f,
116        Err(_) => return Err("failed to convert public_key to 32 len array".into()),
117    };
118
119    let fixed_private_key: [u8; 32] = match private_key.try_into() {
120        Ok(f) => f,
121        Err(_) => return Err("failed to convert private_key to 32 len array".into()),
122    };
123
124    if let rgp::Components::Dh(encrypted_key, _) =
125        rgp::extract_components_mut(position, &mut encrypted_content)
126    {
127        // decrypt message with encrypted content key
128        let decrypted_content = match rgp::decrypt(
129            Some(&fixed_verifier),
130            &encrypted_content,
131            rgp::Decrypt::Dh(encrypted_key, fixed_public_key, fixed_private_key, None),
132        ) {
133            Ok((decrypted_content, _)) => decrypted_content,
134            Err(err) => return Err(err.into()),
135        };
136
137        return Ok(decrypted_content);
138    }
139
140    Err("not DH encryption type".into())
141}
142
143#[test]
144fn test() -> Result<(), String> {
145    let fp_res = generate_fingerprint();
146
147    let rx_dh_keys = generate_dh_keys();
148    let tx_dh_keys = generate_dh_keys();
149
150    let content = vec![1, 2, 3, 4, 5];
151
152    let encrypted = encrypt_dh(
153        fp_res.fingerprint,
154        content.clone(),
155        tx_dh_keys.private,
156        rx_dh_keys.public,
157    )?;
158
159    let decrypted = decrypt_dh(
160        0,
161        encrypted,
162        fp_res.verifier,
163        tx_dh_keys.public,
164        rx_dh_keys.private,
165    )?;
166
167    assert_eq!(content, decrypted);
168
169    Ok(())
170}