Exemplo n.º 1
0
// ScalarMult returns k*(Bx,By) where k is a number in big-endian form. This
// uses the repeated doubling method, which is variable time.
// TODO use a constant time method to prevent side channel attacks.
func (curve *TwistedEdwardsCurve) ScalarMult(x1, y1 *big.Int,
	k []byte) (x, y *big.Int) {
	// Convert the scalar to a big int.
	s := new(big.Int).SetBytes(k)

	// Get a new group element to do cached doubling
	// calculations in.
	dEGE := new(edwards25519.ExtendedGroupElement)
	dEGE.Zero()

	// Use the doubling method for the multiplication.
	// p := given point
	// q := point(zero)
	// for each bit in the scalar, descending:
	//   double(q)
	//   if bit == 1:
	//     add(q, p)
	// return q
	//
	// Note that the addition is skipped for zero bits,
	// making this variable time and thus vulnerable to
	// side channel attack vectors.
	for i := s.BitLen() - 1; i >= 0; i-- {
		dCGE := new(edwards25519.CompletedGroupElement)
		dEGE.Double(dCGE)
		dCGE.ToExtended(dEGE)
		if s.Bit(i) == 1 {
			ss := new([32]byte)
			dEGE.ToBytes(ss)
			var err error
			xi, yi, err := curve.EncodedBytesToBigIntPoint(ss)
			if err != nil {
				return nil, nil
			}
			xAdd, yAdd := curve.Add(xi, yi, x1, y1)
			dTempBytes := BigIntPointToEncodedBytes(xAdd, yAdd)
			dEGE.FromBytes(dTempBytes)
		}
	}

	finalBytes := new([32]byte)
	dEGE.ToBytes(finalBytes)

	var err error
	x, y, err = curve.EncodedBytesToBigIntPoint(finalBytes)
	if err != nil {
		return nil, nil
	}

	return
}
Exemplo n.º 2
0
// Double adds the same pair of big integer coordinates to itself on the
// elliptical curve.
func (curve *TwistedEdwardsCurve) Double(x1, y1 *big.Int) (x, y *big.Int) {
	// Convert to extended projective coordinates.
	a := BigIntPointToEncodedBytes(x1, y1)
	aEGE := new(edwards25519.ExtendedGroupElement)
	aEGE.FromBytes(a)

	r := new(edwards25519.CompletedGroupElement)
	aEGE.Double(r)
	rEGE := new(edwards25519.ExtendedGroupElement)
	r.ToExtended(rEGE)

	s := new([32]byte)
	rEGE.ToBytes(s)
	x, y, _ = curve.EncodedBytesToBigIntPoint(s)

	return
}
Exemplo n.º 3
0
// Add adds two points represented by pairs of big integers on the elliptical
// curve.
func (curve *TwistedEdwardsCurve) Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int) {
	// Convert to extended from affine.
	a := BigIntPointToEncodedBytes(x1, y1)
	aEGE := new(edwards25519.ExtendedGroupElement)
	aEGE.FromBytes(a)

	b := BigIntPointToEncodedBytes(x2, y2)
	bEGE := new(edwards25519.ExtendedGroupElement)
	bEGE.FromBytes(b)

	// Cache b for use in group element addition.
	bCached := new(cachedGroupElement)
	toCached(bCached, bEGE)

	p := aEGE
	q := bCached

	// geAdd(r*CompletedGroupElement, p*ExtendedGroupElement,
	//   q*CachedGroupElement)
	// r is the result.
	r := new(edwards25519.CompletedGroupElement)
	var t0 edwards25519.FieldElement

	edwards25519.FeAdd(&r.X, &p.Y, &p.X)
	edwards25519.FeSub(&r.Y, &p.Y, &p.X)
	edwards25519.FeMul(&r.Z, &r.X, &q.yPlusX)
	edwards25519.FeMul(&r.Y, &r.Y, &q.yMinusX)
	edwards25519.FeMul(&r.T, &q.T2d, &p.T)
	edwards25519.FeMul(&r.X, &p.Z, &q.Z)
	edwards25519.FeAdd(&t0, &r.X, &r.X)
	edwards25519.FeSub(&r.X, &r.Z, &r.Y)
	edwards25519.FeAdd(&r.Y, &r.Z, &r.Y)
	edwards25519.FeAdd(&r.Z, &t0, &r.T)
	edwards25519.FeSub(&r.T, &t0, &r.T)

	rEGE := new(edwards25519.ExtendedGroupElement)
	r.ToExtended(rEGE)

	s := new([32]byte)
	rEGE.ToBytes(s)

	x, y, _ = curve.EncodedBytesToBigIntPoint(s)

	return
}