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 uniform random scalar generation #126

Merged
merged 1 commit into from
Oct 25, 2023
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
41 changes: 23 additions & 18 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add `uni_random` scalar generation [#125]

## [0.12.2] - 2023-10-11

### Fixed
Expand Down Expand Up @@ -210,24 +214,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Rename `S` to `TWO_ADACITY` and export it

<!-- Issues -->
[#117]: (https://github.com/dusk-network/bls12_381/issues/117)
[#109]: (https://github.com/dusk-network/bls12_381/issues/109)
[#108]: (https://github.com/dusk-network/bls12_381/issues/108)
[#100]: (https://github.com/dusk-network/bls12_381/issues/100)
[#93]: (https://github.com/dusk-network/bls12_381/issues/93)
[#75]: (https://github.com/dusk-network/bls12_381/issues/75)
[#84]: (https://github.com/dusk-network/bls12_381/issues/84)
[#94]: (https://github.com/dusk-network/bls12_381/issues/94)
[#90]: (https://github.com/dusk-network/bls12_381/issues/90)
[#86]: (https://github.com/dusk-network/bls12_381/issues/86)
[#78]: (https://github.com/dusk-network/bls12_381/issues/78)
[#61]: (https://github.com/dusk-network/bls12_381/issues/61)
[#67]: (https://github.com/dusk-network/bls12_381/issues/67)
[#54]: (https://github.com/dusk-network/bls12_381/issues/54)
[#59]: (https://github.com/dusk-network/bls12_381/issues/59)
[#58]: (https://github.com/dusk-network/bls12_381/issues/58)
[#52]: (https://github.com/dusk-network/bls12_381/issues/52)
[#50]: (https://github.com/dusk-network/bls12_381/issues/50)
[#125]: https://github.com/dusk-network/bls12_381/issues/125
[#117]: https://github.com/dusk-network/bls12_381/issues/117
[#109]: https://github.com/dusk-network/bls12_381/issues/109
[#108]: https://github.com/dusk-network/bls12_381/issues/108
[#100]: https://github.com/dusk-network/bls12_381/issues/100
[#93]: https://github.com/dusk-network/bls12_381/issues/93
[#75]: https://github.com/dusk-network/bls12_381/issues/75
[#84]: https://github.com/dusk-network/bls12_381/issues/84
[#94]: https://github.com/dusk-network/bls12_381/issues/94
[#90]: https://github.com/dusk-network/bls12_381/issues/90
[#86]: https://github.com/dusk-network/bls12_381/issues/86
[#78]: https://github.com/dusk-network/bls12_381/issues/78
[#61]: https://github.com/dusk-network/bls12_381/issues/61
[#67]: https://github.com/dusk-network/bls12_381/issues/67
[#54]: https://github.com/dusk-network/bls12_381/issues/54
[#59]: https://github.com/dusk-network/bls12_381/issues/59
[#58]: https://github.com/dusk-network/bls12_381/issues/58
[#52]: https://github.com/dusk-network/bls12_381/issues/52
[#50]: https://github.com/dusk-network/bls12_381/issues/50

<!-- Versions -->
[Unreleased]: https://github.com/dusk-network/bls12_381/compare/v0.12.2...HEAD
Expand Down
36 changes: 36 additions & 0 deletions src/scalar/dusk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use core::cmp::{Ord, Ordering, PartialOrd};
use core::convert::TryFrom;
use core::ops::{BitAnd, BitXor};
use dusk_bytes::{Error as BytesError, Serializable};
use rand_core::{CryptoRng, RngCore};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};

use super::{Scalar, MODULUS, R2};
Expand Down Expand Up @@ -253,6 +254,41 @@ impl Scalar {
res
}

/// Compute a uniformly distributed random scalar.
///
/// Because scalars take 255 bits for encoding it is difficult to generate
/// random bit-pattern that ensures to encodes a valid scalar.
/// Wrapping the values that are higher than [`MODULUS`], as done in
/// [`Self::random`], results in hitting some values more than others, and
/// zeroing out the highest two bits will eliminate some values from the
/// possible results.
///
/// This function achieves a uniform distribution of scalars by using
/// rejection sampling: random bit-patterns are generated until a valid
/// scalar is found.
/// The function is not constant time but that shouldn't be a concern since
/// no information about the scalar can be gained by knowing the time of
/// its generation.
pub fn uni_random<R>(rng: &mut R) -> Self
where
R: RngCore + CryptoRng,
{
let mut buf = [0; 32];
let mut scalar: Option<Self> = None;

// We loop as long as it takes to generate a valid scalar.
// As long as the random number generator is implemented properly, this
// loop will terminate.
while scalar == None {
moCello marked this conversation as resolved.
Show resolved Hide resolved
rng.fill_bytes(&mut buf);
// Since modulus has at most 255 bits, we can zero the MSB and like
// this improve our chances of hitting a valid scalar to above 50%
buf[32 - 1] &= 0b0111_1111;
scalar = Self::from_bytes(&buf).into();
}
scalar.unwrap()
}

/// SHR impl
#[inline]
pub fn divn(&mut self, mut n: u32) {
Expand Down