1
2use crate::bngf2m::*;
3use crate::group::*;
4use crate::utils::*;
5use crate::mont::*;
6use num_bigint::{BigInt};
8use num_traits::{zero,one};
9use std::error::Error;
10use std::cmp::PartialEq;
11
12#[allow(unused_imports)]
13use crate::logger::*;
14#[allow(unused_imports)]
15use crate::randop::*;
16
17
18ecsimple_error_class!{BnGf2mPointError}
19
20#[derive(Clone)]
21pub (crate) struct ECGf2mPoint {
22 x :BnGf2m,
23 y :BnGf2m,
24 z :BnGf2m,
25 pub (crate) group :ECGroupBnGf2m,
26 infinity : bool,
27}
28
29
30impl std::fmt::Display for ECGf2mPoint {
31 fn fmt(&self, f:&mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32 write!(f,"curve[{}] isinfinity {} x 0x{:x} y 0x{:x} z 0x{:x}", self.group,self.infinity,self.x,self.y,self.z)
33 }
34}
35
36impl std::default::Default for ECGf2mPoint {
37 fn default() -> Self {
38 ECGf2mPoint {
39 x : BnGf2m::default(),
40 y :BnGf2m::default(),
41 z :BnGf2m::default(),
42 group : ECGroupBnGf2m::default(),
43 infinity : true,
44 }
45 }
46}
47
48impl PartialEq for ECGf2mPoint {
49 fn eq(&self, other :&ECGf2mPoint) -> bool {
50 return self.eq_op(other);
51 }
52
53 fn ne(&self, other :&ECGf2mPoint) -> bool {
54 return !self.eq(other);
55 }
56}
57
58
59impl ECGf2mPoint {
60 pub fn is_infinity(&self) -> bool {
61 return self.infinity;
62 }
63
64 pub fn new(grp :&ECGroupBnGf2m) -> ECGf2mPoint {
65 ECGf2mPoint {
66 x : grp.generator.x.clone(),
67 y : grp.generator.y.clone(),
68 z : grp.generator.z.clone(),
69 group : grp.clone(),
70 infinity : false,
71 }
72 }
73
74 pub fn eq_op(&self, other :&ECGf2mPoint) -> bool {
75 if self.x != other.x {
76 return false;
77 }
78
79 if self.y != other.y {
80 return false;
81 }
82
83 if self.z != other.z {
84 return false;
85 }
86
87 if self.group != other.group {
88 return false;
89 }
90
91 if self.infinity != other.infinity {
92 return false;
93 }
94 return true;
95 }
96
97 pub fn new_point(x :&BnGf2m, y :&BnGf2m,z :&BnGf2m, grp :&ECGroupBnGf2m) -> Self {
98 Self {
99 x :x.clone(),
100 y :y.clone(),
101 z :z.clone(),
102 group :grp.clone(),
103 infinity : false,
104 }
105 }
106
107
108
109 pub fn set_x(&mut self, x :&BnGf2m) {
110 self.x = x.clone();
111 }
112
113 pub fn set_y(&mut self, y :&BnGf2m) {
114 self.y = y.clone();
115 }
116
117 pub fn set_z(&mut self, z :&BnGf2m) {
118 self.z = z.clone();
119 }
120
121 pub fn x(&self) -> BnGf2m {
122 return self.x.clone();
123 }
124
125 pub fn y(&self) -> BnGf2m {
126 return self.y.clone();
127 }
128
129 #[allow(dead_code)]
130 pub fn z(&self) -> BnGf2m {
131 return self.z.clone();
132 }
133
134 pub fn field_mul(&self,a :&BnGf2m, b :&BnGf2m) -> BnGf2m {
135 let retv :BnGf2m ;
136 retv = a * b;
137 let ord :BnGf2m = BnGf2m::new_from_bigint(&self.group.p);
138 ecsimple_log_trace!("a 0x{:X} * b 0x{:X} % ord 0x{:X} = 0x{:X}",a,b,ord, retv.clone() % ord.clone());
139 return retv % ord;
140 }
141
142 pub fn field_sqr(&self,a :&BnGf2m) -> BnGf2m {
143 let retv :BnGf2m;
144 retv = a * a;
145 let ord :BnGf2m = BnGf2m::new_from_bigint(&self.group.p);
146 ecsimple_log_trace!("a 0x{:X} * a 0x{:X} % ord 0x{:X} = 0x{:X}",a,a, ord,retv.clone() % ord.clone());
147 return retv % ord;
148 }
149
150 pub fn field_div(&self,a :&BnGf2m, b:&BnGf2m) -> Result<BnGf2m,Box<dyn Error>> {
151 let fp :BnGf2m = BnGf2m::new_from_bigint(&self.group.p);
152 let invb :BnGf2m = b.inv_op(&fp)?;
153 ecsimple_log_trace!("0x{:X} * 0x{:X} = 1 % 0x{:X}",invb,b,fp);
154 let retv :BnGf2m = invb.mul_op(&a).mod_op(&fp);
155 ecsimple_log_trace!("r 0x{:X} = ( y 0x{:X} * xinv 0x{:X} % p 0x{:X} )",retv,a,invb,fp);
156 Ok(retv)
157 }
158
159 fn ladder_pre(&self, r :&mut ECGf2mPoint, s :&mut ECGf2mPoint, p :&ECGf2mPoint, bits :u64) {
160 let mut bs :BigInt;
161 bs = ecsimple_rand_bits(bits,-1,0);
162 s.z = BnGf2m::new_from_bigint(&bs);
163 s.x = self.field_mul(&(p.x),&(s.z));
166 bs = ecsimple_rand_bits(bits,-1,0);
170 r.y = BnGf2m::new_from_bigint(&bs);
171 r.z = self.field_sqr(&(p.x));
173 r.x = self.field_sqr(&(r.z));
174 r.x = &r.x + &self.group.b;
175 r.z = self.field_mul(&(r.z),&(r.y));
176 r.x = self.field_mul(&(r.x),&(r.y));
177
178 ecsimple_log_trace!("r->X 0x{:X} r->Y 0x{:X} r->Z 0x{:X}", r.x,r.y,r.z);
179
180 return;
181 }
182
183 fn ladder_step(&self, r :&mut ECGf2mPoint, s :&mut ECGf2mPoint, p :&ECGf2mPoint) {
184 r.y = self.field_mul(&(r.z),&(s.x));
185 s.x = self.field_mul(&(r.x),&(s.z));
186 s.y = self.field_sqr(&(r.z));
187
188 r.z = self.field_sqr(&(r.x));
189 s.z = &r.y + &s.x;
190 s.z = self.field_sqr(&(s.z));
191 s.x = self.field_mul(&(r.y),&(s.x));
192 r.y = self.field_mul(&(s.z),&(p.x));
193 s.x = &s.x + &r.y;
194
195 r.y = self.field_sqr(&(r.z));
196 r.z = self.field_mul(&(r.z),&(s.y));
197 s.y = self.field_sqr(&(s.y));
198 s.y = self.field_mul(&(s.y),&(self.group.b));
199 r.x = &r.y + &s.y;
200
201 return;
202 }
203
204 fn make_affine(&self, _r :&mut ECGf2mPoint) {
205 return;
206 }
207
208 fn point_invert(&self, r :&mut ECGf2mPoint) {
209 if r.is_infinity() || r.y.is_zero() {
210 return;
211 }
212
213 self.make_affine(r);
214 r.y = &r.x + &r.y;
215 return;
216 }
217
218 fn field_inv(&self,a :&BnGf2m) -> BnGf2m {
219 let pbn :BnGf2m = BnGf2m::new_from_bigint(&self.group.p);
220 let bn = a.inv_op(&pbn).unwrap();
221 ecsimple_log_trace!("r 0x{:X} * a 0x{:X} = 1 % 0x{:X}", bn,a,pbn);
222 return bn;
223 }
224
225 fn ladder_post(&self,r :&mut ECGf2mPoint,s :&ECGf2mPoint,p :&ECGf2mPoint) {
226 if r.z.is_zero() {
227 r.infinity = true;
228 return;
229 }
230 if s.z.is_zero() {
231 *r = p.clone();
232 self.point_invert(r);
233 return;
234 }
235 let t0 :BnGf2m;
236 let mut t1 :BnGf2m;
237 let mut t2 :BnGf2m;
238
239 t0 = self.field_mul(&(r.z),&(s.z));
240 t1 = self.field_mul(&(p.x),&(r.z));
241 t1 = &r.x + &t1;
242 t2 = self.field_mul(&(p.x),&(s.z));
244 r.z = self.field_mul(&(r.x),&t2);
245 t2 = &t2 + &s.x;
246 t1 = self.field_mul(&t1,&t2);
248 t2 = self.field_sqr(&p.x);
249 t2 = &p.y + &t2;
250 t2 = self.field_mul(&t2,&t0);
252 t1 = &t2 + &t1;
253 t2 = self.field_mul(&p.x,&t0);
255 t2 = self.field_inv(&t2);
256 t1 = self.field_mul(&t1,&t2);
257 r.x = self.field_mul(&r.z,&t2);
258 t2 = &p.x + &r.x;
259 t2 = self.field_mul(&t2,&t1);
261 r.y = &p.y + &t2;
262 r.z = BnGf2m::one();
264 return;
267 }
268
269 pub fn mulex_op(&self,bn1 :&BigInt,bn2 :&BigInt) -> Result<ECGf2mPoint,Box<dyn Error>> {
270 let retv :ECGf2mPoint;
271 let t :ECGf2mPoint = self.mul_op(bn1,false);
272 let r :ECGf2mPoint = self.mul_op(bn2,true);
273 retv = t.add_op_res(&r)?;
274
275 Ok(retv)
276 }
277
278 pub fn add_op_res(&self, other :&ECGf2mPoint) -> Result<ECGf2mPoint,Box<dyn Error>> {
279 if !self.group.eq_op(&other.group) {
280 ecsimple_new_error!{BnGf2mPointError,"self and other not same group"}
281 }
282 let mut retv :ECGf2mPoint = ECGf2mPoint::default();
283 let (x0,y0,x1,y1,mut x2,mut y2) : (BnGf2m,BnGf2m,BnGf2m,BnGf2m,BnGf2m,BnGf2m);
284 let (mut s, t) : (BnGf2m,BnGf2m);
285 if self.infinity || other.infinity {
286 if self.infinity {
287 retv = other.clone();
288 } else {
289 retv = self.clone();
290 }
291 return Ok(retv);
292 }
293 x0 = self.x.clone();
294 y0 = self.y.clone();
295 x1 = other.x.clone();
296 y1 = other.y.clone();
297 ecsimple_log_trace!("x0 0x{:X} y0 0x{:X}",x0,y0);
298 ecsimple_log_trace!("x1 0x{:X} y1 0x{:X}",x1,y1);
299 if !x0.eq_op(&x1) {
300 t = &x0 + &x1;
301 ecsimple_log_trace!("t 0x{:X} = x0 0x{:X} + x1 0x{:X}",t,x0,x1);
302 s = &y0 + &y1;
303 ecsimple_log_trace!("s 0x{:X} = y0 0x{:X} + y1 0x{:X}",s,y0,y1);
304 s = self.field_div(&s,&t)?;
305 x2 = self.field_sqr(&s);
306 x2 = &x2 + &self.group.a;
307 ecsimple_log_trace!("x2 0x{:X} group->a 0x{:X}",x2,self.group.a);
308 x2 = &x2 + &s;
309 ecsimple_log_trace!("x2 0x{:X} s 0x{:X}",x2,s);
310 x2 = &x2 + &t;
311 ecsimple_log_trace!("x2 0x{:X} t 0x{:X}",x2,t);
312 } else {
313 if y0.eq_op(&y1) || x1.is_one() {
314 retv = ECGf2mPoint::default();
315 retv.infinity = true;
316 return Ok(retv);
317 }
318 s = self.field_div(&y1,&x1)?;
319 s = &s + &x1;
320 ecsimple_log_trace!("s 0x{:X} x1 0x{:X}", s, x1);
321 x2 = self.field_sqr(&s);
322 x2 = &x2 + &s;
323 ecsimple_log_trace!("x2 0x{:X} s 0x{:X}",x2,s);
324 x2 = &x2 + &self.group.a;
325 ecsimple_log_trace!("x2 0x{:X} group->a 0x{:X}",x2,self.group.a);
326 }
327
328 y2 = &x1 + &x2;
329 ecsimple_log_trace!("y2 0x{:X} = x1 0x{:X} + x2 0x{:X}",y2,x1,x2);
330 y2 = self.field_mul(&y2,&s);
331 y2 = &y2 + &x2;
332 ecsimple_log_trace!("y2 0x{:X} x2 0x{:X}",y2,x2);
333 y2 = &y2 + &y1;
334 ecsimple_log_trace!("y2 0x{:X} y1 0x{:X}",y2,y1);
335
336 retv.x = x2.clone();
337 retv.y = y2.clone();
338 retv.z = BnGf2m::one();
339 retv.infinity = false;
340
341 ecsimple_log_trace!("r.x 0x{:X} r.y 0x{:X} r.z 0x{:X}", retv.x,retv.y,retv.z);
342
343 Ok(retv)
344 }
345
346
347 pub fn mul_op(&self, bn :&BigInt,copyxy :bool) -> ECGf2mPoint {
348 let zv :BigInt = zero();
349 let p :ECGf2mPoint ;
350 let mut s :ECGf2mPoint = ECGf2mPoint::new(&self.group);
351 let mut r :ECGf2mPoint = ECGf2mPoint::new(&self.group);
352 let mut tmp :ECGf2mPoint;
353 let cardinal :BigInt;
354 let lamda :BigInt;
355 let mut k :BigInt;
356 if bn <= &zv {
357 r = self.clone();
358 r.infinity = true;
359 return r;
360 }
361
362 if self.infinity {
363 return self.clone();
364 }
365
366 if copyxy {
367 p = self.clone();
368 } else {
369 p = ECGf2mPoint::new(&self.group);
370 }
371
372
373 if self.group.order == zv || self.group.cofactor == zv {
374 panic!("group order 0x{:x} or group cofactor 0x{:x}", self.group.order, self.group.cofactor);
375 }
376
377 cardinal = &self.group.order * &self.group.cofactor;
378
379 k = bn.clone();
387 lamda = &k + &cardinal;
388 ecsimple_log_trace!("scalar 0x{:X} k 0x{:X}",k,k);
389 ecsimple_log_trace!("lambda 0x{:X}",lamda);
390
391 k = &lamda + &cardinal;
392 let cardbits = get_max_bits(&cardinal);
395 let mut i :i32;
396 let mut pbit :i32 = 1;
397 let mut kbit :i32;
398 kbit = get_bit_set(&lamda,cardbits as i32);
399 if kbit != 0 {
400 k = lamda;
402 }
403 s.x = BnGf2m::zero();
406 s.y = BnGf2m::zero();
407 s.z = BnGf2m::zero();
408
409 r.x = BnGf2m::zero();
410 r.y = BnGf2m::zero();
411 r.z = BnGf2m::zero();
412
413 ecsimple_log_trace!("p.X 0x{:X} p.Y 0x{:X} p.Z 0x{:X}",p.x,p.y,p.z);
420
421 self.ladder_pre(&mut r,&mut s, &p, (get_max_bits(&self.group.p) - 1 ) as u64);
422
423 i = (cardbits - 1) as i32;
424 while i >= 0 {
425 kbit = get_bit_set(&k,i) ^ pbit;
426 ecsimple_log_trace!("s.X 0x{:X} s.Y 0x{:X} s.Z 0x{:X}",s.x,s.y,s.z);
427 ecsimple_log_trace!("r.X 0x{:X} r.Y 0x{:X} r.Z 0x{:X}",r.x,r.y,r.z);
428 ecsimple_log_trace!("[{}]kbit 0x{:x} pbit 0x{:x} [0x{:x}] bitset [0x{:x}]", i,kbit,pbit,i, get_bit_set(&k,i));
429
430 if kbit != 0 {
431 tmp = s.clone();
432 s = r.clone();
433 r = tmp.clone();
434 }
435
436 ecsimple_log_trace!("s.X 0x{:X} s.Y 0x{:X} s.Z 0x{:X}",s.x,s.y,s.z);
437 ecsimple_log_trace!("r.X 0x{:X} r.Y 0x{:X} r.Z 0x{:X}",r.x,r.y,r.z);
438
439 self.ladder_step(&mut r,&mut s,&p);
440
441 ecsimple_log_trace!("s.X 0x{:X} s.Y 0x{:X} s.Z 0x{:X}",s.x,s.y,s.z);
442 ecsimple_log_trace!("r.X 0x{:X} r.Y 0x{:X} r.Z 0x{:X}",r.x,r.y,r.z);
443 ecsimple_log_trace!("p.X 0x{:X} p.Y 0x{:X} p.Z 0x{:X}",p.x,p.y,p.z);
444
445 pbit ^= kbit;
446 i -= 1;
447 }
448
449 ecsimple_log_trace!("s.X 0x{:X} s.Y 0x{:X} s.Z 0x{:X}",s.x,s.y,s.z);
450 ecsimple_log_trace!("r.X 0x{:X} r.Y 0x{:X} r.Z 0x{:X}",r.x,r.y,r.z);
451
452 if pbit != 0 {
453 tmp = s.clone();
454 s = r.clone();
455 r = tmp.clone();
456 }
457
458
459 ecsimple_log_trace!("s.X 0x{:X} s.Y 0x{:X} s.Z 0x{:X}",s.x,s.y,s.z);
460 ecsimple_log_trace!("r.X 0x{:X} r.Y 0x{:X} r.Z 0x{:X}",r.x,r.y,r.z);
461
462 self.ladder_post(&mut r,&mut s,&p);
463 ecsimple_log_trace!("r.X 0x{:X} r.Y 0x{:X} r.Z 0x{:X}",r.x,r.y,r.z);
465 return r;
468 }
469
470 pub fn get_affine_points(&self) -> Result<(BnGf2m,BnGf2m),Box<dyn Error>> {
471 if self.infinity {
472 ecsimple_new_error!{BnGf2mPointError,"is infinity"}
473 }
474 if ! self.z.is_one() {
475 ecsimple_new_error!{BnGf2mPointError,"z 0x{:X}",self.z}
476 }
477
478
479 Ok((self.x.clone(),self.y.clone()))
480 }
481
482 pub fn check_on_curve(&self) -> Result<(),Box<dyn Error>> {
483 let mut lh :BnGf2m;
484 let y2 :BnGf2m;
485 if self.infinity {
486 return Ok(());
487 }
488 if !self.z.is_one() {
489 ecsimple_new_error!{BnGf2mPointError,"z 0x{:X} not one",self.z}
490 }
491 lh = self.x.add_op(&self.group.a);
492 lh = self.field_mul(&lh,&self.x);
493 lh = lh.add_op(&self.y);
494 lh =self.field_mul(&lh,&self.x);
495 lh = lh.add_op(&self.group.b);
496 y2 = self.field_sqr(&self.y);
497 lh = lh.add_op(&y2);
498 if !lh.is_zero() {
499 ecsimple_new_error!{BnGf2mPointError,"x 0x{:X} y 0x{:X} not on group {}",self.x,self.y,self.group.curvename}
500 }
501 Ok(())
502 }
503
504
505}
506
507
508ecsimple_error_class!{ECPrimePointError}
509
510#[derive(Clone)]
511pub (crate) struct ECPrimePoint {
512 x :BigInt,
513 y :BigInt,
514 z :BigInt,
515 pub (crate) group :ECGroupPrime,
516 montv : MontNum,
517 infinity : bool,
518 z_is_one : bool,
519}
520
521impl std::fmt::Display for ECPrimePoint {
522 fn fmt(&self, f:&mut std::fmt::Formatter<'_>) -> std::fmt::Result {
523 write!(f,"curve[{}] isinfinity {} x 0x{:x} y 0x{:x} z 0x{:x}", self.group,self.infinity,self.x,self.y,self.z)
524 }
525}
526
527impl PartialEq for ECPrimePoint {
528 fn eq(&self, other:&Self) -> bool {
529 return self.eq_op(other);
530 }
531
532 fn ne(&self, other:&Self) -> bool {
533 return ! self.eq_op(other);
534 }
535}
536
537
538impl std::default::Default for ECPrimePoint {
539 fn default() -> Self {
540 let ov :BigInt = one();
541 let tv :BigInt = ov.clone() + ov.clone() + ov.clone();
542 ECPrimePoint {
543 x : zero(),
544 y : zero(),
545 z : zero(),
546 group : ECGroupPrime::default(),
547 montv : MontNum::new(&tv).unwrap(),
548 infinity : true,
549 z_is_one : true,
550 }
551 }
552}
553
554impl ECPrimePoint {
555 pub (crate) fn new(grp :&ECGroupPrime) -> ECPrimePoint {
556 let pnt :ECPrimePoint = ECPrimePoint {
557 x : grp.generator.x.clone(),
558 y : grp.generator.y.clone(),
559 z : grp.generator.z.clone(),
560 group : grp.clone(),
561 montv : MontNum::new(&grp.p).unwrap(),
562 infinity : false,
563 z_is_one : true,
564 };
565 return pnt;
566 }
567
568 pub (crate) fn new_point(x :&BigInt, y :&BigInt,z :&BigInt, grp :&ECGroupPrime) -> Self {
569 let pnt : ECPrimePoint = Self {
570 x :x.clone(),
571 y :y.clone(),
572 z :z.clone(),
573 group :grp.clone(),
574 montv : MontNum::new(&grp.p).unwrap(),
575 infinity : false,
576 z_is_one : true,
577 };
578 return pnt;
579 }
580
581
582 pub fn set_x(&mut self, x :&BigInt) {
583 self.x = x.clone();
584 }
585
586 pub fn set_y(&mut self, y :&BigInt) {
587 self.y = y.clone();
588 }
589
590 pub fn set_z(&mut self, z :&BigInt) {
591 self.z = z.clone();
592 }
593
594
595 pub fn x(&self) -> BigInt {
596 return self.x.clone();
597 }
598
599 pub fn y(&self) -> BigInt {
600 return self.y.clone();
601 }
602
603 #[allow(dead_code)]
604 pub fn z(&self) -> BigInt {
605 return self.z.clone();
606 }
607
608
609 pub fn field_sqr(&self,a :&BigInt) -> BigInt {
610 let retv :BigInt = self.montv.mont_mul(a,a);
611 ecsimple_log_trace!("r 0x{:X} = a 0x{:X} ^ 2 % group.field 0x{:X}",retv,a,self.group.p);
612 return retv;
613 }
614
615 pub fn field_mul(&self,a :&BigInt,b :&BigInt) -> BigInt {
616 let retv :BigInt = self.montv.mont_mul(a,b);
617 ecsimple_log_trace!("r 0x{:X} = a 0x{:X} * b 0x{:X} % m 0x{:X}",retv,a,b,self.group.p);
618 return retv;
619 }
620
621 pub fn sub_mod_quick(&self,a :&BigInt,b :&BigInt,m :&BigInt) -> BigInt {
622 let mut r :BigInt;
623 let zv :BigInt = zero();
624 r = a - b;
625 if r < zv {
626 r += m;
627 }
628 return r;
629 }
630
631 pub (crate) fn lshift_mod_quick(&self,a :&BigInt,sn :i64, m :&BigInt) -> BigInt {
632 let r :BigInt;
633 r = a << sn;
634 return r % m;
635 }
636
637 pub (crate) fn lshift1_mod_quick(&self,a :&BigInt,m :&BigInt) -> BigInt {
638 let r :BigInt;
639 r = a << 1;
640 return r % m;
641 }
642
643 pub (crate) fn add_mod_quick(&self,a :&BigInt,b :&BigInt, m :&BigInt) -> BigInt {
644 let retv :BigInt;
645 retv = a + b;
646 return retv % m;
647 }
648
649 fn field_encode(&self,a :&BigInt) -> BigInt {
650 let retv :BigInt;
651 retv = self.montv.mont_to(a);
652 ecsimple_log_trace!("r 0x{:X} = BN_to_montgomery(a 0x{:X},field 0x{:X});",retv,a,self.group.p);
653 return retv;
654 }
655
656
657 #[allow(unused_variables)]
658 fn ladder_pre(&self, r :&mut ECPrimePoint, s :&mut ECPrimePoint, p :&ECPrimePoint, bits :u64) {
659 let mut rndv :BigInt;
660 let zv :BigInt = zero();
661 ecsimple_log_trace!("ladder_pre");
662 s.x = self.field_sqr(&p.x);
670 r.x = self.sub_mod_quick(&s.x,&self.group.a,&self.group.p);
671 ecsimple_log_trace!("r.x 0x{:X} = sub_mod_quick(s.x 0x{:X},group.a 0x{:X},group.field 0x{:X})",r.x,s.x,self.group.a,self.group.p);
672 r.x = self.field_sqr(&r.x);
673 s.y = self.field_mul(&p.x,&self.group.b);
674 s.y = self.lshift_mod_quick(&s.y,3,&self.group.p);
675 ecsimple_log_trace!("s.y 0x{:X} = s.y << 3 % 0x{:X}",s.y,self.group.p);
676 r.x = self.sub_mod_quick(&r.x,&s.y,&self.group.p);
677 ecsimple_log_trace!("r.X 0x{:X} = sub_mod_quick(r.x 0x{:X},s.y 0x{:X},group.field 0x{:X})",r.x,r.x,s.y,self.group.p);
678 s.z = self.add_mod_quick(&s.x,&self.group.a,&self.group.p);
679 ecsimple_log_trace!("s.z 0x{:X} = add_mod_quick(s.x 0x{:X},group.a 0x{:X},group.field 0x{:X})",s.z,s.x,self.group.a,self.group.p);
680
681 r.z = self.field_mul(&p.x,&s.z);
682 r.z = self.add_mod_quick(&self.group.b,&r.z,&self.group.p);
683 ecsimple_log_trace!("r.z 0x{:X} = add_mod_quick(group.b 0x{:X},r.z,group.field 0x{:X})",r.z,self.group.b,self.group.p);
684 r.z = self.lshift_mod_quick(&r.z,2,&self.group.p);
685 ecsimple_log_trace!("r.z 0x{:X} = lshift_mod_quick(r.z,2,group.field 0x{:X})", r.z,self.group.p);
686 ecsimple_log_trace!("before rnd points");
687 loop {
688 rndv = ecsimple_private_rand_range(&self.group.p);
689 if rndv != zv {
690 r.y = rndv.clone();
691 break;
692 }
693 }
694
695 loop {
696 rndv = ecsimple_private_rand_range(&self.group.p);
697 if rndv != zv {
698 s.z = rndv.clone();
699 break;
700 }
701 }
702 ecsimple_log_trace!("after rnd points");
703
704 r.y = self.field_encode(&r.y);
705 s.z = self.field_encode(&s.z);
706
707 r.z = self.field_mul(&r.z,&r.y);
708 r.x = self.field_mul(&r.x,&r.y);
709
710 s.x = self.field_mul(&p.x,&s.z);
711
712
713
714 return;
715 }
716
717 fn ladder_step(&self, r :&mut ECPrimePoint, s :&mut ECPrimePoint, p :&ECPrimePoint) {
718 let mut t0 :BigInt;
719 let mut t1 :BigInt;
720 let t2 :BigInt;
721 let mut t3 :BigInt;
722 let mut t4 :BigInt;
723 let mut t5 :BigInt;
724 let mut t6 :BigInt;
725
726 t6 = self.field_mul(&r.x,&s.x);
727 t0 = self.field_mul(&r.z,&s.z);
728 t4 = self.field_mul(&r.x,&s.z);
729 t3 = self.field_mul(&r.z,&s.x);
730 t5 = self.field_mul(&self.group.a,&t0);
731 t5 = self.add_mod_quick(&t6,&t5,&self.group.p);
732 ecsimple_log_trace!("add_mod_quick(t5 0x{:X},t6 0x{:X},t5,group.field 0x{:X})",t5,t6,self.group.p);
733 t6 = self.add_mod_quick(&t3,&t4,&self.group.p);
734 ecsimple_log_trace!("add_mod_quick(t6 0x{:X},t3 0x{:X},t4 0x{:X},group.field 0x{:X})",t6,t3,t4,self.group.p);
735 t5 = self.field_mul(&t6,&t5);
736 t0 = self.field_sqr(&t0);
737 t2 = self.lshift_mod_quick(&self.group.b,2,&self.group.p);
738 ecsimple_log_trace!("mod_lshift_quick(t2 0x{:X},group.b 0x{:X},2,group.field 0x{:X})",t2,self.group.b,self.group.p);
739 t0 = self.field_mul(&t2,&t0);
740 t5 = self.lshift1_mod_quick(&t5 , &self.group.p);
741 ecsimple_log_trace!("lshift1_mod_quick(t5 0x{:X},t5,group.field 0x{:X})",t5,self.group.p);
742 t3 = self.sub_mod_quick(&t4,&t3,&self.group.p);
743 ecsimple_log_trace!("sub_mod_quick(t3 0x{:X},t4 0x{:X},t3,group.field 0x{:X})",t3,t4,self.group.p);
744 s.z = self.field_sqr(&t3);
745 t4 = self.field_mul(&s.z,&p.x);
746 t0 = self.add_mod_quick(&t0,&t5,&self.group.p);
747 ecsimple_log_trace!("add_mod_quick(t0 0x{:X},t0,t5 0x{:X},group.field 0x{:X})",t0,t5,self.group.p);
748 s.x = self.sub_mod_quick(&t0,&t4,&self.group.p);
749 ecsimple_log_trace!("sub_mod_quick(s.x 0x{:X},t0 0x{:X},t4 0x{:X},group.field 0x{:X})",s.x,t0,t4,self.group.p);
750 t4 = self.field_sqr(&r.x);
751 t5 = self.field_sqr(&r.z);
752 t6 = self.field_mul(&t5,&self.group.a);
753 ecsimple_log_trace!("new t6 0x{:X}",t6);
754 t1 = self.add_mod_quick(&r.x,&r.z,&self.group.p);
755 ecsimple_log_trace!("add_mod_quick(t1 0x{:X},r.x 0x{:X},r.z 0x{:X},group.field 0x{:X})",t1,r.x,r.z,self.group.p);
756 t1 = self.field_sqr(&t1);
757 t1 = self.sub_mod_quick(&t1,&t4,&self.group.p);
758 ecsimple_log_trace!("sub_mod_quick(t1 0x{:X},t1,t4 0x{:X},group.field 0x{:X})",t1,t4,self.group.p);
759 t1 = self.sub_mod_quick(&t1,&t5,&self.group.p);
760 ecsimple_log_trace!("sub_mod_quick(t1 0x{:X},t1,t5 0x{:X},group.field 0x{:X})",t1,t5,self.group.p);
761 t3 = self.sub_mod_quick(&t4,&t6,&self.group.p);
762 ecsimple_log_trace!("sub_mod_quick(t3 0x{:X},t4 0x{:X},t6 0x{:X},group.field 0x{:X})",t3,t4,t6,self.group.p);
763 t3 = self.field_sqr(&t3);
764 t0 = self.field_mul(&t5,&t1);
765 t0 = self.field_mul(&t2,&t0);
766 r.x = self.sub_mod_quick(&t3,&t0,&self.group.p);
767 ecsimple_log_trace!("sub_mod_quick(r.x 0x{:X},t3 0x{:X},t0 0x{:X},group.field 0x{:X})",r.x,t3,t0,self.group.p);
768 t3 = self.add_mod_quick(&t4,&t6,&self.group.p);
769 ecsimple_log_trace!("add_mod_quick(t3 0x{:X},t4 0x{:X},t6 0x{:X},group.field 0x{:X})",t3,t4,t6,self.group.p);
770 t4 = self.field_sqr(&t5);
771 t4 = self.field_mul(&t4,&t2);
772 t1 = self.field_mul(&t1,&t3);
773 t1 = self.lshift1_mod_quick(&t1,&self.group.p);
774 ecsimple_log_trace!("lshift1_mod_quick(t1 0x{:X},t1,group.field 0x{:X})",t1,self.group.p);
775 r.z = self.add_mod_quick(&t4,&t1,&self.group.p);
776 ecsimple_log_trace!("add_mod_quick(r.z 0x{:X},t4 0x{:X},t1 0x{:X},group.field 0x{:X})",r.z,t4,t1,self.group.p);
777 return;
778 }
779
780 pub (crate) fn field_decode(&self,a :&BigInt) -> BigInt {
781 let retv :BigInt = self.montv.mont_from(a);
782 return retv;
783 }
784
785 fn field_inv(&self,a :&BigInt) -> BigInt {
786 let ov :BigInt = one();
787
788 let e :BigInt = &self.group.p - &ov - &ov;
789 let retv:BigInt = self.montv.mont_pow(a,&e);
790 ecsimple_log_trace!("field_inv(r 0x{:X},a 0x{:X},e 0x{:X},group.field 0x{:X})",retv,a,e,self.group.p);
791 return retv;
792 }
793
794 fn field_set_to_one(&self) -> BigInt {
795 let retv :BigInt = self.group.generator.z.clone();
796 ecsimple_log_trace!("set_to_one(r 0x{:X})",retv);
797 return retv;
798 }
799
800 fn ladder_post(&self, r :&mut ECPrimePoint, s :&mut ECPrimePoint, p :&ECPrimePoint) {
801 let mut t0 :BigInt;
802 let mut t1 :BigInt;
803 let t2 :BigInt;
804 let t3 :BigInt;
805 let t4 :BigInt;
806 let t5 :BigInt;
807 let mut t6 :BigInt;
808
809 t4 = self.lshift1_mod_quick(&p.y,&self.group.p);
810 ecsimple_log_trace!("lshift1_mod_quick(t4 0x{:X},p.y 0x{:X},group.field 0x{:X})",t4,p.y,self.group.p);
811 t6 = self.field_mul(&r.x,&t4);
812 t6 = self.field_mul(&s.z,&t6);
813 t5 = self.field_mul(&r.z,&t6);
814
815 t1 = self.lshift1_mod_quick(&self.group.b,&self.group.p);
816 ecsimple_log_trace!("lshift1_mod_quick(t1 0x{:X},group.b 0x{:X},group.field 0x{:X})",t1,self.group.b,self.group.p);
817 t1 = self.field_mul(&s.z,&t1);
818 t3 = self.field_sqr(&r.z);
819 t2 = self.field_mul(&t3,&t1);
820 t6 = self.field_mul(&r.z,&self.group.a);
821 t1 = self.field_mul(&p.x,&r.x);
822 t1 = self.add_mod_quick(&t1,&t6,&self.group.p);
823 ecsimple_log_trace!("add_mod_quick(t1 0x{:X},t1,t6 0x{:X},group.field 0x{:X})",t1,t6,self.group.p);
824 t1 = self.field_mul(&s.z,&t1);
825 t0 = self.field_mul(&p.x,&r.z);
826 t6 = self.add_mod_quick(&r.x,&t0,&self.group.p);
827 ecsimple_log_trace!("add_mod_quick(t6 0x{:X},r.x 0x{:X},t0 0x{:X},group.field 0x{:X})",t6,r.x,t0,self.group.p);
828 t6 = self.field_mul(&t6,&t1);
829 t6 = self.add_mod_quick(&t6,&t2,&self.group.p);
830 ecsimple_log_trace!("add_mod_quick(t6 0x{:X},t6,t2 0x{:X},group.field 0x{:X})",t6,t2,self.group.p);
831 t0 = self.sub_mod_quick(&t0,&r.x,&self.group.p);
832 ecsimple_log_trace!("sub_mod_quick(t0 0x{:X},t0,r.x 0x{:X},group.field 0x{:X})",t0,r.x,self.group.p);
833 t0 = self.field_sqr(&t0);
834 t0 = self.field_mul(&t0,&s.x);
835 t0 = self.sub_mod_quick(&t6,&t0,&self.group.p);
836 ecsimple_log_trace!("sub_mod_quick(t0 0x{:X},t6 0x{:X},t0,group.field 0x{:X})",t0,t6,self.group.p);
837 t1 = self.field_mul(&s.z,&t4);
838 t1 = self.field_mul(&t3,&t1);
839 t1 = self.field_decode(&t1);
840 t1 = self.field_inv(&t1);
841 t1 = self.field_encode(&t1);
842 r.x = self.field_mul(&t5,&t1);
843 r.y = self.field_mul(&t0,&t1);
844 r.z = self.field_set_to_one();
845
846 return;
847 }
848
849 pub fn get_affine_coordinates(&self,r :&ECPrimePoint) -> ECPrimePoint {
850 ecsimple_log_trace!("point.X 0x{:X} point.Y 0x{:X} point.Z 0x{:X}",r.x,r.y,r.z);
851 let mut retv :ECPrimePoint = r.clone();
852 retv.z = self.montv.mont_from(&r.z);
853 retv.x = self.montv.mont_from(&r.x);
854 retv.y = self.montv.mont_from(&r.y);
855 ecsimple_log_trace!("x 0x{:X} y 0x{:X} z 0x{:X}",retv.x,retv.y,retv.z);
856 return retv;
857 }
858
859 pub fn set_affine_coordinates(&self,x :&BigInt,y :&BigInt,z :&BigInt) -> Result<ECPrimePoint,Box<dyn Error>> {
860 let mut retv :ECPrimePoint = ECPrimePoint::new(&self.group);
861 ecsimple_log_trace!("field 0x{:X}",self.group.p);
862 ecsimple_log_trace!("x 0x{:X} y 0x{:X} z 0x{:X}",x,y,z);
863 retv.x = nmod(x,&self.group.p);
864 ecsimple_log_trace!("point->X 0x{:X} = x 0x{:X} % group->field 0x{:X}", retv.x,x,self.group.p);
865 retv.x = self.field_encode(&retv.x);
866 ecsimple_log_trace!("field_encode point->X 0x{:X}",retv.x);
867
868 retv.y = nmod(y,&self.group.p);
869 ecsimple_log_trace!("point->Y 0x{:X} = y 0x{:X} % group->field 0x{:X}", retv.y,y,self.group.p);
870 retv.y = self.field_encode(&retv.y);
871 ecsimple_log_trace!("field_encode point->Y 0x{:X}",retv.y);
872
873 retv.z = nmod(z,&self.group.p);
874 ecsimple_log_trace!("point->Z 0x{:X} = z 0x{:X} % group->field 0x{:X}",retv.z,z,self.group.p);
875 retv.z = self.field_set_to_one();
876 ecsimple_log_trace!("field_set_to_one point->Z 0x{:X}",retv.z);
877
878 Ok(retv)
879 }
880
881
882
883
884
885 #[allow(unused_assignments)]
886 #[allow(unused_variables)]
887 pub fn mul_op(&self, bn :&BigInt,copyxy :bool ) -> ECPrimePoint {
888 let zv :BigInt = zero();
889 let p :ECPrimePoint ;
890 let mut s :ECPrimePoint = ECPrimePoint::new(&self.group);
891 let mut r :ECPrimePoint = ECPrimePoint::new(&self.group);
892 let mut tmp :ECPrimePoint;
893 let cardinal :BigInt;
894 let mut lamda :BigInt = zero();
895 let mut k :BigInt = zero();
896 if bn <= &zv {
897 r = self.clone();
898 r.infinity = true;
899 return r;
900 }
901
902 if self.infinity {
903 return self.clone();
904 }
905
906 if copyxy {
907 p = self.clone();
908 } else {
909 p = ECPrimePoint::new(&self.group);
910 }
911 ecsimple_log_trace!("p.x 0x{:X} p.y 0x{:X} p.z 0x{:X}",p.x,p.y,p.z);
912
913
914 if self.group.order == zv || self.group.cofactor == zv {
915 panic!("group order 0x{:x} or group cofactor 0x{:x}", self.group.order, self.group.cofactor);
916 }
917
918 cardinal = &self.group.order * &self.group.cofactor;
919
920 ecsimple_log_trace!("k 0x{:X} lambda 0x{:X}", k, lamda);
925 k = bn.clone();
928 lamda = &k + &cardinal;
929 ecsimple_log_trace!("scalar 0x{:X} k 0x{:X}",k,k);
930 ecsimple_log_trace!("lambda 0x{:X}",lamda);
931
932 let mut kbit :i32;
933 k = &lamda + &cardinal;
934 ecsimple_log_trace!("k 0x{:X} cardinality 0x{:X}",k,cardinal);
935
936 let cardbits = get_max_bits(&cardinal);
937 kbit = get_bit_set(&lamda,cardbits as i32);
938 if kbit != 0 {
939 (lamda,k) = (k,lamda);
940 }
941
942 let mut i :i32;
943 let mut pbit :i32 = 1;
944 ecsimple_log_trace!("k 0x{:X} lambda 0x{:X} cardinality_bits 0x{:x}",k,lamda,cardbits);
945
946 s.x = zero();
947 s.y = zero();
948 s.z = zero();
949
950 r.x = zero();
951 r.y = zero();
952 r.z = zero();
953
954 ecsimple_log_trace!("p.X 0x{:X} p.Y 0x{:X} p.Z 0x{:X}",p.x,p.y,p.z);
961
962
963 ecsimple_log_trace!("p.X 0x{:X} p.Y 0x{:X} p.Z 0x{:X}",p.x,p.y,p.z);
964 self.ladder_pre(&mut r,&mut s, &p, (get_max_bits(&self.group.p) - 1 ) as u64);
965
966 i = (cardbits - 1) as i32;
967 while i >= 0 {
968 kbit = get_bit_set(&k,i) ^ pbit;
969 ecsimple_log_trace!("s.X 0x{:X} s.Y 0x{:X} s.Z 0x{:X}",s.x,s.y,s.z);
970 ecsimple_log_trace!("r.X 0x{:X} r.Y 0x{:X} r.Z 0x{:X}",r.x,r.y,r.z);
971 ecsimple_log_trace!("[{}]kbit 0x{:x} pbit 0x{:x} [0x{:x}] bitset [0x{:x}]", i,kbit,pbit,i, get_bit_set(&k,i));
972
973 if kbit != 0 {
974 tmp = s.clone();
975 s = r.clone();
976 r = tmp.clone();
977 }
978
979 ecsimple_log_trace!("s.X 0x{:X} s.Y 0x{:X} s.Z 0x{:X}",s.x,s.y,s.z);
980 ecsimple_log_trace!("r.X 0x{:X} r.Y 0x{:X} r.Z 0x{:X}",r.x,r.y,r.z);
981
982 self.ladder_step(&mut r,&mut s,&p);
983
984 ecsimple_log_trace!("s.X 0x{:X} s.Y 0x{:X} s.Z 0x{:X}",s.x,s.y,s.z);
985 ecsimple_log_trace!("r.X 0x{:X} r.Y 0x{:X} r.Z 0x{:X}",r.x,r.y,r.z);
986 ecsimple_log_trace!("p.X 0x{:X} p.Y 0x{:X} p.Z 0x{:X}",p.x,p.y,p.z);
987
988 pbit ^= kbit;
989 i -= 1;
990 }
991
992 ecsimple_log_trace!("s.X 0x{:X} s.Y 0x{:X} s.Z 0x{:X}",s.x,s.y,s.z);
993 ecsimple_log_trace!("r.X 0x{:X} r.Y 0x{:X} r.Z 0x{:X}",r.x,r.y,r.z);
994
995 if pbit != 0 {
996 tmp = s.clone();
997 s = r.clone();
998 r = tmp.clone();
999 }
1000
1001
1002 ecsimple_log_trace!("s.X 0x{:X} s.Y 0x{:X} s.Z 0x{:X}",s.x,s.y,s.z);
1003 ecsimple_log_trace!("r.X 0x{:X} r.Y 0x{:X} r.Z 0x{:X}",r.x,r.y,r.z);
1004
1005 self.ladder_post(&mut r,&mut s,&p);
1006 ecsimple_log_trace!("r.X 0x{:X} r.Y 0x{:X} r.Z 0x{:X}",r.x,r.y,r.z);
1008 r = self.get_affine_coordinates(&r);
1011
1012 return r;
1013 }
1014
1015 pub fn check_on_curve(&self) -> Result<(),Box<dyn Error>> {
1016 let mut rh :BigInt;
1017 let ov :BigInt = one();
1018 let z4 :BigInt;
1019 let z6 :BigInt;
1020 let mut tmp :BigInt;
1021 let field :BigInt = self.group.p.clone();
1022
1023 rh = self.field_sqr(&self.x);
1024 if self.z != ov {
1025 tmp = self.field_sqr(&self.z);
1026 z4 = self.field_sqr(&tmp);
1027 z6 = self.field_mul(&z4,&tmp);
1028
1029 if self.group.is_minus3 {
1030 tmp = self.lshift1_mod_quick(&z4,&field);
1031 ecsimple_log_trace!("lshift1_mod_quick(tmp 0x{:X},Z4 0x{:X},p 0x{:X})",tmp,z4,field);
1032 tmp = self.add_mod_quick(&tmp,&z4,&field);
1033 ecsimple_log_trace!("add_mod_quick(tmp 0x{:X},tmp,Z4 0x{:X},p 0x{:X})",tmp,z4,field);
1034 rh = self.sub_mod_quick(&rh,&tmp,&field);
1035 ecsimple_log_trace!("sub_mod_quick(rh 0x{:X},rh,tmp 0x{:X},p 0x{:X})",rh,tmp,field);
1036 rh = self.field_mul(&rh,&self.x);
1037 } else {
1038 tmp = self.field_mul(&z4,&self.group.a);
1039 rh = self.add_mod_quick(&rh,&tmp,&field);
1040 ecsimple_log_trace!("add_mod_quick(rh 0x{:X},rh,tmp 0x{:X},p 0x{:X})",rh,tmp,field);
1041 rh = self.field_mul(&rh,&self.x);
1042 }
1043 tmp = self.field_mul(&self.group.b,&z6);
1044 rh = self.add_mod_quick(&rh,&tmp,&field);
1045 ecsimple_log_trace!("add_mod_quick(rh 0x{:X},rh,tmp 0x{:X},p 0x{:X})",rh,tmp,field);
1046 } else {
1047 rh = self.add_mod_quick(&rh,&self.group.a,&field);
1048 ecsimple_log_trace!("add_mod_quick(rh 0x{:X},rh,group.a 0x{:X},p 0x{:X})",rh, self.group.a,field);
1049 rh = self.field_mul(&rh,&self.x);
1050 rh = self.add_mod_quick(&rh,&self.group.b,&field);
1051 ecsimple_log_trace!("add_mod_quick(rh 0x{:X},rh,group.b 0x{:X},p 0x{:X})",rh,self.group.b,field);
1052 }
1053
1054 tmp = self.field_sqr(&self.y);
1055 if tmp != rh {
1056 ecsimple_new_error!{ECPrimePointError,"tmp 0x{:X} != rh 0x{:X}",tmp,rh}
1057 }
1058 Ok(())
1059 }
1060
1061 fn get_wnaf_variable(&self,bn :&BigInt) -> Result<(Vec<u8>,i32),Box<dyn Error>> {
1062 let wnaf_bit :i32 = get_wnaf_bits(bn);
1063 let curnaf :Vec<u8> = wnaf_value(bn,wnaf_bit)?;
1064 Ok((curnaf,wnaf_bit))
1065 }
1066
1067 fn dbl(&self) -> Result<ECPrimePoint,Box<dyn Error>> {
1068 let mut retv :ECPrimePoint = ECPrimePoint::new(&self.group);
1069 let zv :BigInt = zero();
1070 let field :BigInt = self.group.p.clone();
1071 let mut n0 :BigInt;
1072 let mut n1 :BigInt;
1073 let mut n2 :BigInt;
1074 let mut n3 :BigInt;
1075
1076 if self.infinity {
1077 retv.z = zv.clone();
1078 retv.z_is_one = false;
1079 return Ok(retv);
1080 }
1081
1082 if self.z_is_one {
1083 n0 = self.field_sqr(&self.x);
1084 n1 = self.lshift1_mod_quick(&n0,&field);
1085 ecsimple_log_trace!("mod_lshift_quick(n1 0x{:X},n0 0x{:X},p 0x{:X})",n1,n0,field);
1086 n0 = self.add_mod_quick(&n0,&n1,&field);
1087 ecsimple_log_trace!("mod_add_quick(n0 0x{:X},n0,n1 0x{:X},p 0x{:X})",n0,n1,field);
1088 n1 = self.add_mod_quick(&n0,&self.group.a,&field);
1089 ecsimple_log_trace!("mod_add_quick(n1 0x{:X},n0 0x{:X},group.a 0x{:X},p 0x{:X})",n1,n0,self.group.a,field);
1090 } else if self.group.is_minus3 {
1092 n1 = self.field_sqr(&self.z);
1093 n0 = self.add_mod_quick(&self.x,&n1,&field);
1094 ecsimple_log_trace!("mod_add_quick(n0 0x{:X},a.x 0x{:X},n1 0x{:X},p 0x{:X})",n0,self.x,n1,field);
1095 n2 = self.sub_mod_quick(&self.x,&n1,&field);
1096 ecsimple_log_trace!("mod_sub_quick(n2 0x{:X},a.x 0x{:X},n1 0x{:X},p 0x{:X})",n2,self.x,n1,field);
1097 n1 = self.field_mul(&n0,&n2);
1098 n0 = self.lshift1_mod_quick(&n1,&field);
1099 ecsimple_log_trace!("mod_lshift_quick(n0 0x{:X},n1 0x{:X},p 0x{:X})",n0, n1,field);
1100 n1 = self.add_mod_quick(&n0,&n1,&field);
1101 ecsimple_log_trace!("mod_add_quick(n1 0x{:X},n0 0x{:X},n1,p 0x{:X})",n1,n0,field);
1102 } else {
1107 n0 = self.field_sqr(&self.x);
1108 n1 = self.lshift1_mod_quick(&n0,&field);
1109 ecsimple_log_trace!("mod_lshift_quick(n1 0x{:X},n0 0x{:X},p 0x{:X})",n1,n0,field);
1110 n0 = self.add_mod_quick(&n0,&n1,&field);
1111 ecsimple_log_trace!("mod_add_quick(n0 0x{:X},n0,n1 0x{:X},p 0x{:X})",n0,n1,field);
1112 n1 = self.field_sqr(&self.z);
1113 n1 = self.field_sqr(&n1);
1114 n1 = self.field_mul(&n1,&self.group.a);
1115 n1 = self.add_mod_quick(&n1,&n0,&field);
1116 ecsimple_log_trace!("mod_add_quick(n1 0x{:X},n1,n0 0x{:X},p 0x{:X})",n1,n0,field);
1117 }
1119
1120 if self.z_is_one {
1121 n0 = self.y.clone();
1122 ecsimple_log_trace!("BN_copy(n0 0x{:X},a.y 0x{:X})",n0,self.y);
1123 } else {
1124 n0 = self.field_mul(&self.y,&self.z);
1125 }
1126 retv.z = self.lshift1_mod_quick(&n0,&field);
1127 ecsimple_log_trace!("mod_lshift_quick(r.z 0x{:X},n0 0x{:X},p 0x{:X})",retv.z,n0,field);
1128 retv.z_is_one = false;
1129 n3 = self.field_sqr(&self.y);
1132 n2 = self.field_mul(&self.x,&n3);
1133 n2 = self.lshift_mod_quick(&n2,2,&field);
1134 ecsimple_log_trace!("mod_lshift_quick(n2 0x{:X},n2,0x2,p 0x{:X})",n2,field);
1135 n0 = self.lshift1_mod_quick(&n2,&field);
1138 ecsimple_log_trace!("mod_lshift_quick(n0 0x{:X},n2 0x{:X},p 0x{:X})",n0,n2,field);
1139 retv.x = self.field_sqr(&n1);
1140 retv.x = self.sub_mod_quick(&retv.x,&n0,&field);
1141 ecsimple_log_trace!("mod_sub_quick(r.x 0x{:X},r.x,n0 0x{:X},p 0x{:X})",retv.x,n0,field);
1142 n0 = self.field_sqr(&n3);
1146 n3 = self.lshift_mod_quick(&n0,0x3,&field);
1147 ecsimple_log_trace!("mod_lshift_quick(n3 0x{:X},n0 0x{:X},0x3,p 0x{:X})",n3,n0,field);
1148 n0 = self.sub_mod_quick(&n2,&retv.x,&field);
1151 ecsimple_log_trace!("mod_sub_quick(n0 0x{:X},n2 0x{:X},r.x 0x{:X},p 0x{:X})",n0,n2,retv.x,field);
1152 n0 = self.field_mul(&n1,&n0);
1153 retv.y = self.sub_mod_quick(&n0,&n3,&field);
1154 ecsimple_log_trace!("mod_sub_quick(r.y 0x{:X},n0 0x{:X},n3 0x{:X},p 0x{:X})",retv.y,n0,n3,field);
1155 Ok(retv)
1158 }
1159
1160 fn add(&self,b :&ECPrimePoint) -> Result<ECPrimePoint,Box<dyn Error>> {
1161 let mut retv :ECPrimePoint = ECPrimePoint::new(&self.group);
1162 let mut n0 :BigInt;
1163 let mut n1 :BigInt;
1164 let mut n2 :BigInt;
1165 let mut n3 :BigInt;
1166 let mut n4 :BigInt;
1167 let mut n5 :BigInt;
1168 let n6 :BigInt;
1169 let field :BigInt = self.group.p.clone();
1170 let zv :BigInt = zero();
1171 let ov :BigInt = one();
1172 let tv :BigInt = ov.clone() + ov.clone();
1173 if self.group != b.group {
1174 ecsimple_new_error!{ECPrimePointError,"not valid group point"}
1175 }
1176 if self == b {
1177 return self.dbl();
1178 } else if self.infinity {
1179 retv = b.clone();
1180 return Ok(retv);
1181 } else if b.infinity {
1182 retv= self.clone();
1183 return Ok(retv);
1184 }
1185
1186 if b.z_is_one {
1187 n1 = self.x.clone();
1188 ecsimple_log_trace!("BN_copy(n1 0x{:X},a.x 0x{:X})",n1,self.x);
1189 n2 = self.y.clone();
1190 ecsimple_log_trace!("BN_copy(n2 0x{:X},a.y 0x{:X})",n2,self.y);
1191 } else {
1194 n0 = self.field_sqr(&b.z);
1195 n1 = self.field_mul(&self.x,&n0);
1196 n0 = self.field_mul(&n0,&b.z);
1199 n2 = self.field_mul(&self.y,&n0);
1200 }
1202
1203 if self.z_is_one {
1204 n3 = b.x.clone();
1205 ecsimple_log_trace!("BN_copy(n3 0x{:X},b.x 0x{:X})",n3,b.x);
1206 n4 = b.y.clone();
1207 ecsimple_log_trace!("BN_copy(n4 0x{:X},b.y 0x{:X})",n4,b.y);
1208 } else {
1211 n0 = self.field_sqr(&self.z);
1212 n3 = self.field_mul(&b.x,&n0);
1213 n0 = self.field_mul(&n0,&self.z);
1216 n4 = self.field_mul(&b.y,&n0);
1217 }
1219
1220 n5 = self.sub_mod_quick(&n1,&n3,&field);
1221 ecsimple_log_trace!("mod_sub_quick(n5 0x{:X},n1 0x{:X},n3 0x{:X},p 0x{:X})",n5,n1,n3,field);
1222 n6 = self.sub_mod_quick(&n2,&n4,&field);
1223 ecsimple_log_trace!("mod_sub_quick(n6 0x{:X},n2 0x{:X},n4 0x{:X},p 0x{:X})",n6,n2,n4,field);
1224 if n5 == zv {
1228 if n6 == zv {
1229 retv = self.dbl()?;
1230 ecsimple_log_trace!("a.x 0x{:X} a.y 0x{:X} a.z 0x{:X}",self.x,self.y,self.z);
1231 ecsimple_log_trace!("r.x 0x{:X} r.y 0x{:X} r.z 0x{:X}",retv.x,retv.y,retv.z);
1232 return Ok(retv);
1233 } else {
1234 retv.z = zv.clone();
1235 retv.z_is_one = false;
1236 ecsimple_log_trace!("r.z 0");
1237 return Ok(retv);
1238 }
1239 }
1240
1241 n1 = self.add_mod_quick(&n1,&n3,&field);
1242 ecsimple_log_trace!("mod_add_quick(n1 0x{:X},n1,n3 0x{:X},p 0x{:X})",n1,n3,field);
1243 n2 = self.add_mod_quick(&n2,&n4,&field);
1244 ecsimple_log_trace!("mod_add_quick(n2 0x{:X},n2,n4 0x{:X},p 0x{:X})",n2,n4,field);
1245 if self.z_is_one && b.z_is_one {
1249 retv.z = n5.clone();
1250 ecsimple_log_trace!("BN_copy(r.z 0x{:X},n5 0x{:X})",retv.z,n5);
1251 } else {
1252 if self.z_is_one {
1253 n0 = b.z.clone();
1254 ecsimple_log_trace!("BN_copy(n0 0x{:X},b.z 0x{:X})",n0,b.z);
1255 } else if b.z_is_one {
1256 n0 = self.z.clone();
1257 ecsimple_log_trace!("BN_copy(n0 0x{:X},a.z 0x{:X})",n0,self.z);
1258 } else {
1259 n0 = self.field_mul(&self.z,&b.z);
1260 }
1261
1262 retv.z = self.field_mul(&n0,&n5);
1263 }
1264 retv.z_is_one = false;
1265 n0 = self.field_sqr(&n6);
1268 n4 = self.field_sqr(&n5);
1269 n3 = self.field_mul(&n1,&n4);
1270 retv.x = self.sub_mod_quick(&n0,&n3,&field);
1271 ecsimple_log_trace!("mod_sub_quick(r.x 0x{:X},n0 0x{:X},n3 0x{:X},p 0x{:X})",retv.x,n0,n3,field);
1272 n0 = self.lshift1_mod_quick(&retv.x,&field);
1275 ecsimple_log_trace!("mod_lshift_quick(n0 0x{:X},r.x 0x{:X},p 0x{:X})",n0,retv.x,field);
1276 n0 = self.sub_mod_quick(&n3,&n0,&field);
1277 ecsimple_log_trace!("mod_sub_quick(n0 0x{:X},n3 0x{:X},n0,p 0x{:X})",n0,n3,field);
1278 n0 = self.field_mul(&n0,&n6);
1281 n5 = self.field_mul(&n4,&n5);
1282 n1 = self.field_mul(&n2,&n5);
1283 n0 = self.sub_mod_quick(&n0,&n1,&field);
1284 ecsimple_log_trace!("mod_sub_quick(n0 0x{:X},n0,n1 0x{:X},p 0x{:X})",n0,n1,field);
1285
1286 if (n0.clone() % tv.clone()) != zv {
1287 n0 = n0.clone() + field.clone();
1288 ecsimple_log_trace!("BN_add(n0 0x{:X},n0,p 0x{:X})",n0,field);
1289 }
1290 retv.y = n0.clone() >> 1;
1293 ecsimple_log_trace!("BN_rshift1(r.y 0x{:X},n0 0x{:X})",retv.y,n0);
1294 Ok(retv)
1297 }
1298
1299 pub fn eq_op(&self, other :&ECPrimePoint) -> bool {
1300 if self.group != other.group {
1301 return false;
1302 }
1303 if self.infinity != other.infinity {
1304 return false;
1305 }
1306
1307 if self.infinity && other.infinity {
1308 return true;
1309 }
1310
1311 if self.x != other.x {
1312 return false;
1313 }
1314
1315 if self.y != other.y {
1316 return false;
1317 }
1318
1319 if self.z != other.z {
1320 return false;
1321 }
1322
1323 return true;
1324 }
1325
1326 fn points_make_affine(&self,points :&mut [ECPrimePoint]) -> Result<(),Box<dyn Error>> {
1327 let mut tmp :BigInt;
1328 let mut tmp_z :BigInt;
1329 let mut prod_z :Vec<BigInt> = Vec::new();
1330 let zv :BigInt = zero();
1331 let mut idx :usize;
1332 if points.len() == 0 {
1333 return Ok(());
1334 }
1335 while prod_z.len() < points.len() {
1336 prod_z.push(zv.clone());
1337 }
1338
1339 if points[0].z != zv {
1340 prod_z[0] = points[0].z.clone();
1341 ecsimple_log_trace!("BN_copy(prod_Z[0] 0x{:X},points[0].z 0x{:X})",prod_z[0],points[0].z);
1342 } else {
1343 prod_z[0] = self.field_set_to_one();
1344 }
1345
1346 idx = 1;
1347 while idx < points.len() {
1348 if points[idx].z != zv {
1349 prod_z[idx] = self.field_mul(&prod_z[idx-1],&points[idx].z);
1350 } else {
1351 prod_z[idx] = prod_z[idx-1].clone();
1352 ecsimple_log_trace!("BN_copy(prod_Z[{}] 0x{:X},prod_Z[{}] 0x{:X})",idx,prod_z[idx],idx-1,prod_z[idx-1]);
1353 }
1354 idx += 1;
1355 }
1356
1357 tmp = self.field_inv(&prod_z[prod_z.len() - 1]);
1358
1359 tmp = self.field_encode(&tmp);
1360 tmp = self.field_encode(&tmp);
1361
1362 idx = points.len() - 1;
1363 while idx > 0 {
1364 if points[idx].z != zv {
1365 tmp_z = self.field_mul(&prod_z[idx-1],&tmp);
1366 tmp = self.field_mul(&tmp,&points[idx].z);
1367 points[idx].z = tmp_z.clone();
1368 }
1369 idx -= 1;
1370 }
1371
1372 if points[0].z != zv {
1373 points[0].z = tmp.clone();
1374 }
1375
1376 idx = 0;
1377 while idx < points.len() {
1378 if points[idx].z != zv {
1379 tmp = self.field_sqr(&points[idx].z);
1380 points[idx].x = self.field_mul(&points[idx].x,&tmp);
1381 tmp = self.field_mul(&tmp,&points[idx].z);
1382 points[idx].y = self.field_mul(&points[idx].y,&tmp);
1383 points[idx].z = self.field_set_to_one();
1384 points[idx].z_is_one = true;
1385 }
1386 idx += 1;
1387 }
1388 Ok(())
1389 }
1390
1391 fn invert(&self) -> Result<ECPrimePoint,Box<dyn Error>> {
1392 let mut retv :ECPrimePoint = self.clone();
1393 let zv :BigInt = zero();
1394 let field :BigInt = self.group.p.clone();
1395 if retv.z == zv || retv.y == zv {
1396 return Ok(retv);
1397 }
1398
1399 retv.y = bnusub(&field,&retv.y);
1400 ecsimple_log_trace!("BN_usub(p.y 0x{:X},group.field 0x{:X},p.y)",retv.y,field);
1401 Ok(retv)
1402 }
1403
1404 fn blind_coordinate(&self) -> Result<ECPrimePoint,Box<dyn Error>> {
1405 let mut retv :ECPrimePoint = self.clone();
1406 let zv :BigInt = zero();
1407 let mut lambda :BigInt;
1408 let mut temp :BigInt;
1409 loop {
1410 lambda = ecsimple_private_rand_range(&self.group.p);
1411 if lambda != zv {
1412 break;
1413 }
1414 }
1415
1416 lambda = self.field_encode(&lambda);
1417 ecsimple_log_trace!("field_encode");
1418 retv.z = self.field_mul(&retv.z,&lambda);
1419 ecsimple_log_trace!("field_mul");
1420 temp = self.field_sqr(&lambda);
1421 ecsimple_log_trace!("field_sqr");
1422 retv.x = self.field_mul(&retv.x,&temp);
1423 ecsimple_log_trace!("field_mul");
1424 temp = self.field_mul(&temp,&lambda);
1425 ecsimple_log_trace!("field_mul");
1426 retv.y = self.field_mul(&retv.y,&temp);
1427 ecsimple_log_trace!("field_mul");
1428 retv.z_is_one = false;
1429
1430 Ok(retv)
1431 }
1432
1433 fn point_set_infinity(&mut self) {
1434 self.z_is_one = false;
1435 self.z = zero();
1436 self.infinity = true;
1437 return;
1438 }
1439
1440 pub fn mulex_op(&self,bn1 :&BigInt,bn2 :&BigInt) -> Result<ECPrimePoint,Box<dyn Error>> {
1441 let mut retv :ECPrimePoint = self.clone();
1442
1443 let mut val_sub :Vec<Vec<ECPrimePoint>> = Vec::new();
1444 let mut wnaf_bits :Vec<i32> = Vec::new();
1445 let mut wnaf :Vec<Vec<u8>> = Vec::new();
1446 let mut curnaf :Vec<u8>;
1447 let mut bits :i32;
1448 let mut cv :Vec<ECPrimePoint>;
1449 let mut idx :usize;
1450 let mut tmp :ECPrimePoint;
1451 let mut jdx :usize;
1452 let mut affinepoints :Vec<ECPrimePoint>;
1453 let mut affidx :usize;
1454 let mut r_is_at_infinity :bool;
1455 let mut max_len :i32=0;
1456 let mut k :i32;
1457 let mut r_is_inversted :bool = false;
1458 (curnaf,bits) = self.get_wnaf_variable(bn2)?;
1459 wnaf_bits.push(bits);
1460 wnaf.push(curnaf.clone());
1461 ecsimple_log_trace!("scalars[0] 0x{:X}",bn2);
1462 ecsimple_debug_buffer_trace!(curnaf.as_ptr(),curnaf.len(),"wNAF wsize[0] 0x{:x}",wnaf_bits[0]);
1463 cv = Vec::new();
1464 cv.push(self.clone());
1465 val_sub.push(cv.clone());
1466 ecsimple_log_trace!("val_sub[0][0].X 0x{:X} val_sub[0][0].Y 0x{:X} val_sub[0][0].Z 0x{:X}",val_sub[0][0].x(),val_sub[0][0].y(),val_sub[0][0].z());
1467
1468
1469
1470 (curnaf,bits) = self.get_wnaf_variable(bn1)?;
1471 wnaf_bits.push(bits);
1472 ecsimple_log_trace!("scalar 0x{:X}",bn1);
1473 ecsimple_debug_buffer_trace!(curnaf.as_ptr(),curnaf.len(),"wNAF wsize[1] 0x{:x}",wnaf_bits[1]);
1474 wnaf.push(curnaf.clone());
1475 cv = Vec::new();
1476 cv.push(ECPrimePoint::new(&self.group));
1477 val_sub.push(cv.clone());
1478 ecsimple_log_trace!("val_sub[1][0].X 0x{:X} val_sub[1][0].Y 0x{:X} val_sub[1][0].Z 0x{:X}",val_sub[1][0].x(),val_sub[1][0].y(),val_sub[1][0].z());
1479
1480 idx = 0;
1481 while idx < wnaf_bits.len() {
1482 while val_sub[idx].len() < (1 << (wnaf_bits[idx] - 1)) as usize {
1483 val_sub[idx].push(ECPrimePoint::new(&self.group));
1484 }
1485 idx += 1;
1486 }
1487
1488 idx = 0;
1489 while idx < wnaf.len() {
1490 if max_len < wnaf[idx].len() as i32 {
1491 max_len = wnaf[idx].len() as i32;
1492 }
1493 idx += 1;
1494 }
1495
1496 idx = 0;
1497 while idx < val_sub.len() {
1498 if idx == 0 {
1499 ecsimple_log_trace!("[{}] copy points [{}]",idx,idx);
1500 val_sub[idx][0] = self.clone();
1501 } else {
1502 ecsimple_log_trace!("[{}] copy generator",idx);
1503 val_sub[idx][0] = ECPrimePoint::new(&self.group);
1504 }
1505
1506 ecsimple_log_trace!("val_sub[{}][0].X 0x{:X} val_sub[{}][0].Y 0x{:X} val_sub[{}][0].Z 0x{:X}",idx,val_sub[idx][0].x(),idx,val_sub[idx][0].y(),idx,val_sub[idx][0].z());
1507
1508 if wnaf[idx].len() > 1 {
1509 tmp = val_sub[idx][0].dbl()?;
1510 ecsimple_log_trace!("val_sub[{}][0].x 0x{:X} val_sub[{}][0].y 0x{:X} val_sub[{}][0].z 0x{:X}",idx,val_sub[idx][0].x,idx,val_sub[idx][0].y,idx,val_sub[idx][0].z);
1511 ecsimple_log_trace!("tmp.x 0x{:X} tmp.y 0x{:X} tmp.z 0x{:X}",tmp.x,tmp.y,tmp.z);
1512 jdx = 1;
1513 while jdx < (1 << (wnaf_bits[idx]-1)) as usize {
1514 val_sub[idx][jdx] = val_sub[idx][jdx-1].add(&tmp)?;
1515 ecsimple_log_trace!("val_sub[{}][{}].x 0x{:X} val_sub[{}][{}].y 0x{:X} val_sub[{}][{}].z 0x{:X}",idx,jdx-1,val_sub[idx][jdx-1].x,idx,jdx-1,val_sub[idx][jdx-1].y,idx,jdx-1,val_sub[idx][jdx-1].z);
1516 ecsimple_log_trace!("val_sub[{}][{}].x 0x{:X} val_sub[{}][{}].y 0x{:X} val_sub[{}][{}].z 0x{:X}",idx,jdx,val_sub[idx][jdx].x,idx,jdx,val_sub[idx][jdx].y,idx,jdx,val_sub[idx][jdx].z);
1517 jdx += 1;
1518 }
1519
1520 }
1521
1522 idx += 1;
1523 }
1524
1525 idx = 0;
1526 affinepoints = Vec::new();
1527 while idx < val_sub.len() {
1528 jdx = 0;
1529 while jdx < val_sub[idx].len() {
1530 affinepoints.push(val_sub[idx][jdx].clone());
1531 jdx += 1;
1532 }
1533 idx += 1;
1534 }
1535
1536 idx = 0;
1537 while idx < affinepoints.len() {
1538 ecsimple_log_trace!("val[{}].x 0x{:X} val[{}].y 0x{:X} val[{}].z 0x{:X}",idx,affinepoints[idx].x,idx,affinepoints[idx].y,idx,affinepoints[idx].z);
1539 idx += 1;
1540 }
1541
1542 self.points_make_affine(&mut affinepoints)?;
1543
1544 idx = 0;
1545 affidx = 0;
1546 while idx < val_sub.len() {
1547 jdx = 0;
1548 while jdx < val_sub[idx].len() {
1549 val_sub[idx][jdx] = affinepoints[affidx].clone();
1550 affidx += 1;
1551 jdx += 1;
1552 }
1553 idx += 1;
1554 }
1555
1556 r_is_at_infinity = true;
1557 ecsimple_log_trace!("max_len {} wnaf.len() {}",max_len,wnaf.len());
1558 k = max_len -1 ;
1559 while k >= 0 {
1560 if ! r_is_at_infinity {
1561 retv = retv.dbl()?;
1562 }
1563 idx = 0;
1564 while idx < wnaf.len() {
1565 if wnaf[idx].len() as i32 > k {
1566 let mut digit :u8 = wnaf[idx][k as usize];
1567 let mut is_neg :bool = false;
1568 ecsimple_log_trace!("wnaf[{}][{}] 0x{:x}",idx,k,digit);
1569 if digit != 0 {
1570 if (digit & 0x80) != 0 {
1571 is_neg = true;
1572 digit = 0xff - digit + 1;
1573 }
1574 ecsimple_log_trace!("digit [{}]",digit);
1575
1576 if is_neg != r_is_inversted {
1577 if ! r_is_at_infinity {
1578 retv = retv.invert()?;
1579 }
1580 r_is_inversted = !r_is_inversted;
1581 }
1582
1583 if r_is_at_infinity {
1584 ecsimple_log_trace!("digit [{}]",digit);
1585 retv = val_sub[idx][(digit >> 1) as usize].clone();
1586 retv = retv.blind_coordinate()?;
1587 r_is_at_infinity = false;
1588 } else {
1589 ecsimple_log_trace!("digit [{}]",digit);
1590 ecsimple_log_trace!("will get [{}][{}]",idx,(digit >> 1));
1591 retv = retv.add(&val_sub[idx][(digit >> 1) as usize])?;
1592 }
1593 }
1594 }
1595 idx += 1;
1596 }
1597
1598 k -= 1;
1599 }
1600
1601 if r_is_at_infinity {
1602 retv.point_set_infinity();
1603 } else {
1604 if r_is_inversted {
1605 retv = retv.invert()?;
1606 }
1607 }
1608 Ok(retv)
1609 }
1610
1611 pub fn get_affine_points(&self) -> Result<(BigInt,BigInt),Box<dyn Error>> {
1612 let zv :BigInt = zero();
1613 let ov :BigInt = one();
1614 let x :BigInt;
1615 let y :BigInt;
1616 let z :BigInt;
1617 let z_ :BigInt;
1618 let z_1 :BigInt;
1619 let z_2 :BigInt;
1620 let z_3 :BigInt;
1621 if self.z == zv {
1622 ecsimple_new_error!{ECPrimePointError,"z == 0"}
1623 }
1624
1625 ecsimple_log_trace!("point.X 0x{:X} point.Y 0x{:X} point.Z 0x{:X}",self.x,self.y,self.z);
1626
1627 z = self.field_decode(&self.z);
1628 z_ = z.clone();
1629 if z_ == ov {
1630 x = self.x.clone();
1631 y = self.y.clone();
1632 } else {
1633 z_1 = self.field_inv(&z_);
1634 z_2 = z_1.clone() * z_1.clone() % self.group.p.clone();
1635 ecsimple_log_trace!("BN_mod_sqr(Z_2 0x{:X},Z_1 0x{:X},group.field 0x{:X})",z_2,z_1,self.group.p);
1636 x = self.field_mul(&self.x,&z_2);
1637 z_3 = z_2.clone() * z_1.clone() % self.group.p.clone();
1638 y = self.field_mul(&self.y,&z_3);
1639 }
1640
1641 ecsimple_log_trace!("x 0x{:X}",x);
1642 ecsimple_log_trace!("y 0x{:X}",y);
1643 Ok((x,y))
1644 }
1645
1646}
1647