Пример #1
0
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
}
Пример #2
0
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...
	}
}