1#![allow(non_snake_case)]
15#![deny(missing_docs)]
16
17extern crate alloc;
18
19use alloc::boxed::Box;
20use kyberlib::{
21 KyberLibError, KYBER_CIPHERTEXT_BYTES, KYBER_PUBLIC_KEY_BYTES,
22 KYBER_SECRET_KEY_BYTES, KYBER_SHARED_SECRET_BYTES,
23};
24use rand::rngs::OsRng;
25use wasm_bindgen::prelude::*;
26
27#[wasm_bindgen]
33pub fn keypair() -> Result<Keys, JsError> {
34 let mut rng = OsRng {};
35 match kyberlib::keypair(&mut rng) {
36 Ok(keys) => Ok(Keys {
37 pubkey: Box::new(keys.public),
38 secret: Box::new(keys.secret),
39 }),
40 Err(KyberLibError::RandomBytesGeneration) => {
41 Err(JsError::new("Error trying to fill random bytes"))
42 }
43 _ => Err(JsError::new("The keypair could not be generated")),
44 }
45}
46
47#[wasm_bindgen]
57pub fn encapsulate(pk: Box<[u8]>) -> Result<Kex, JsValue> {
58 if pk.len() != KYBER_PUBLIC_KEY_BYTES {
59 return Err(JsValue::null());
60 }
61
62 let mut rng = OsRng {};
63 match kyberlib::encapsulate(&pk, &mut rng) {
64 Ok(kex) => Ok(Kex {
65 ciphertext: Box::new(kex.0),
66 sharedSecret: Box::new(kex.1),
67 }),
68 Err(_) => Err(JsValue::null()),
69 }
70}
71
72#[wasm_bindgen]
83pub fn decapsulate(
84 ct: Box<[u8]>,
85 sk: Box<[u8]>,
86) -> Result<Box<[u8]>, JsValue> {
87 if ct.len() != KYBER_CIPHERTEXT_BYTES
88 || sk.len() != KYBER_SECRET_KEY_BYTES
89 {
90 return Err(JsValue::null());
91 }
92
93 match kyberlib::decapsulate(&ct, &sk) {
94 Ok(ss) => Ok(Box::new(ss)),
95 Err(_) => Err(JsValue::null()),
96 }
97}
98
99#[wasm_bindgen]
101#[derive(Debug)]
102pub struct Keys {
103 pubkey: Box<[u8]>,
104 secret: Box<[u8]>,
105}
106
107#[wasm_bindgen]
109#[derive(Debug)]
110pub struct Kex {
111 ciphertext: Box<[u8]>,
112 sharedSecret: Box<[u8]>,
113}
114
115#[wasm_bindgen]
116impl Keys {
117 #[wasm_bindgen(constructor)]
125 pub fn new() -> Result<Keys, JsError> {
126 keypair()
127 }
128
129 #[wasm_bindgen(getter)]
133 pub fn pubkey(&self) -> Box<[u8]> {
134 self.pubkey.clone()
135 }
136
137 #[wasm_bindgen(getter)]
141 pub fn secret(&self) -> Box<[u8]> {
142 self.secret.clone()
143 }
144}
145
146#[wasm_bindgen]
147impl Kex {
148 #[wasm_bindgen(constructor)]
158 pub fn new(public_key: Box<[u8]>) -> Self {
159 encapsulate(public_key).expect("Invalid Public Key Size")
160 }
161
162 #[wasm_bindgen(getter)]
166 pub fn ciphertext(&self) -> Box<[u8]> {
167 self.ciphertext.clone()
168 }
169
170 #[wasm_bindgen(getter)]
174 pub fn sharedSecret(&self) -> Box<[u8]> {
175 self.sharedSecret.clone()
176 }
177
178 #[wasm_bindgen(setter)]
184 pub fn set_ciphertext(&mut self, ciphertext: Box<[u8]>) {
185 self.ciphertext = ciphertext;
186 }
187
188 #[wasm_bindgen(setter)]
194 pub fn set_sharedSecret(&mut self, sharedSecret: Box<[u8]>) {
195 self.sharedSecret = sharedSecret;
196 }
197}
198
199#[wasm_bindgen]
201#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
202pub struct Params {
203 #[wasm_bindgen(readonly)]
205 pub publicKeyBytes: usize,
206 #[wasm_bindgen(readonly)]
208 pub secretKeyBytes: usize,
209 #[wasm_bindgen(readonly)]
211 pub ciphertextBytes: usize,
212 #[wasm_bindgen(readonly)]
214 pub sharedSecretBytes: usize,
215}
216
217#[wasm_bindgen]
218impl Params {
219 #[wasm_bindgen(getter)]
221 pub fn publicKeyBytes() -> usize {
222 KYBER_PUBLIC_KEY_BYTES
223 }
224
225 #[wasm_bindgen(getter)]
227 pub fn secretKeyBytes() -> usize {
228 KYBER_SECRET_KEY_BYTES
229 }
230
231 #[wasm_bindgen(getter)]
233 pub fn ciphertextBytes() -> usize {
234 KYBER_CIPHERTEXT_BYTES
235 }
236
237 #[wasm_bindgen(getter)]
239 pub fn sharedSecretBytes() -> usize {
240 KYBER_SHARED_SECRET_BYTES
241 }
242}