| 965 | } |
| 966 | |
| 967 | Point Secp256K1::Double(Point &p) { |
| 968 | |
| 969 | |
| 970 | /* |
| 971 | if (Y == 0) |
| 972 | return POINT_AT_INFINITY |
| 973 | W = a * Z ^ 2 + 3 * X ^ 2 |
| 974 | S = Y * Z |
| 975 | B = X * Y*S |
| 976 | H = W ^ 2 - 8 * B |
| 977 | X' = 2*H*S |
| 978 | Y' = W*(4*B - H) - 8*Y^2*S^2 |
| 979 | Z' = 8*S^3 |
| 980 | return (X', Y', Z') |
| 981 | */ |
| 982 | |
| 983 | Int z2; |
| 984 | Int x2; |
| 985 | Int _3x2; |
| 986 | Int w; |
| 987 | Int s; |
| 988 | Int s2; |
| 989 | Int b; |
| 990 | Int _8b; |
| 991 | Int _8y2s2; |
| 992 | Int y2; |
| 993 | Int h; |
| 994 | Point r; |
| 995 | |
| 996 | z2.ModSquareK1(&p.z); |
| 997 | z2.SetInt32(0); // a=0 |
| 998 | x2.ModSquareK1(&p.x); |
| 999 | _3x2.ModAdd(&x2,&x2); |
| 1000 | _3x2.ModAdd(&x2); |
| 1001 | w.ModAdd(&z2,&_3x2); |
| 1002 | s.ModMulK1(&p.y,&p.z); |
| 1003 | b.ModMulK1(&p.y,&s); |
| 1004 | b.ModMulK1(&p.x); |
| 1005 | h.ModSquareK1(&w); |
| 1006 | _8b.ModAdd(&b,&b); |
| 1007 | _8b.ModDouble(); |
| 1008 | _8b.ModDouble(); |
| 1009 | h.ModSub(&_8b); |
| 1010 | |
| 1011 | r.x.ModMulK1(&h,&s); |
| 1012 | r.x.ModAdd(&r.x); |
| 1013 | |
| 1014 | s2.ModSquareK1(&s); |
| 1015 | y2.ModSquareK1(&p.y); |
| 1016 | _8y2s2.ModMulK1(&y2,&s2); |
| 1017 | _8y2s2.ModDouble(); |
| 1018 | _8y2s2.ModDouble(); |
| 1019 | _8y2s2.ModDouble(); |
| 1020 | |
| 1021 | r.y.ModAdd(&b,&b); |
| 1022 | r.y.ModAdd(&r.y,&r.y); |
| 1023 | r.y.ModSub(&h); |
| 1024 | r.y.ModMulK1(&w); |