func (p *point) UnmarshalBinary(buf []byte) error { if len(buf) != 32 { return errors.New("curve25519 point wrong size") } if C.ge_frombytes_vartime(&p.p, (*C.uchar)(unsafe.Pointer(&buf[0]))) != 0 { return errors.New("curve25519 point invalid") } return nil }
func (P *point) Pick(data []byte, rand cipher.Stream) (abstract.Point, []byte) { // How many bytes to embed? dl := P.PickLen() if dl > len(data) { dl = len(data) } for { // Pick a random point, with optional embedded data var b [32]byte rand.XORKeyStream(b[:], b[:]) if data != nil { b[0] = byte(dl) // Encode length in low 8 bits copy(b[1:1+dl], data) // Copy in data to embed } if C.ge_frombytes_vartime(&P.p, // Try to decode (*C.uchar)(unsafe.Pointer(&b[0]))) != 0 { continue // invalid point, retry } // We're using the prime-order subgroup, // so we need to make sure the point is in that subgroup. // If we're not trying to embed data, // we can convert our point into one in the subgroup // simply by multiplying it by the cofactor. if data == nil { P.Mul(P, cofactor) // multiply by cofactor if P.Equal(nullPoint) { continue // unlucky; try again } return P, data[dl:] // success } // Since we need the point's y-coordinate to hold our data, // we must simply check if the point is in the subgroup // and retry point generation until it is. var Q point Q.Mul(P, primeOrder) if Q.Equal(nullPoint) { return P, data[dl:] // success } // Keep trying... } }