Beispiel #1
0
// Bytes returns the variable length byte slice of the value.
// It returns the byte slice using the same endianness as i.
func (i *Int) Bytes() []byte {
	buff := i.V.Bytes()
	if i.BO == LittleEndian {
		buff = util.Reverse(buff, buff)
	}
	return buff
}
Beispiel #2
0
// Decode an Edwards curve point into the given x,y coordinates.
// Returns an error if the input does not denote a valid curve point.
// Note that this does NOT check if the point is in the prime-order subgroup:
// an adversary could create an encoding denoting a point
// on the twist of the curve, or in a larger subgroup.
// However, the "safecurves" criteria (http://safecurves.cr.yp.to)
// ensure that none of these other subgroups are small
// other than the tiny ones represented by the cofactor;
// hence Diffie-Hellman exchange can be done without subgroup checking
// without exposing more than the least-significant bits of the scalar.
func (c *curve) decodePoint(bb []byte, x, y *nist.Int) error {

	// Convert from little-endian
	//fmt.Printf("decoding:\n%s\n", hex.Dump(bb))
	b := make([]byte, len(bb))
	util.Reverse(b, bb)

	// Extract the sign of the x-coordinate
	xsign := uint(b[0] >> 7)
	b[0] &^= 0x80

	// Extract the y-coordinate
	y.V.SetBytes(b)
	y.M = &c.P

	// Compute the corresponding x-coordinate
	if !c.solveForX(x, y) {
		return errors.New("invalid elliptic curve point")
	}
	if c.coordSign(x) != xsign {
		x.Neg(x)
	}

	return nil
}
Beispiel #3
0
// SetBytes set the value value to a number represented
// by a byte string.
// Endianness depends on the endianess set in i.
func (i *Int) SetBytes(a []byte) abstract.Scalar {
	var buff = a
	if i.BO == LittleEndian {
		buff = util.Reverse(nil, a)
	}
	i.V.SetBytes(buff).Mod(&i.V, i.M)
	return i
}
Beispiel #4
0
// Encode the value of this Int into a little-endian byte-slice
// at least min bytes but no more than max bytes long.
// Panics if max != 0 and the Int cannot be represented in max bytes.
func (i *Int) LittleEndian(min, max int) []byte {
	act := i.MarshalSize()
	pad := act
	if pad < min {
		pad = min
	}
	if max != 0 && pad > max {
		panic("Int not representable in max bytes")
	}
	buf := make([]byte, pad)
	util.Reverse(buf[:act], i.V.Bytes())
	return buf
}
Beispiel #5
0
// Attempt to decode a Int from a byte-slice buffer.
// Returns an error if the buffer is not exactly Len() bytes long
// or if the contents of the buffer represents an out-of-range integer.
func (i *Int) UnmarshalBinary(buf []byte) error {
	if len(buf) != i.MarshalSize() {
		return errors.New("Int.Decode: wrong size buffer")
	}
	// Still needed here because of the comparison with the modulo
	if i.BO == LittleEndian {
		buf = util.Reverse(nil, buf)
	}
	i.V.SetBytes(buf)
	if i.V.Cmp(i.M) >= 0 {
		return errors.New("Int.Decode: value out of range")
	}
	return nil
}
Beispiel #6
0
// Encode an Edwards curve point.
// We use little-endian encoding for consistency with Ed25519.
func (c *curve) encodePoint(x, y *nist.Int) []byte {

	// Encode the y-coordinate
	b, _ := y.MarshalBinary()

	// Encode the sign of the x-coordinate.
	if y.M.BitLen()&7 == 0 {
		// No unused bits at the top of y-coordinate encoding,
		// so we must prepend a whole byte.
		b = append(make([]byte, 1), b...)
	}
	if c.coordSign(x) != 0 {
		b[0] |= 0x80
	}

	// Convert to little-endian
	util.Reverse(b, b)
	//fmt.Printf("encoding %s,%s:\n%s\n", x.String(), y.String(),
	//		hex.Dump(b))
	return b
}
Beispiel #7
0
// Pick a [pseudo-]random curve point with optional embedded data,
// filling in the point's x,y coordinates
// and returning any remaining data not embedded.
func (c *curve) pickPoint(P point, data []byte, rand cipher.Stream) []byte {

	// How much data to embed?
	dl := c.pickLen()
	if dl > len(data) {
		dl = len(data)
	}

	// Retry until we find a valid point
	var x, y nist.Int
	var Q abstract.Point
	for {
		// Get random bits the size of a compressed Point encoding,
		// in which the topmost bit is reserved for the x-coord sign.
		l := c.PointLen()
		b := make([]byte, l)
		rand.XORKeyStream(b, b) // Interpret as little-endian
		if data != nil {
			b[0] = byte(dl)       // Encode length in low 8 bits
			copy(b[1:1+dl], data) // Copy in data to embed
		}
		util.Reverse(b, b) // Convert to big-endian form

		xsign := b[0] >> 7                    // save x-coordinate sign bit
		b[0] &^= 0xff << uint(c.P.BitLen()&7) // clear high bits

		y.M = &c.P // set y-coordinate
		y.SetBytes(b)

		if !c.solveForX(&x, &y) { // Corresponding x-coordinate?
			continue // none, retry
		}

		// Pick a random sign for the x-coordinate
		if c.coordSign(&x) != uint(xsign) {
			x.Neg(&x)
		}

		// Initialize the point
		P.initXY(&x.V, &y.V, c.self)
		if c.full {
			// If we're using the full group,
			// we just need any point on the curve, so we're done.
			return data[dl:]
		}

		// 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, &c.cofact) // multiply by cofactor
			if P.Equal(c.null) {
				continue // unlucky; try again
			}
			return data[dl:]
		}

		// Since we need the point's y-coordinate to make sense,
		// we must simply check if the point is in the subgroup
		// and retry point generation until it is.
		if Q == nil {
			Q = c.self.Point()
		}
		Q.Mul(P, &c.order)
		if Q.Equal(c.null) {
			return data[dl:]
		}

		// Keep trying...
	}
}
Beispiel #8
0
// Set value to a number represented in a little-endian byte string.
func (i *Int) SetLittleEndian(a []byte) *Int {
	be := make([]byte, len(a))
	util.Reverse(be, a)
	i.V.SetBytes(be).Mod(&i.V, i.M)
	return i
}