// 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) }
// Verify checks whether the message has a valid signature. func Verify(publicKey [32]byte, message []byte, signature *[64]byte) bool { publicKey[31] &= 0x7F /* Convert the Curve25519 public key into an Ed25519 public key. In particular, convert Curve25519's "montgomery" x-coordinate into an Ed25519 "edwards" y-coordinate: ed_y = (mont_x - 1) / (mont_x + 1) NOTE: mont_x=-1 is converted to ed_y=0 since fe_invert is mod-exp Then move the sign bit into the pubkey from the signature. */ var edY, one, montX, montXMinusOne, montXPlusOne edwards25519.FieldElement edwards25519.FeFromBytes(&montX, &publicKey) edwards25519.FeOne(&one) edwards25519.FeSub(&montXMinusOne, &montX, &one) edwards25519.FeAdd(&montXPlusOne, &montX, &one) edwards25519.FeInvert(&montXPlusOne, &montXPlusOne) edwards25519.FeMul(&edY, &montXMinusOne, &montXPlusOne) var A_ed [32]byte edwards25519.FeToBytes(&A_ed, &edY) A_ed[31] |= signature[63] & 0x80 signature[63] &= 0x7F return ed25519.Verify(&A_ed, message, signature) }