1use crate::sm2::p256_ecc::{Point, P256C_PARAMS};
2
3pub(crate) fn add_1998_cmo(p1: &Point, p2: &Point) -> Point {
18    let x1 = &p1.x;
19    let y1 = &p1.y;
20    let z1 = &p1.z;
21    let x2 = &p2.x;
22    let y2 = &p2.y;
23    let z2 = &p2.z;
24
25    let z1z1 = z1.square();
26    let z2z2 = z2.square();
27    let u1 = x1 * &z2z2;
28    let u2 = x2 * &z1z1;
29    let s1 = y1 * z2 * &z2z2;
30    let s2 = y2 * z1 * &z1z1;
31    let h = &u2 - &u1;
32
33    let r = &s2 - &s1;
34    let hh = h.square();
35    let hhh = &h * &hh;
36    let v = &u1 * &hh;
37    let x3 = &r.square() - &hhh - &v.double();
38    let y3 = &r * (&v - &x3) - &s1 * &hhh;
39    let z3 = z1 * z2 * &h;
40
41    Point {
42        x: x3,
43        y: y3,
44        z: z3,
45    }
46}
47
48pub(crate) fn double_1998_cmo(p1: &Point) -> Point {
51    let ecc_a = &P256C_PARAMS.a;
52    let (x1, y1, z1) = (&p1.x, &p1.y, &p1.z);
53    let is_z1_one = z1.is_one();
54    let yy = y1.square();
55    let yyyy = &yy.square();
56    let xx = x1.square();
57    let s = x1.double().double() * &yy;
58    if !is_z1_one {
59        let zz = z1.square();
60        let m = &xx.double() + &xx + ecc_a * &zz.square();
61        let t = &m.square() - &s.double();
62        let y3 = &m * (&s - &t) - yyyy.double().double().double();
63        let x3 = t;
64        let z3 = (y1 + z1).square() - &yy - &zz;
65        Point {
66            x: x3,
67            y: y3,
68            z: z3,
69        }
70    } else {
71        let m = (xx.double() + xx) + ecc_a;
72        let t = &m.square() - &s.double();
73        let x3 = t;
74        let y3 = m * (s - &x3) - yyyy.double().double().double();
75        let z3 = y1.double();
76        Point {
77            x: x3,
78            y: y3,
79            z: z3,
80        }
81    }
82}