@@ -28,7 +28,7 @@ pub struct Csidh<Fp: FqTrait, const NUM_ELLS: usize, const FSQRTP: usize> {
28
28
}
29
29
30
30
pub struct CsidhPrivateKey < const NUM_ELLS : usize > {
31
- e : [ u64 ; NUM_ELLS ] , // secret degree
31
+ e : [ u32 ; NUM_ELLS ] , // secret degree
32
32
d : [ bool ; NUM_ELLS ] , // secret direction
33
33
}
34
34
@@ -83,27 +83,35 @@ impl<Fp: FqTrait + std::fmt::Debug, const NUM_ELLS: usize, const FSQRTP: usize>
83
83
C24 : & Fp ,
84
84
rng : & mut R ,
85
85
) -> ( 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 ( ) ;
92
100
93
- ( P , twist == 0 )
101
+ ( P , is_sqrt == u32 :: MAX )
94
102
}
95
103
96
104
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 ] ;
98
106
let mut d = [ false ; NUM_ELLS ] ;
99
107
100
108
for i in 0 ..NUM_ELLS {
101
109
// 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 ;
107
115
}
108
116
109
117
// sample direction
@@ -113,6 +121,10 @@ impl<Fp: FqTrait + std::fmt::Debug, const NUM_ELLS: usize, const FSQRTP: usize>
113
121
CsidhPrivateKey { e, d }
114
122
}
115
123
124
+ //
125
+ // ACTION
126
+ //
127
+
116
128
fn action < R : CryptoRng + RngCore > (
117
129
& self ,
118
130
public_key : & CsidhPublicKey < Fp > ,
@@ -125,7 +137,7 @@ impl<Fp: FqTrait + std::fmt::Debug, const NUM_ELLS: usize, const FSQRTP: usize>
125
137
let mut sk_e = private_key. e ;
126
138
let sk_d = private_key. d ;
127
139
128
- let mut done: u64 = sk_e. iter ( ) . sum ( ) ;
140
+ let mut done: u32 = sk_e. iter ( ) . sum ( ) ;
129
141
while done != 0 {
130
142
let ( mut P , direction) = self . rand_point ( & A24 , & C24 , rng) ;
131
143
@@ -193,6 +205,13 @@ impl<Fp: FqTrait + std::fmt::Debug, const NUM_ELLS: usize, const FSQRTP: usize>
193
205
}
194
206
}
195
207
208
+
209
+
210
+ //
211
+ // VERIFICATION
212
+ //
213
+
214
+ /// recursily computes [p+1/l] for all l
196
215
fn cofactor_multiples ( & self , P : & mut [ PointX < Fp > ; NUM_ELLS ] , A24 : & Fp , C24 : & Fp , lower : usize , upper : usize ) {
197
216
if upper - lower == 1 {
198
217
return ;
@@ -238,16 +257,15 @@ impl<Fp: FqTrait + std::fmt::Debug, const NUM_ELLS: usize, const FSQRTP: usize>
238
257
continue ;
239
258
}
240
259
260
+ // P should now have order l, so we verify that by checking [l]P = 0
241
261
P [ i] = Curve :: < Fp > :: xmul_proj_u64_vartime ( & A24 , & C24 , & P [ i] , self . primes [ i] ) ;
242
262
243
263
if P [ i] . is_zero ( ) == 0 {
244
264
return false ;
245
265
}
246
266
267
+ // if the order of out starting Point is > 4sqrt(p), the curve must be supersingular
247
268
order = mul_bn_by_u64_vartime ( & order[ ..] , self . primes [ i] ) ;
248
-
249
- println ! ( "{:#?}" , order) ;
250
-
251
269
match bn_compare_vartime ( & order[ ..] , & self . four_sqrt_p [ ..] ) {
252
270
std:: cmp:: Ordering :: Greater => return true ,
253
271
_ => { } ,
0 commit comments