Skip to content

Commit

Permalink
fix(ext/node): prime generation (#18861)
Browse files Browse the repository at this point in the history
Towards #18455

`safe`, `add` and `rem` options are not implemented because there is no
rust crate that provides this functionality (except rust-openssl maybe)
and its just not clear if this API is used widely.
  • Loading branch information
littledivy authored Apr 27, 2023
1 parent 742cc31 commit b0264be
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 157 deletions.
216 changes: 108 additions & 108 deletions cli/tests/node_compat/test/parallel/test-crypto-prime.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,129 +36,129 @@ assert(
checks: 10
}));

// (async function() {
// const prime = await pgeneratePrime(36);
// assert(await pCheckPrime(prime));
// })().then(common.mustCall());

// assert.throws(() => {
// generatePrimeSync(32, { bigint: '' });
// }, { code: 'ERR_INVALID_ARG_TYPE' });

// assert.throws(() => {
// generatePrime(32, { bigint: '' }, common.mustNotCall());
// }, { code: 'ERR_INVALID_ARG_TYPE' });

// {
// const prime = generatePrimeSync(3, { bigint: true });
// assert.strictEqual(typeof prime, 'bigint');
// assert.strictEqual(prime, 7n);
// assert(checkPrimeSync(prime));
// checkPrime(prime, common.mustSucceed(assert));
// }
(async function() {
const prime = await pgeneratePrime(36);
assert(await pCheckPrime(prime));
})().then(common.mustCall());

assert.throws(() => {
generatePrimeSync(32, { bigint: '' });
}, { code: 'ERR_INVALID_ARG_TYPE' });

assert.throws(() => {
generatePrime(32, { bigint: '' }, common.mustNotCall());
}, { code: 'ERR_INVALID_ARG_TYPE' });

{
const prime = generatePrimeSync(3, { bigint: true });
assert.strictEqual(typeof prime, 'bigint');
assert.strictEqual(prime, 7n);
assert(checkPrimeSync(prime));
checkPrime(prime, common.mustSucceed(assert));
}

// {
// generatePrime(3, { bigint: true }, common.mustSucceed((prime) => {
// assert.strictEqual(typeof prime, 'bigint');
// assert.strictEqual(prime, 7n);
// assert(checkPrimeSync(prime));
// checkPrime(prime, common.mustSucceed(assert));
// }));
// }
{
generatePrime(3, { bigint: true }, common.mustSucceed((prime) => {
assert.strictEqual(typeof prime, 'bigint');
assert.strictEqual(prime, 7n);
assert(checkPrimeSync(prime));
checkPrime(prime, common.mustSucceed(assert));
}));
}


// ['hello', false, {}, []].forEach((i) => {
// assert.throws(() => generatePrime(i), {
// code: 'ERR_INVALID_ARG_TYPE'
// });
// assert.throws(() => generatePrimeSync(i), {
// code: 'ERR_INVALID_ARG_TYPE'
// });
// });
['hello', false, {}, []].forEach((i) => {
assert.throws(() => generatePrime(i), {
code: 'ERR_INVALID_ARG_TYPE'
});
assert.throws(() => generatePrimeSync(i), {
code: 'ERR_INVALID_ARG_TYPE'
});
});

// ['hello', false, 123].forEach((i) => {
// assert.throws(() => generatePrime(80, i, common.mustNotCall()), {
// code: 'ERR_INVALID_ARG_TYPE'
// });
// assert.throws(() => generatePrimeSync(80, i), {
// code: 'ERR_INVALID_ARG_TYPE'
// });
// });
['hello', false, 123].forEach((i) => {
assert.throws(() => generatePrime(80, i, common.mustNotCall()), {
code: 'ERR_INVALID_ARG_TYPE'
});
assert.throws(() => generatePrimeSync(80, i), {
code: 'ERR_INVALID_ARG_TYPE'
});
});

// ['hello', false, 123].forEach((i) => {
// assert.throws(() => generatePrime(80, {}), {
// code: 'ERR_INVALID_ARG_TYPE'
// });
// });
['hello', false, 123].forEach((i) => {
assert.throws(() => generatePrime(80, {}), {
code: 'ERR_INVALID_ARG_TYPE'
});
});

// [-1, 0, 2 ** 31, 2 ** 31 + 1, 2 ** 32 - 1, 2 ** 32].forEach((size) => {
// assert.throws(() => generatePrime(size, common.mustNotCall()), {
// code: 'ERR_OUT_OF_RANGE',
// message: />= 1 && <= 2147483647/
// });
// assert.throws(() => generatePrimeSync(size), {
// code: 'ERR_OUT_OF_RANGE',
// message: />= 1 && <= 2147483647/
// });
// });
[-1, 0, 2 ** 31, 2 ** 31 + 1, 2 ** 32 - 1, 2 ** 32].forEach((size) => {
assert.throws(() => generatePrime(size, common.mustNotCall()), {
code: 'ERR_OUT_OF_RANGE',
message: />= 1 && <= 2147483647/
});
assert.throws(() => generatePrimeSync(size), {
code: 'ERR_OUT_OF_RANGE',
message: />= 1 && <= 2147483647/
});
});

