Skip to content

Commit

Permalink
Merge pull request #126 from dusk-network/mocello/random
Browse files Browse the repository at this point in the history
Add uniform random scalar generation
  • Loading branch information
moCello authored Oct 25, 2023
2 parents c9790e0 + c210972 commit 7990d15
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 18 deletions.
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 {
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

0 comments on commit 7990d15

Please sign in to comment.