addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and (x2, y2, z2) and returns their sum, also in Jacobian form.
(x1, y1, z1, x2, y2, z2 *big.Int)
| 137 | // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and |
| 138 | // (x2, y2, z2) and returns their sum, also in Jacobian form. |
| 139 | func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { |
| 140 | // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl |
| 141 | z1z1 := new(big.Int).Mul(z1, z1) |
| 142 | z1z1.Mod(z1z1, BitCurve.P) |
| 143 | z2z2 := new(big.Int).Mul(z2, z2) |
| 144 | z2z2.Mod(z2z2, BitCurve.P) |
| 145 | |
| 146 | u1 := new(big.Int).Mul(x1, z2z2) |
| 147 | u1.Mod(u1, BitCurve.P) |
| 148 | u2 := new(big.Int).Mul(x2, z1z1) |
| 149 | u2.Mod(u2, BitCurve.P) |
| 150 | h := new(big.Int).Sub(u2, u1) |
| 151 | if h.Sign() == -1 { |
| 152 | h.Add(h, BitCurve.P) |
| 153 | } |
| 154 | i := new(big.Int).Lsh(h, 1) |
| 155 | i.Mul(i, i) |
| 156 | j := new(big.Int).Mul(h, i) |
| 157 | |
| 158 | s1 := new(big.Int).Mul(y1, z2) |
| 159 | s1.Mul(s1, z2z2) |
| 160 | s1.Mod(s1, BitCurve.P) |
| 161 | s2 := new(big.Int).Mul(y2, z1) |
| 162 | s2.Mul(s2, z1z1) |
| 163 | s2.Mod(s2, BitCurve.P) |
| 164 | r := new(big.Int).Sub(s2, s1) |
| 165 | if r.Sign() == -1 { |
| 166 | r.Add(r, BitCurve.P) |
| 167 | } |
| 168 | r.Lsh(r, 1) |
| 169 | v := new(big.Int).Mul(u1, i) |
| 170 | |
| 171 | x3 := new(big.Int).Set(r) |
| 172 | x3.Mul(x3, x3) |
| 173 | x3.Sub(x3, j) |
| 174 | x3.Sub(x3, v) |
| 175 | x3.Sub(x3, v) |
| 176 | x3.Mod(x3, BitCurve.P) |
| 177 | |
| 178 | y3 := new(big.Int).Set(r) |
| 179 | v.Sub(v, x3) |
| 180 | y3.Mul(y3, v) |
| 181 | s1.Mul(s1, j) |
| 182 | s1.Lsh(s1, 1) |
| 183 | y3.Sub(y3, s1) |
| 184 | y3.Mod(y3, BitCurve.P) |
| 185 | |
| 186 | z3 := new(big.Int).Add(z1, z2) |
| 187 | z3.Mul(z3, z3) |
| 188 | z3.Sub(z3, z1z1) |
| 189 | if z3.Sign() == -1 { |
| 190 | z3.Add(z3, BitCurve.P) |
| 191 | } |
| 192 | z3.Sub(z3, z2z2) |
| 193 | if z3.Sign() == -1 { |
| 194 | z3.Add(z3, BitCurve.P) |
| 195 | } |
| 196 | z3.Mul(z3, h) |