diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2023-03-28 16:26:38 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-28 10:56:38 +0000 |
commit | 10012c2fe312a4f7ddc5217adaa6718c91bfb819 (patch) | |
tree | a5e5124a43465e5a5fed4e32771e92356b37aa5f /ext/node/crypto/mod.rs | |
parent | 67e21e71ce6a9c7d0f261219609de61f6dd0c7a3 (diff) |
feat(ext/node): add `crypto.checkPrime` API (#18465)
Towards #18455
This commit implements `checkPrimeSync` and `checkPrime` in node:crypto
using the Miller-Rabin primality test (fun fact: it actually is a test
for composite numbers)
It first compares the candidate against many known small primes and if
not, proceeds to run the Miller-Rabin primality test.
http://nickle.org/examples/miller-rabin.5c used as reference
implementation.
Diffstat (limited to 'ext/node/crypto/mod.rs')
-rw-r--r-- | ext/node/crypto/mod.rs | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/ext/node/crypto/mod.rs b/ext/node/crypto/mod.rs index be4035561..352d9c31a 100644 --- a/ext/node/crypto/mod.rs +++ b/ext/node/crypto/mod.rs @@ -2,10 +2,13 @@ use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::op; +use deno_core::serde_v8; use deno_core::OpState; use deno_core::ResourceId; use deno_core::StringOrBuffer; use deno_core::ZeroCopyBuf; +use num_bigint::BigInt; +use std::future::Future; use std::rc::Rc; use rsa::padding::PaddingScheme; @@ -17,6 +20,52 @@ use rsa::RsaPublicKey; mod cipher; mod digest; +mod primes; + +#[op] +pub fn op_node_check_prime(num: serde_v8::BigInt, checks: usize) -> bool { + primes::is_probably_prime(&num, checks) +} + +#[op] +pub fn op_node_check_prime_bytes( + bytes: &[u8], + checks: usize, +) -> Result<bool, AnyError> { + let candidate = BigInt::from_bytes_be(num_bigint::Sign::Plus, bytes); + Ok(primes::is_probably_prime(&candidate, checks)) +} + +#[op] +pub async fn op_node_check_prime_async( + num: serde_v8::BigInt, + checks: usize, +) -> Result<bool, AnyError> { + // TODO(@littledivy): use rayon for CPU-bound tasks + Ok( + tokio::task::spawn_blocking(move || { + primes::is_probably_prime(&num, checks) + }) + .await?, + ) +} + +#[op] +pub fn op_node_check_prime_bytes_async( + bytes: &[u8], + checks: usize, +) -> Result<impl Future<Output = Result<bool, AnyError>> + 'static, AnyError> { + let candidate = BigInt::from_bytes_be(num_bigint::Sign::Plus, bytes); + // TODO(@littledivy): use rayon for CPU-bound tasks + Ok(async move { + Ok( + tokio::task::spawn_blocking(move || { + primes::is_probably_prime(&candidate, checks) + }) + .await?, + ) + }) +} #[op(fast)] pub fn op_node_create_hash(state: &mut OpState, algorithm: &str) -> u32 { |