Пример #1
0
// extendedToBigAffine converts projective x, y, and z field elements into
// affine x and y coordinates, and returns whether or not the x value
// returned is negative.
func (curve *TwistedEdwardsCurve) extendedToBigAffine(xi, yi,
	zi *edwards25519.FieldElement) (*big.Int, *big.Int, bool) {
	var recip, x, y edwards25519.FieldElement

	// Normalize to Z=1.
	edwards25519.FeInvert(&recip, zi)
	edwards25519.FeMul(&x, xi, &recip)
	edwards25519.FeMul(&y, yi, &recip)

	isNegative := edwards25519.FeIsNegative(&x) == 1

	return FieldElementToBigInt(&x), FieldElementToBigInt(&y), isNegative
}
Пример #2
0
// BigIntPointToEncodedBytes converts an affine point to a compressed
// 32 byte integer representation.
func BigIntPointToEncodedBytes(x *big.Int, y *big.Int) *[32]byte {
	s := BigIntToEncodedBytes(y)
	xB := BigIntToEncodedBytes(x)
	xFE := new(edwards25519.FieldElement)
	edwards25519.FeFromBytes(xFE, xB)
	isNegative := edwards25519.FeIsNegative(xFE) == 1

	if isNegative {
		s[31] |= (1 << 7)
	} else {
		s[31] &^= (1 << 7)
	}

	return s
}
Пример #3
0
// RecoverXFieldElement recovers the X value for some Y value, for a coordinate
// on the Ed25519 curve given as a field element. Y value. Probably the fastest
// way to get your respective X from Y.
func (curve *TwistedEdwardsCurve) RecoverXFieldElement(xIsNeg bool,
	y *edwards25519.FieldElement) *edwards25519.FieldElement {
	// (y^2 - 1)
	l := new(edwards25519.FieldElement)
	edwards25519.FeSquare(l, y)
	edwards25519.FeSub(l, l, &feOne)

	// inv(d*y^2+1)
	r := new(edwards25519.FieldElement)
	edwards25519.FeSquare(r, y)
	edwards25519.FeMul(r, r, &fed)
	edwards25519.FeAdd(r, r, &feOne)
	edwards25519.FeInvert(r, r)

	x2 := new(edwards25519.FieldElement)
	edwards25519.FeMul(x2, r, l)

	// Get a big int so we can do the exponentiation.
	x2Big := FieldElementToBigInt(x2)

	// x = exp(x^2,(P+3)/8, P)
	qp3 := new(big.Int).Add(curve.P, three)
	qp3.Div(qp3, eight) // /= curve.H
	xBig := new(big.Int).Exp(x2Big, qp3, curve.P)

	// Convert back to a field element and do
	// the rest.
	x := BigIntToFieldElement(xBig)

	// check (x^2 - x2) % q != 0
	x22 := new(edwards25519.FieldElement)
	edwards25519.FeSquare(x22, x)
	xsub := new(edwards25519.FieldElement)
	edwards25519.FeSub(xsub, x22, x2)
	xsubBig := FieldElementToBigInt(xsub)
	xsubBig.Mod(xsubBig, curve.P)

	if xsubBig.Cmp(zero) != 0 {
		xi := new(edwards25519.FieldElement)
		edwards25519.FeMul(xi, x, &feI)
		xiModBig := FieldElementToBigInt(xi)
		xiModBig.Mod(xiModBig, curve.P)
		xiMod := BigIntToFieldElement(xiModBig)

		x = xiMod
	}

	xBig = FieldElementToBigInt(x)
	xmod2 := new(big.Int).Mod(xBig, two)
	if xmod2.Cmp(zero) != 0 {
		// TODO replace this with FeSub
		xBig.Sub(curve.P, xBig)
		x = BigIntToFieldElement(xBig)
	}

	// We got the wrong x, negate it to get the right one.
	isNegative := edwards25519.FeIsNegative(x) == 1
	if xIsNeg != isNegative {
		edwards25519.FeNeg(x, x)
	}

	return x
}