Exemple #1
0
// doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
// returns its double, also in Jacobian form.
func (curve *Curve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
	// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
	delta := new(big.Int).Mul(z, z)
	delta.Mod(delta, curve.P)
	gamma := new(big.Int).Mul(y, y)
	gamma.Mod(gamma, curve.P)
	alpha := new(big.Int).Sub(x, delta)
	if alpha.Sign() == -1 {
		alpha.Add(alpha, curve.P)
	}
	alpha2 := new(big.Int).Add(x, delta)
	alpha.Mul(alpha, alpha2)
	alpha2.Set(alpha)
	alpha.Lsh(alpha, 1)
	alpha.Add(alpha, alpha2)

	beta := alpha2.Mul(x, gamma)

	x3 := new(big.Int).Mul(alpha, alpha)
	beta8 := new(big.Int).Lsh(beta, 3)
	x3.Sub(x3, beta8)
	for x3.Sign() == -1 {
		x3.Add(x3, curve.P)
	}
	x3.Mod(x3, curve.P)

	z3 := new(big.Int).Add(y, z)
	z3.Mul(z3, z3)
	z3.Sub(z3, gamma)
	if z3.Sign() == -1 {
		z3.Add(z3, curve.P)
	}
	z3.Sub(z3, delta)
	if z3.Sign() == -1 {
		z3.Add(z3, curve.P)
	}
	z3.Mod(z3, curve.P)

	beta.Lsh(beta, 2)
	beta.Sub(beta, x3)
	if beta.Sign() == -1 {
		beta.Add(beta, curve.P)
	}
	y3 := alpha.Mul(alpha, beta)

	gamma.Mul(gamma, gamma)
	gamma.Lsh(gamma, 3)
	gamma.Mod(gamma, curve.P)

	y3.Sub(y3, gamma)
	if y3.Sign() == -1 {
		y3.Add(y3, curve.P)
	}
	y3.Mod(y3, curve.P)

	return x3, y3, z3
}
func Factorial(n uint64) (r *big.Int) {
	var oddFactNDiv2, oddFactNDiv4 big.Int

	// closes on oddFactNDiv2, oddFactNDiv4
	oddSwing := func(n uint64) (r *big.Int) {

		if n < uint64(len(smallOddSwing)) {
			return big.NewInt(smallOddSwing[n])
		}

		length := (n - 1) / 4
		if n%4 != 2 {
			length++
		}
		high := n - (n+1)&1
		ndiv4 := n / 4

		var oddFact big.Int
		if ndiv4 < uint64(len(smallOddFactorial)) {
			oddFact.SetInt64(smallOddFactorial[ndiv4])
			r = &oddFact
		} else {
			r = &oddFactNDiv4
		}

		return oddFact.Quo(oddProduct(high, length), r)
	}

	// closes on oddFactNDiv2, oddFactNDiv4, oddSwing, and itself
	var oddFactorial func(uint64) *big.Int
	oddFactorial = func(n uint64) (oddFact *big.Int) {
		if n < uint64(len(smallOddFactorial)) {
			oddFact = big.NewInt(smallOddFactorial[n])
		} else {
			oddFact = oddFactorial(n / 2)
			oddFact.Mul(oddFact.Mul(oddFact, oddFact), oddSwing(n))
		}

		oddFactNDiv4.Set(&oddFactNDiv2)
		oddFactNDiv2.Set(oddFact)
		return oddFact
	}

	oddFactNDiv2.SetInt64(1)
	oddFactNDiv4.SetInt64(1)
	r = oddFactorial(n)
	exp := uint(n - uint64(xmath.BitCount64(n)))
	return r.Lsh(r, exp)
}
func recursive(in int64, value *big.Int, v vector.IntVector, primeIndex int, primes []*big.Int, winner *big.Int, winner2 *vector.IntVector) {

	if in > 4000000 {

		if value.Cmp(winner) < 0 || winner.Cmp(big.NewInt(-1)) == 0 {
			winner.Set(value)
			*winner2 = v
			fmt.Println(in, winner, *winner2)
			//fmt.Print(in, winner, *winner2, " (")
			//for k, v := range *winner2 {
			//	fmt.Print(primes[k], "**", v, " * ")
			//}
			//fmt.Println(")")
		}

		return
	}

	for i := int64(15); i >= 1; i -= 1 {

		var factor big.Int

		factor.Exp(primes[primeIndex], big.NewInt(i), nil)

		//fmt.Println(factor, i, primes[primeIndex])

		newV := v.Copy()
		newV.Push(int(i))

		var newValue big.Int
		newValue.Mul(value, &factor)

		recursive(in*(2*i+1)-i, &newValue, newV, primeIndex+1, primes, winner, winner2)

	}
}