Skip to content
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

Add (near) optimal default parameters #732

Merged
merged 1 commit into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions fastcrypto-vdf/src/class_group/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use num_traits::Signed;
use rand::distributions::uniform::UniformSampler;
use rand::{Rng, SeedableRng};
use rand_chacha::ChaCha8Rng;
use std::cmp::min;
use std::ops::{AddAssign, ShlAssign, Shr};

impl QuadraticForm {
Expand All @@ -27,7 +26,8 @@ impl QuadraticForm {
///
/// Increasing `k` speeds-up the function (at least up to some break even point), but it also decreases the size of
/// the range of the hash function, so `k` must be picked no larger than the `k` computed in [largest_allowed_k]. If
/// it is larger, an [InvalidInput] error is returned.
/// it is larger, an [InvalidInput] error is returned. If in doubt, use the [hash_to_group_with_default_parameters]
/// instead.
pub fn hash_to_group(
seed: &[u8],
discriminant: &Discriminant,
Expand All @@ -52,13 +52,21 @@ impl QuadraticForm {
seed: &[u8],
discriminant: &Discriminant,
) -> FastCryptoResult<Self> {
// Let k be the largest power of two in the range up to 64
let largest_k = largest_allowed_k(discriminant) + 1;
let k = min(64, largest_k.next_power_of_two() >> 1);
let k = get_default_k(discriminant.bits() as usize);
Self::hash_to_group(seed, discriminant, k)
}
}

fn get_default_k(discriminant_bits: usize) -> u16 {
// This is chosen to ensure that the range of the hash function is large (at least 2^256) but also that the
// performance is near optimal, based on benchmarks.
if discriminant_bits <= 2048 {
16
} else {
32
}
}

/// Increasing `k` reduces the range of the hash function for a given discriminant. This function returns a choice of
/// `k` such that the range is at least `2^256`, and chooses this it as large as possible. Consult the paper for
/// details.
Expand All @@ -80,7 +88,7 @@ fn sample_modulus(
k: u16,
) -> FastCryptoResult<(BigInt, BigInt)> {
// This heuristic bound ensures that the range of the hash function has size at least 2^256.
if k > largest_allowed_k(discriminant) {
if discriminant.bits() < 800 || k > largest_allowed_k(discriminant) {
return Err(InvalidInput);
}

Expand Down
2 changes: 1 addition & 1 deletion fastcrypto-vdf/src/class_group/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,5 +147,5 @@ fn qf_default_hash_test() {
let discriminant = Discriminant::try_from(-BigInt::from_str_radix("c3811f4ad2f4a7bdf2ed89385866ad526c6dd3aa942e04c141d0562a8e7b014f08804f47b3c2ecbba0a5a0ad8f4d8e869a10cff13dbc522aea141f6d1c42913f2d3bff8d3e7656c72523a2e9d47f838234bd65f05ef3ca86c2f640bca6630ed8d1da21e30a67f83e25b89c32c2d0dc0bacb81bd971b0932a82d131b4a74bff36b60b66543105da2c3ecb1a4e8c2cb6d47c1e85942cce8f3fc50c27856e6dfbd15c0bd5017fea15ae0eb43dfb32b2d947c3131d1951f00bcc40352eeb65e364551e40d13768f443406760ee6b37a5b5819d3f630c034c7f42212ad49c803772aaafd4cd1f87697c68d5a6b0855f475b370b20058558993e76759caa38edbc82407b4e3559bade5f7479a860ebef62fed82d657765ebb8f7f375c2b78f73669760e4bd4932177087a49a0b68d7", 16).unwrap()).unwrap();

let qf = QuadraticForm::hash_to_group_with_default_parameters(b"seed", &discriminant).unwrap();
assert_eq!(qf.to_bytes(), hex::decode("008b04397d87d59220ec1bbbf79f471689ad0a48f67625abed478749b2f110d79990684b782160a7e00288c240160d10da0198298fd68f7e3fa0964975f1816d5bb38c978ea1bc9fb5aaefa62971435de9565801c80e545b497d00783c0d518722311c6fa7e924bff4f4765f6f3c6b3de8dcf1c314e7ea8df998de524af394e5cec7dfc867cf07f7eb501dfc270111ff304620732b3d44d3ceeadbd054e20eb953eed85ac684044b1192c1ccaeb9ba79695b28204e7148e8560e4b782c6b20ea20123bda9061eed1920d7ff1fd9741220ee1fac09f596524a12aa993734f2fa4ccf792d46c3bf8320073def0c938e6fb608b8866f70fc380f1a37f3fd9c52935837f5ff06ef6ab882599460e7b950ab17a75602a0b29523ab99c4d030923244a5a9e0431759c59a33a471641c013dadaebdc711baf3a05320330959f13b88c6619c64201bc10517c0bbc69524e6d3345eaeade453ea1ebe8b4ce41068e321399c41e8a90831f9713aa2df564423dfa2fe36e65ccf8157c9ebd24f4ac545482b1a609b7bce94316af8e53cbe191ba073b312a60831ea1f657a92ded17350710ed").unwrap());
assert_eq!(qf.to_bytes(), hex::decode("00910131e81a0ad42da693099a5c3756a494a32be2f80055634b6ffad271b03a1da3d4fd94d310d63ba16dcfaff8ec034215db89aac493573a399d3ecd0db3418234a96ad8cd92f93b3f9d5964e1e7b6d89c4ea7cecaf8a8b86d3ea039b5b47d76cba90539317efc131a8d25b14c2effe966ffdde5151babfe3f5604c1edbc82132c66a8941edd2fa3392b101770d3e0cb90c10117e4aa2da476751cc4ff0a848db4dfbe56ee3e9f09922b3f55c8a0374a2c296fc5a73fc259375d2a931c8e1515cb872005ed5a50ee85ee663b6130254d389c4092d945490e92deeaf27f91d684509ec1b9dd718f01a041d3ade398fac284c3b220950c8832d030d6b0236fa5e6626f63ec0be64f66d82cdcb45f70a169a2c0fff664d1c37f8fafc0153b9f6aeeff986bf056ec5953fc362fcb229a359053f1393a6cbdecc8a0b3e5853be996b0d0ba7a660c00ed6728f4762f01009c8b8ad12b493e8f3e3e9d58837e42372586101e585d40a1715271afe41fe435a57921bd9acd4fcbadfd4e4396812727c3c5fe100296e01d3baa8d9bbc37904080dfcb4860ba8476ac1a0af200244fc8028e71ff7b3a58a85341cb0cdf").unwrap());
}
Loading