// RepresentativeToPublicKey converts a uniform representative value for a // curve25519 public key, as produced by ScalarBaseMult, to a curve25519 public // key. func RepresentativeToPublicKey(publicKey, representative *[32]byte) { var rr2, v, e edwards25519.FieldElement edwards25519.FeFromBytes(&rr2, representative) edwards25519.FeSquare2(&rr2, &rr2) rr2[0]++ edwards25519.FeInvert(&rr2, &rr2) edwards25519.FeMul(&v, &edwards25519.A, &rr2) edwards25519.FeNeg(&v, &v) var v2, v3 edwards25519.FieldElement edwards25519.FeSquare(&v2, &v) edwards25519.FeMul(&v3, &v, &v2) edwards25519.FeAdd(&e, &v3, &v) edwards25519.FeMul(&v2, &v2, &edwards25519.A) edwards25519.FeAdd(&e, &v2, &e) chi(&e, &e) var eBytes [32]byte edwards25519.FeToBytes(&eBytes, &e) // eBytes[1] is either 0 (for e = 1) or 0xff (for e = -1) eIsMinus1 := int32(eBytes[1]) & 1 var negV edwards25519.FieldElement edwards25519.FeNeg(&negV, &v) edwards25519.FeCMove(&v, &negV, eIsMinus1) edwards25519.FeZero(&v2) edwards25519.FeCMove(&v2, &edwards25519.A, eIsMinus1) edwards25519.FeSub(&v, &v, &v2) edwards25519.FeToBytes(publicKey, &v) }
// IsOnCurve returns bool to say if the point (x,y) is on the curve by // checking (y^2 - x^2 - 1 - dx^2y^2) % P == 0. func (curve *TwistedEdwardsCurve) IsOnCurve(x *big.Int, y *big.Int) bool { // Convert to field elements. xB := BigIntToEncodedBytes(x) yB := BigIntToEncodedBytes(y) yfe := new(edwards25519.FieldElement) xfe := new(edwards25519.FieldElement) edwards25519.FeFromBytes(yfe, yB) edwards25519.FeFromBytes(xfe, xB) x2 := new(edwards25519.FieldElement) edwards25519.FeSquare(x2, xfe) y2 := new(edwards25519.FieldElement) edwards25519.FeSquare(y2, yfe) dx2y2 := new(edwards25519.FieldElement) edwards25519.FeMul(dx2y2, &fed, x2) edwards25519.FeMul(dx2y2, dx2y2, y2) enum := new(edwards25519.FieldElement) edwards25519.FeSub(enum, y2, x2) edwards25519.FeSub(enum, enum, &feOne) edwards25519.FeSub(enum, enum, dx2y2) enumBig := FieldElementToBigInt(enum) enumBig.Mod(enumBig, curve.P) if enumBig.Cmp(zero) != 0 { return false } // Check if we're in the cofactor of the curve (8). modEight := new(big.Int) modEight.Mod(enumBig, eight) if modEight.Cmp(zero) != 0 { return false } return true }
// 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 }
// EncodedBytesToFieldElement converts a 32 byte little endian integer into // a field element. func EncodedBytesToFieldElement(s *[32]byte) *edwards25519.FieldElement { fe := new(edwards25519.FieldElement) edwards25519.FeFromBytes(fe, s) return fe }
// BigIntToFieldElement converts a big little endian integer into its corresponding // 40 byte field representation. func BigIntToFieldElement(a *big.Int) *edwards25519.FieldElement { aB := BigIntToEncodedBytes(a) fe := new(edwards25519.FieldElement) edwards25519.FeFromBytes(fe, aB) return fe }