Skip to content

Commit f90629c

Browse files
committed
cleanup and faster point sampling
1 parent ef1a717 commit f90629c

File tree

3 files changed

+41
-28
lines changed

3 files changed

+41
-28
lines changed

src/elliptic/point.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use fp2::traits::Fp as FpTrait;
2-
use rand_core::{CryptoRng, RngCore};
32

43
/// Special x-only representation of a point (or a pair of points,
54
/// since two Y coordinates may match a given X).
@@ -65,12 +64,6 @@ impl<Fq: FpTrait> PointX<Fq> {
6564
P.Z = Fq::ONE;
6665
}
6766
}
68-
69-
/// Return a new random X only point.
70-
pub fn rand_point<R: CryptoRng + RngCore>(rng: &mut R) -> PointX<Fq> {
71-
let x = Fq::rand(rng);
72-
PointX::from_x_coord(&x)
73-
}
7467
}
7568

7669
impl<Fq: FpTrait> ::std::fmt::Display for PointX<Fq> {

src/protocols/csidh.rs

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub struct Csidh<Fp: FqTrait, const NUM_ELLS: usize, const FSQRTP: usize> {
2828
}
2929

3030
pub struct CsidhPrivateKey<const NUM_ELLS: usize> {
31-
e: [u64; NUM_ELLS], // secret degree
31+
e: [u32; NUM_ELLS], // secret degree
3232
d: [bool; NUM_ELLS], // secret direction
3333
}
3434

@@ -83,27 +83,35 @@ impl<Fp: FqTrait + std::fmt::Debug, const NUM_ELLS: usize, const FSQRTP: usize>
8383
C24: &Fp,
8484
rng: &mut R,
8585
) -> (PointX<Fp>, bool) {
86-
let curve = Curve::<Fp>::curve_from_A24_proj(&A24, &C24);
87-
let P = PointX::rand_point(rng);
88-
89-
// to check if the point is on the curve,
90-
// or on the twist
91-
let (_, twist) = curve.lift_pointx(&P);
86+
// get a random point
87+
let x = Fp::rand(rng);
88+
let P = PointX::from_x_coord(&x);
89+
90+
// projective curve: x^3C+4Ax^2−2x^2C2+XC​
91+
let tmp = (*A24*x)+(*A24*x);
92+
let four_Ax = tmp+tmp;
93+
let tmp = *C24*x;
94+
let Cxx = tmp*x;
95+
let two_Cx = tmp+tmp;
96+
97+
// if RHS i a sqrt, it is on the curve
98+
let RHS = (Cxx+four_Ax-two_Cx+(*C24))*x;
99+
let (_, is_sqrt) = RHS.sqrt();
92100

93-
(P, twist == 0)
101+
(P, is_sqrt == u32::MAX)
94102
}
95103

96104
fn sample_secret_key<R: CryptoRng + RngCore>(&self, rng: &mut R) -> CsidhPrivateKey<NUM_ELLS> {
97-
let mut e = [0u64; NUM_ELLS];
105+
let mut e = [0u32; NUM_ELLS];
98106
let mut d = [false; NUM_ELLS];
99107

100108
for i in 0..NUM_ELLS {
101109
// sample exponent between 0 and max_exponent
102-
e[i] = rng.next_u64();
103-
e[i] >>= 59; // shift to increase probabily to hit the range
104-
while e[i] > self.max_exponent as u64 {
105-
e[i] = rng.next_u64();
106-
e[i] >>= 59;
110+
e[i] = rng.next_u32();
111+
e[i] >>= 27; // shift to increase probabily to hit the range
112+
while e[i] > self.max_exponent as u32 {
113+
e[i] = rng.next_u32() ;
114+
e[i] >>= 27;
107115
}
108116

109117
// sample direction
@@ -113,6 +121,10 @@ impl<Fp: FqTrait + std::fmt::Debug, const NUM_ELLS: usize, const FSQRTP: usize>
113121
CsidhPrivateKey { e, d }
114122
}
115123

124+
//
125+
// ACTION
126+
//
127+
116128
fn action<R: CryptoRng + RngCore>(
117129
&self,
118130
public_key: &CsidhPublicKey<Fp>,
@@ -125,7 +137,7 @@ impl<Fp: FqTrait + std::fmt::Debug, const NUM_ELLS: usize, const FSQRTP: usize>
125137
let mut sk_e = private_key.e;
126138
let sk_d = private_key.d;
127139

128-
let mut done: u64 = sk_e.iter().sum();
140+
let mut done: u32 = sk_e.iter().sum();
129141
while done != 0 {
130142
let (mut P, direction) = self.rand_point(&A24, &C24, rng);
131143

@@ -193,6 +205,13 @@ impl<Fp: FqTrait + std::fmt::Debug, const NUM_ELLS: usize, const FSQRTP: usize>
193205
}
194206
}
195207

208+
209+
210+
//
211+
// VERIFICATION
212+
//
213+
214+
/// recursily computes [p+1/l] for all l
196215
fn cofactor_multiples(&self, P : &mut [PointX<Fp>;NUM_ELLS], A24: &Fp , C24: &Fp, lower: usize, upper: usize) {
197216
if upper - lower == 1 {
198217
return;
@@ -238,16 +257,15 @@ impl<Fp: FqTrait + std::fmt::Debug, const NUM_ELLS: usize, const FSQRTP: usize>
238257
continue;
239258
}
240259

260+
// P should now have order l, so we verify that by checking [l]P = 0
241261
P[i] = Curve::<Fp>::xmul_proj_u64_vartime(&A24, &C24, &P[i], self.primes[i]);
242262

243263
if P[i].is_zero() == 0 {
244264
return false;
245265
}
246266

267+
// if the order of out starting Point is > 4sqrt(p), the curve must be supersingular
247268
order = mul_bn_by_u64_vartime(&order[..], self.primes[i]);
248-
249-
println!("{:#?}", order);
250-
251269
match bn_compare_vartime(&order[..], &self.four_sqrt_p[..]) {
252270
std::cmp::Ordering::Greater => return true,
253271
_ => {},

src/protocols/csidh_parameters.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ mod csidh_512 {
1414
283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 587,
1515
];
1616

17-
const FOUR_SQRT_P: [u64; 5] = [
17+
// not the best place for this...
18+
pub const LEN_4SQRTP: usize = 5;
19+
const FOUR_SQRT_P: [u64; LEN_4SQRTP] = [
1820
0x17895e71e1a20b3f,
1921
0x38d0cd95f8636a56,
2022
0x142b9541e59682cd,
@@ -23,13 +25,13 @@ mod csidh_512 {
2325
];
2426

2527

26-
pub const CSIDH_PARAMS: CsidhParameters<NUM_PRIMES, 5> = CsidhParameters {
28+
pub const CSIDH_PARAMS: CsidhParameters<NUM_PRIMES, LEN_4SQRTP> = CsidhParameters {
2729
max_exponent: MAX_EXPONENT,
2830
two_cofactor: COFACTOR,
2931
primes: PRIMES,
3032
four_sqrt_p: FOUR_SQRT_P,
3133
};
3234
}
3335

34-
pub const CSIDH_512: Csidh<Csidh512, { csidh_512::NUM_PRIMES }, 5> =
36+
pub const CSIDH_512: Csidh<Csidh512, { csidh_512::NUM_PRIMES }, { csidh_512::LEN_4SQRTP}> =
3537
Csidh::new(&csidh_512::CSIDH_PARAMS);

0 commit comments

Comments
 (0)