Beispiel #1
0
// Initialize Elligator 1 parameters given magic point s
func (el *el1param) init(ec *curve, s *big.Int) *el1param {
	var two, invc, cm1, d nist.Int

	el.ec = ec
	el.s.Init(s, &ec.P)

	// c = 2/s^2
	two.Init64(2, &ec.P)
	el.c.Mul(&el.s, &el.s).Div(&two, &el.c)

	// r = c+1/c
	invc.Inv(&el.c)
	el.r.Add(&el.c, &invc)

	// Precomputed values
	el.r2m2.Mul(&el.r, &el.r).Sub(&el.r2m2, &two)          // r^2-2
	el.invc2.Mul(&invc, &invc)                             // 1/c^2
	el.pp1d4.Add(&ec.P, one).Div(&el.pp1d4, big.NewInt(4)) // (p+1)/4
	cm1.Sub(&el.c, &ec.one)
	el.cm1s.Mul(&cm1, &el.s) // (c-1)s
	el.m2.Init64(-2, &ec.P)  // -2

	// 2s(c-1)Chi(c)/r
	chi(&el.c3x, &el.c)
	el.c3x.Mul(&el.c3x, &two).Mul(&el.c3x, &el.s).Mul(&el.c3x, &cm1)
	el.c3x.Div(&el.c3x, &el.r)

	// Sanity check: d = -(c+1)^2/(c-1)^2
	d.Add(&el.c, &ec.one).Div(&d, &cm1).Mul(&d, &d).Neg(&d)
	if d.Cmp(&ec.d) != 0 {
		panic("el1 init: d came out wrong")
	}

	return el
}
Beispiel #2
0
// Initialize a twisted Edwards curve with given parameters.
// Caller passes pointers to null and base point prototypes to be initialized.
func (c *curve) init(self abstract.Group, p *Param, fullGroup bool,
	null, base point) *curve {
	c.self = self
	c.Param = *p
	c.full = fullGroup
	c.null = null

	// Edwards curve parameters as ModInts for convenience
	c.a.Init(&p.A, &p.P)
	c.d.Init(&p.D, &p.P)

	// Cofactor
	c.cofact.Init64(int64(p.R), &c.P)

	// Determine the modulus for scalars on this curve.
	// Note that we do NOT initialize c.order with Init(),
	// as that would normalize to the modulus, resulting in zero.
	// Just to be sure it's never used, we leave c.order.M set to nil.
	// We want it to be in a ModInt so we can pass it to P.Mul(),
	// but the scalar's modulus isn't needed for point multiplication.
	if fullGroup {
		// Scalar modulus is prime-order times the ccofactor
		c.order.V.SetInt64(int64(p.R)).Mul(&c.order.V, &p.Q)
	} else {
		c.order.V.Set(&p.Q) // Prime-order subgroup
	}

	// Useful ModInt constants for this curve
	c.zero.Init64(0, &c.P)
	c.one.Init64(1, &c.P)

	// Identity element is (0,1)
	null.initXY(zero, one, self)

	// Base point B
	var bx, by *big.Int
	if !fullGroup {
		bx, by = &p.PBX, &p.PBY
	} else {
		bx, by = &p.FBX, &p.FBY
		base.initXY(&p.FBX, &p.FBY, self)
	}
	if by.Sign() == 0 {
		// No standard base point was defined, so pick one.
		// Find the lowest-numbered y-coordinate that works.
		//println("Picking base point:")
		var x, y nist.Int
		for y.Init64(2, &c.P); ; y.Add(&y, &c.one) {
			if !c.solveForX(&x, &y) {
				continue // try another y
			}
			if c.coordSign(&x) != 0 {
				x.Neg(&x) // try positive x first
			}
			base.initXY(&x.V, &y.V, self)
			if c.validPoint(base) {
				break // got one
			}
			x.Neg(&x) // try -bx
			if c.validPoint(base) {
				break // got one
			}
		}
		//println("BX: "+x.V.String())
		//println("BY: "+y.V.String())
		bx, by = &x.V, &y.V
	}
	base.initXY(bx, by, self)

	// Uniform representation encoding methods,
	// only useful when using the full group.
	// (Points taken from the subgroup would be trivially recognizable.)
	if fullGroup {
		if p.Elligator1s.Sign() != 0 {
			c.hide = new(el1param).init(c, &p.Elligator1s)
		} else if p.Elligator2u.Sign() != 0 {
			c.hide = new(el2param).init(c, &p.Elligator2u)
		}
		// XXX Elligator Squared
	}

	// Sanity checks
	if !c.validPoint(null) {
		panic("invalid identity point " + null.String())
	}
	if !c.validPoint(base) {
		panic("invalid base point " + base.String())
	}

	return c
}
Beispiel #3
0
func chi(r, v *nist.Int) {
	r.Init64(int64(math.Jacobi(&v.V, v.M)), v.M)
}