31
31
// Double returns 2*(x,y)
32
32
Double(x1, y1 *big.Int) (x, y *big.Int)
33
33
// ScalarMult returns k*(Bx,By) where k is a number in big-endian form.
34
ScalarMult(x1, y1 *big.Int, scalar []byte) (x, y *big.Int)
35
// ScalarBaseMult returns k*G, where G is the base point of the group and k
36
// is an integer in big-endian form.
37
ScalarBaseMult(scalar []byte) (x, y *big.Int)
34
ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int)
35
// ScalarBaseMult returns k*G, where G is the base point of the group
36
// and k is an integer in big-endian form.
37
ScalarBaseMult(k []byte) (x, y *big.Int)
40
40
// CurveParams contains the parameters of an elliptic curve and also provides
69
69
return x3.Cmp(y2) == 0
72
// zForAffine returns a Jacobian Z value for the affine point (x, y). If x and
73
// y are zero, it assumes that they represent the point at infinity because (0,
74
// 0) is not on the any of the curves handled here.
75
func zForAffine(x, y *big.Int) *big.Int {
77
if x.Sign() != 0 || y.Sign() != 0 {
72
83
// affineFromJacobian reverses the Jacobian transform. See the comment at the
84
// top of the file. If the point is ∞ it returns 0, 0.
74
85
func (curve *CurveParams) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
87
return new(big.Int), new(big.Int)
75
90
zinv := new(big.Int).ModInverse(z, curve.P)
76
91
zinvsq := new(big.Int).Mul(zinv, zinv)
86
101
func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
87
z := new(big.Int).SetInt64(1)
88
return curve.affineFromJacobian(curve.addJacobian(x1, y1, z, x2, y2, z))
102
z1 := zForAffine(x1, y1)
103
z2 := zForAffine(x2, y2)
104
return curve.affineFromJacobian(curve.addJacobian(x1, y1, z1, x2, y2, z2))
91
107
// addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
92
108
// (x2, y2, z2) and returns their sum, also in Jacobian form.
93
109
func (curve *CurveParams) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
94
110
// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
111
x3, y3, z3 := new(big.Int), new(big.Int), new(big.Int)
95
125
z1z1 := new(big.Int).Mul(z1, z1)
96
126
z1z1.Mod(z1z1, curve.P)
97
127
z2z2 := new(big.Int).Mul(z2, z2)
119
150
if r.Sign() == -1 {
120
151
r.Add(r, curve.P)
153
yEqual := r.Sign() == 0
154
if xEqual && yEqual {
155
return curve.doubleJacobian(x1, y1, z1)
123
158
v := new(big.Int).Mul(u1, i)
125
x3 := new(big.Int).Set(r)
130
165
x3.Mod(x3, curve.P)
132
y3 := new(big.Int).Set(r)
156
185
func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
157
z1 := new(big.Int).SetInt64(1)
186
z1 := zForAffine(x1, y1)
158
187
return curve.affineFromJacobian(curve.doubleJacobian(x1, y1, z1))
221
250
func (curve *CurveParams) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
222
// We have a slight problem in that the identity of the group (the
223
// point at infinity) cannot be represented in (x, y) form on a finite
224
// machine. Thus the standard add/double algorithm has to be tweaked
225
// slightly: our initial state is not the identity, but x, and we
226
// ignore the first true bit in |k|. If we don't find any true bits in
227
// |k|, then we return nil, nil, because we cannot return the identity
230
251
Bz := new(big.Int).SetInt64(1)
252
x, y, z := new(big.Int), new(big.Int), new(big.Int)
235
seenFirstTrue := false
236
254
for _, byte := range k {
237
255
for bitNum := 0; bitNum < 8; bitNum++ {
239
x, y, z = curve.doubleJacobian(x, y, z)
256
x, y, z = curve.doubleJacobian(x, y, z)
241
257
if byte&0x80 == 0x80 {
245
x, y, z = curve.addJacobian(Bx, By, Bz, x, y, z)
258
x, y, z = curve.addJacobian(Bx, By, Bz, x, y, z)
256
264
return curve.affineFromJacobian(x, y, z)