mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-03 17:40:34 +00:00
Use a Group::random which doesn't have a known DL
While Group::random shouldn't be used instead of a hash to curve, anyone who did would've previously been insecure and now isn't. Could've done a recover_x and a raw Point construction, followed by a cofactor mul, to avoid the serialization, yet the serialization ensures full validity under the standard from_bytes function. THis also doesn't need to be micro-optimized.
This commit is contained in:
parent
b97713aac7
commit
ee6316b26b
2 changed files with 24 additions and 8 deletions
|
@ -311,10 +311,15 @@ macro_rules! dalek_group {
|
||||||
|
|
||||||
impl Group for $Point {
|
impl Group for $Point {
|
||||||
type Scalar = Scalar;
|
type Scalar = Scalar;
|
||||||
// Ideally, this would be cryptographically secure, yet that's not a bound on the trait
|
fn random(mut rng: impl RngCore) -> Self {
|
||||||
// k256 also does this
|
loop {
|
||||||
fn random(rng: impl RngCore) -> Self {
|
let mut bytes = field::FieldElement::random(&mut rng).to_repr();
|
||||||
&$BASEPOINT_TABLE * Scalar::random(rng)
|
bytes[31] |= u8::try_from(rng.next_u32() % 2).unwrap() << 7;
|
||||||
|
let opt = Self::from_bytes(&bytes);
|
||||||
|
if opt.is_some().into() {
|
||||||
|
return opt.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn identity() -> Self {
|
fn identity() -> Self {
|
||||||
Self($DPoint::identity())
|
Self($DPoint::identity())
|
||||||
|
|
|
@ -165,10 +165,16 @@ impl SubAssign<&Point> for Point {
|
||||||
|
|
||||||
impl Group for Point {
|
impl Group for Point {
|
||||||
type Scalar = Scalar;
|
type Scalar = Scalar;
|
||||||
// Ideally, this would be cryptographically secure, yet that's not a bound on the trait
|
fn random(mut rng: impl RngCore) -> Self {
|
||||||
// k256 also does this
|
loop {
|
||||||
fn random(rng: impl RngCore) -> Self {
|
let mut bytes = FieldElement::random(&mut rng).to_repr();
|
||||||
Self::generator() * Scalar::random(rng)
|
let mut_ref: &mut [u8] = bytes.as_mut();
|
||||||
|
mut_ref[56] |= u8::try_from(rng.next_u32() % 2).unwrap() << 7;
|
||||||
|
let opt = Self::from_bytes(&bytes);
|
||||||
|
if opt.is_some().into() {
|
||||||
|
return opt.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn identity() -> Self {
|
fn identity() -> Self {
|
||||||
Point { x: FieldElement::zero(), y: FieldElement::one(), z: FieldElement::one() }
|
Point { x: FieldElement::zero(), y: FieldElement::one(), z: FieldElement::one() }
|
||||||
|
@ -378,3 +384,8 @@ a401cd9df24632adfe6b418dc942d8a091817dd8bd70e1c72ba52f3c\
|
||||||
.unwrap()
|
.unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn random() {
|
||||||
|
Point::random(&mut rand_core::OsRng);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue