// 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) } }