-
Notifications
You must be signed in to change notification settings - Fork 239
Web optimizations #559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Web optimizations #559
Changes from 1 commit
1dbda17
d804258
b2ab9a1
02507fe
dcd8f4a
e024029
6feb9b7
65ba727
055a7c2
ec6f289
cf72d6c
e5d68a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
Uint8Array when not necessary
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,39 +7,51 @@ pub use crate::util::{inner_u32, inner_u64}; | |
| #[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))] | ||
| compile_error!("`wasm_js` backend can be enabled only for OS-less WASM targets!"); | ||
|
|
||
| #[cfg(target_feature = "atomics")] | ||
| use js_sys::Uint8Array; | ||
newpavlov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; | ||
|
|
||
| // Size of our temporary Uint8Array buffer used with WebCrypto methods | ||
| // Maximum is 65536 bytes see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues | ||
| const CRYPTO_BUFFER_SIZE: u16 = 256; | ||
| // Maximum buffer size allowed in `Crypto.getRandomValuesSize` is 65536 bytes. | ||
| // See https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues | ||
| const MAX_BUFFER_SIZE: u16 = 256; | ||
daxpedda marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { | ||
| CRYPTO.with(|crypto| { | ||
| let crypto = crypto.as_ref().ok_or(Error::WEB_CRYPTO)?; | ||
|
|
||
| // getRandomValues does not work with all types of WASM memory, | ||
| // so we initially write to browser memory to avoid exceptions. | ||
| let buf = Uint8Array::new_with_length(CRYPTO_BUFFER_SIZE.into()); | ||
| for chunk in dest.chunks_mut(CRYPTO_BUFFER_SIZE.into()) { | ||
| let chunk_len: u32 = chunk | ||
| .len() | ||
| .try_into() | ||
| .expect("chunk length is bounded by CRYPTO_BUFFER_SIZE"); | ||
| // The chunk can be smaller than buf's length, so we call to | ||
| // JS to create a smaller view of buf without allocation. | ||
| let sub_buf = if chunk_len == u32::from(CRYPTO_BUFFER_SIZE) { | ||
| buf.clone() | ||
| } else { | ||
| buf.subarray(0, chunk_len) | ||
| }; | ||
|
|
||
| if crypto.get_random_values(&sub_buf).is_err() { | ||
| return Err(Error::WEB_GET_RANDOM_VALUES); | ||
| #[cfg(not(target_feature = "atomics"))] | ||
| { | ||
| for chunk in dest.chunks_mut(MAX_BUFFER_SIZE.into()) { | ||
| if crypto.get_random_values(chunk).is_err() { | ||
| return Err(Error::WEB_GET_RANDOM_VALUES); | ||
| } | ||
| } | ||
| } | ||
| #[cfg(target_feature = "atomics")] | ||
| { | ||
| // getRandomValues does not work with all types of WASM memory, | ||
| // so we initially write to browser memory to avoid exceptions. | ||
| let buf = Uint8Array::new_with_length(MAX_BUFFER_SIZE.into()); | ||
| for chunk in dest.chunks_mut(MAX_BUFFER_SIZE.into()) { | ||
| let chunk_len: u32 = chunk | ||
| .len() | ||
| .try_into() | ||
| .expect("chunk length is bounded by MAX_BUFFER_SIZE"); | ||
| // The chunk can be smaller than buf's length, so we call to | ||
| // JS to create a smaller view of buf without allocation. | ||
| let sub_buf = if chunk_len == u32::from(MAX_BUFFER_SIZE) { | ||
| buf.clone() | ||
| } else { | ||
| buf.subarray(0, chunk_len) | ||
| }; | ||
|
|
||
| if crypto.get_random_values(&sub_buf).is_err() { | ||
| return Err(Error::WEB_GET_RANDOM_VALUES); | ||
| } | ||
|
|
||
| // SAFETY: `sub_buf`'s length is the same length as `chunk` | ||
| unsafe { sub_buf.raw_copy_to_ptr(chunk.as_mut_ptr().cast::<u8>()) }; | ||
| // SAFETY: `sub_buf`'s length is the same length as `chunk` | ||
| unsafe { sub_buf.raw_copy_to_ptr(chunk.as_mut_ptr().cast::<u8>()) }; | ||
| } | ||
| } | ||
| Ok(()) | ||
| }) | ||
|
|
@@ -53,6 +65,10 @@ extern "C" { | |
| #[wasm_bindgen(thread_local_v2, js_name = crypto)] | ||
|
||
| static CRYPTO: Option<Crypto>; | ||
| // Crypto.getRandomValues() | ||
| #[cfg(not(target_feature = "atomics"))] | ||
| #[wasm_bindgen(method, js_name = getRandomValues, catch)] | ||
|
||
| fn get_random_values(this: &Crypto, buf: &mut [MaybeUninit<u8>]) -> Result<(), JsValue>; | ||
| #[cfg(target_feature = "atomics")] | ||
| #[wasm_bindgen(method, js_name = getRandomValues, catch)] | ||
| fn get_random_values(this: &Crypto, buf: &Uint8Array) -> Result<(), JsValue>; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.