// ['test', -1, {}, []].forEach((i) => {
// assert.throws(() => generatePrime(8, { safe: i }, common.mustNotCall()), {
// code: 'ERR_INVALID_ARG_TYPE'
// });
// assert.throws(() => generatePrime(8, { rem: i }, common.mustNotCall()), {
// code: 'ERR_INVALID_ARG_TYPE'
// });
// assert.throws(() => generatePrime(8, { add: i }, common.mustNotCall()), {
// code: 'ERR_INVALID_ARG_TYPE'
// });
// assert.throws(() => generatePrimeSync(8, { safe: i }), {
// code: 'ERR_INVALID_ARG_TYPE'
// });
// assert.throws(() => generatePrimeSync(8, { rem: i }), {
// code: 'ERR_INVALID_ARG_TYPE'
// });
// assert.throws(() => generatePrimeSync(8, { add: i }), {
// code: 'ERR_INVALID_ARG_TYPE'
// });
// });
['test', -1, {}, []].forEach((i) => {
assert.throws(() => generatePrime(8, { safe: i }, common.mustNotCall()), {
code: 'ERR_INVALID_ARG_TYPE'
});
assert.throws(() => generatePrime(8, { rem: i }, common.mustNotCall()), {
code: 'ERR_INVALID_ARG_TYPE'
});
assert.throws(() => generatePrime(8, { add: i }, common.mustNotCall()), {
code: 'ERR_INVALID_ARG_TYPE'
});
assert.throws(() => generatePrimeSync(8, { safe: i }), {
code: 'ERR_INVALID_ARG_TYPE'
});
assert.throws(() => generatePrimeSync(8, { rem: i }), {
code: 'ERR_INVALID_ARG_TYPE'
});
assert.throws(() => generatePrimeSync(8, { add: i }), {
code: 'ERR_INVALID_ARG_TYPE'
});
});

// {
// // Negative BigInts should not be converted to 0 silently.
{
// Negative BigInts should not be converted to 0 silently.

// assert.throws(() => generatePrime(20, { add: -1n }, common.mustNotCall()), {
// code: 'ERR_OUT_OF_RANGE',
// message: 'The value of "options.add" is out of range. It must be >= 0. ' +
// 'Received -1n'
// });
assert.throws(() => generatePrime(20, { add: -1n }, common.mustNotCall()), {
code: 'ERR_OUT_OF_RANGE',
message: 'The value of "options.add" is out of range. It must be >= 0. ' +
'Received -1n'
});

// assert.throws(() => generatePrime(20, { rem: -1n }, common.mustNotCall()), {
// code: 'ERR_OUT_OF_RANGE',
// message: 'The value of "options.rem" is out of range. It must be >= 0. ' +
// 'Received -1n'
// });
assert.throws(() => generatePrime(20, { rem: -1n }, common.mustNotCall()), {
code: 'ERR_OUT_OF_RANGE',
message: 'The value of "options.rem" is out of range. It must be >= 0. ' +
'Received -1n'
});

// assert.throws(() => checkPrime(-1n, common.mustNotCall()), {
// code: 'ERR_OUT_OF_RANGE',
// message: 'The value of "candidate" is out of range. It must be >= 0. ' +
// 'Received -1n'
// });
// }
// assert.throws(() => checkPrime(-1n, common.mustNotCall()), {
// code: 'ERR_OUT_OF_RANGE',
// message: 'The value of "candidate" is out of range. It must be >= 0. ' +
// 'Received -1n'
// });
}

// generatePrime(80, common.mustSucceed((prime) => {
// assert(checkPrimeSync(prime));
// checkPrime(prime, common.mustSucceed((result) => {
// assert(result);
// }));
// }));
generatePrime(80, common.mustSucceed((prime) => {
assert(checkPrimeSync(prime));
checkPrime(prime, common.mustSucceed((result) => {
assert(result);
}));
}));

// assert(checkPrimeSync(generatePrimeSync(80)));
assert(checkPrimeSync(generatePrimeSync(80)));

// generatePrime(80, {}, common.mustSucceed((prime) => {
// assert(checkPrimeSync(prime));
// }));
generatePrime(80, {}, common.mustSucceed((prime) => {
assert(checkPrimeSync(prime));
}));

// assert(checkPrimeSync(generatePrimeSync(80, {})));
assert(checkPrimeSync(generatePrimeSync(80, {})));

// generatePrime(32, { safe: true }, common.mustSucceed((prime) => {
// assert(checkPrimeSync(prime));
Expand Down
2 changes: 2 additions & 0 deletions ext/node/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ deno_core::extension!(deno_node,
ops::crypto::op_node_check_prime_async,
ops::crypto::op_node_check_prime_bytes,
ops::crypto::op_node_check_prime_bytes_async,
ops::crypto::op_node_gen_prime,
ops::crypto::op_node_gen_prime_async,
ops::crypto::op_node_pbkdf2,
ops::crypto::op_node_pbkdf2_async,
ops::crypto::op_node_hkdf,
Expand Down
17 changes: 17 additions & 0 deletions ext/node/ops/crypto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -901,3 +901,20 @@ pub async fn op_node_scrypt_async(
})
.await?
}

#[inline]
fn gen_prime(size: usize) -> ZeroCopyBuf {
primes::Prime::generate(size).0.to_bytes_be().into()
}

#[op]
pub fn op_node_gen_prime(size: usize) -> ZeroCopyBuf {
gen_prime(size)
}

#[op]
pub async fn op_node_gen_prime_async(
size: usize,
) -> Result<ZeroCopyBuf, AnyError> {
Ok(tokio::task::spawn_blocking(move || gen_prime(size)).await?)
}
2 changes: 1 addition & 1 deletion ext/node/ops/crypto/primes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use num_traits::Zero;
use rand::Rng;
use std::ops::Deref;

pub struct Prime(num_bigint_dig::BigUint);
pub struct Prime(pub num_bigint_dig::BigUint);

impl Prime {
pub fn generate(n: usize) -> Self {
Expand Down
Loading

0 comments on commit b0264be

Please sign in to comment.