summaryrefslogtreecommitdiff
path: root/ext/node/crypto/mod.rs
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2023-03-28 16:26:38 +0530
committerGitHub <noreply@github.com>2023-03-28 10:56:38 +0000
commit10012c2fe312a4f7ddc5217adaa6718c91bfb819 (patch)
treea5e5124a43465e5a5fed4e32771e92356b37aa5f /ext/node/crypto/mod.rs
parent67e21e71ce6a9c7d0f261219609de61f6dd0c7a3 (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.rs49
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 {