-
Notifications
You must be signed in to change notification settings - Fork 10
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 UniScalarRng
#123
Add UniScalarRng
#123
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, small comment.
68bc330
to
032c167
Compare
032c167
to
9514529
Compare
Resolves: #121 Co-authored-by: Victor Lopez <[email protected]>
9514529
to
81ccc66
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we are adding unnecessary complexity by introducing a new RNG. Making it a function of JubJubScalar
would be simpler & more consistent
for integer in scalar.iter_mut() { | ||
*integer = self.0.next_u64(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure we need an iterator here. This will make it harder for the compiler to optimize. Being a small, fixed size array, why not just take the next_u64
?
for (i, integer) in scalar.iter().enumerate() { | ||
let bytes = integer.to_le_bytes(); | ||
dest[i * 8..(i + 1) * 8].copy_from_slice(&bytes); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto; unnecessary usage of iterators
if dest.len() > 32 { | ||
dest[32..].fill(0); | ||
} | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The returned value is a raw little-endian representation of the scalar limbs. This is not the expected serialized format, I wonder why we are doing it.
If we are to generate the limbs, we should probably send them directly to the scalar. We only have to return "bytes" because we opted to create a new RNG, when in fact what we need is to sample uniform 4-tuple u64
.
|
||
use super::{Fr, MODULUS, R2}; | ||
// We use rejection sampling to generate a valid scalar. | ||
fn fill_bytes(&mut self, dest: &mut [u8]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why we create a new RNG when we just want to create new random scalars from a given uniform RNG.
What we are attempting to achieve is to have a uniform implementation for JubJubScalar
that takes a uniform sampler, not to create our own samples (that in the end will increase the type complexity of the stack).
Why not just implement this as a function JubJubScalar::random
or JubJubScalar::uniform_random
?
I favor replacing the previous implementation since the uniform bits is a desirable property in any context.
let mut buf32 = [0u8; 32]; | ||
let mut buf64 = [0u8; 64]; | ||
|
||
for _ in 0..100000 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A more suitable approach would be to use a fuzzing library. Consider quickcheck
After extensive discussions we decided to not change the random scalar generation because it was deemed secure enough for our purpose: We will use this paper to determine whether the current implementation of the random scalar implementation as done in the In the current implementation of For
and
To check whether the above approach is secure, we do the following: For
This leads to:
and
Now we can check whether:
This clearly holds true, which means that we fall in the first conversion of the paper above, and can safely sample an element from the field over This concludes that we don't need to make any adjustments to the current implementation of random scalar generation. |
Resolves: #121