Example #1
0
// Elligator 1 reverse-map from point to uniform representative.
// Returns nil if point has no uniform representative.
// See section 3.3 of the Elligator paper.
func (el *el1param) HideEncode(P point, rand cipher.Stream) []byte {
	ec := el.ec
	x, y := P.getXY()
	var a, b, etar, etarp1, X, z, u, t, t1 nist.Int

	// condition 1: a = y+1 is nonzero
	a.Add(y, &ec.one)
	if a.V.Sign() == 0 {
		return nil // y+1 = 0, no representative
	}

	// etar = r(y-1)/2(y+1)
	t1.Add(y, &ec.one).Add(&t1, &t1) // 2(y+1)
	etar.Sub(y, &ec.one).Mul(&etar, &el.r).Div(&etar, &t1)

	// condition 2: b = (1 + eta r)^2 - 1 is a square
	etarp1.Add(&ec.one, &etar) // etarp1 = (1 + eta r)
	b.Mul(&etarp1, &etarp1).Sub(&b, &ec.one)
	if math.Jacobi(&b.V, b.M) < 0 {
		return nil // b not a square, no representative
	}

	// condition 3: if etar = -2 then x=2s(c-1)Chi(c)/r
	if etar.Equal(&el.m2) && !x.Equal(&el.c3x) {
		return nil
	}

	// X = -(1+eta r)+((1+eta r)^2-1)^((q+1)/4)
	X.Exp(&b, &el.pp1d4).Sub(&X, &etarp1)

	// z = Chi((c-1)sX(1+X)x(X^2+1/c^2))
	z.Mul(&el.cm1s, &X).Mul(&z, t.Add(&ec.one, &X)).Mul(&z, x)
	z.Mul(&z, t.Mul(&X, &X).Add(&t, &el.invc2))
	chi(&z, &z)

	// u = zX
	u.Mul(&z, &X)

	// t = (1-u)/(1+u)
	t.Div(a.Sub(&ec.one, &u), b.Add(&ec.one, &u))

	// Map representative to a byte-string by padding the upper byte.
	// This assumes that the prime c.P is close enough to a power of 2
	// that the adversary will never notice the "missing" values;
	// this is true for the class of curves Elligator1 was designed for.
	rep, _ := t.MarshalBinary()
	padmask := el.padmask()
	if padmask != 0 {
		var pad [1]byte
		rand.XORKeyStream(pad[:], pad[:])
		rep[0] |= pad[0] & padmask
	}
	return rep
}
Example #2
0
// Elligator 2 reverse-map from point to uniform representative.
// Returns nil if point has no uniform representative.
// See section 5.3 of the Elligator paper.
func (el *el2param) HideEncode(P point, rand cipher.Stream) []byte {
	edx, edy := P.getXY()
	var x, y, r, xpA, t1 nist.Int

	// convert Edwards to Montgomery coordinates
	el.ed2mont(&x, &y, edx, edy)

	// condition 1: x != -A
	if x.Equal(&el.negA) {
		return nil // x = -A, no representative
	}

	// condition 2: if y=0, then x=0
	if y.V.Sign() == 0 && x.V.Sign() != 0 {
		return nil // y=0 but x!=0, no representative
	}

	// condition 3: -ux(x+A) is a square
	xpA.Add(&x, &el.A)
	t1.Mul(&el.u, &x).Mul(&t1, &xpA).Neg(&t1)
	if math.Jacobi(&t1.V, t1.M) < 0 {
		return nil // not a square, no representative
	}

	if y.V.Cmp(&el.pm1d2) <= 0 { // y in image of sqrt function
		r.Mul(&xpA, &el.u).Div(&x, &r)
	} else { // y not in image of sqrt function
		r.Mul(&el.u, &x).Div(&xpA, &r)
	}
	r.Neg(&r)
	el.sqrt(&r, &r)

	// Sanity check on result
	if r.V.Cmp(&el.pm1d2) > 0 {
		panic("el2: r too big")
	}

	// Map representative to a byte-string by padding the upper byte.
	// This assumes that the prime c.P is close enough to a power of 2
	// that the adversary will never notice the "missing" values;
	// this is true for the class of curves Elligator1 was designed for.
	rep, _ := r.MarshalBinary()
	padmask := el.padmask()
	if padmask != 0 {
		var pad [1]byte
		rand.XORKeyStream(pad[:], pad[:])
		rep[0] |= pad[0] & padmask
	}
	return rep
}
Example #3
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
}