示例#1
0
func sieveInterval(n *big.Int) (min, max *big.Int) {

	lnn := float64(n.BitLen()) * math.Log(2)

	if lnn < 1.0 {
		/* if this is not done. if n is 1 everything explodes sqrt(<0) = NaN */
		lnn = 1.0
	}

	lnlnn := math.Log(lnn)
	exp := int64(math.Ceil(math.Sqrt(lnn*lnlnn) * math.Log2(math.E)))

	L := big.NewInt(0)
	L.Exp(misc.Two, big.NewInt(exp), nil) // magic parameter (wikipedia)

	sqrtN := misc.SquareRootCeil(n)

	sieveMin := big.NewInt(0)
	sieveMin.Sub(sqrtN, L)
	sieveMax := big.NewInt(0)
	sieveMax.Add(sqrtN, L)

	return sieveMin, sieveMax
}
示例#2
0
func findXandY(n *big.Int, cis, dis []*big.Int, exponents [][]int) (*big.Int, *big.Int) {

	ls := linearSystemFromExponents(exponents)
	ls.GaussianElimination(ls)
	ls = ls.EliminateEmptyRows()
	ls = ls.Transpose()
	usedCombinations := ls.MakeEmptyRows()

	if len(usedCombinations) == 0 {
		return nil, nil
	}

	aAndBSquaredList := []AandBSquared{}

	for _, indexSet := range usedCombinations {

		a := big.NewInt(1)
		bb := big.NewInt(1)

		for _, i := range indexSet {
			a.Mul(a, cis[i])
			bb.Mul(bb, dis[i])
		}

		aAndBSquaredList = append(aAndBSquaredList, AandBSquared{a, bb})
	}

	x := big.NewInt(0)
	y := big.NewInt(0)

	xTimesY := big.NewInt(0)
	multiplicity := big.NewInt(0)
	testMod := big.NewInt(0)
	gcd := big.NewInt(0)

	abbChannel := make(chan AandBSquared, 100000)
	doneChannel := make(chan bool)
	cancelChannel := make(chan bool, 1)

	var abb AandBSquared

	go createPowerSetRecursively(0, AandBSquared{big.NewInt(1), big.NewInt(1)},
		aAndBSquaredList, abbChannel, cancelChannel, doneChannel)

	numberOfIndexSetsToGo := -1

	for attempts := 0; ; /*attempts < 100*/ attempts += 1 {

		if numberOfIndexSetsToGo == 0 {
			break
		}

		select {
		case <-doneChannel:
			numberOfIndexSetsToGo = len(abbChannel)
			continue
		case abb = <-abbChannel:
			if numberOfIndexSetsToGo > -1 {
				numberOfIndexSetsToGo -= 1
			}
		}

		x.SetInt64(0)
		y.SetInt64(0)

		abb.b = misc.SquareRootCeil(abb.b)

		x.Add(abb.a, abb.b)
		x.Mod(x, n)

		y.Sub(abb.a, abb.b)
		y.Mod(y, n)

		if x.Cmp(misc.Zero) == 0 || x.Cmp(misc.One) == 0 || y.Cmp(misc.Zero) == 0 || y.Cmp(misc.One) == 0 {
			/* discard trivial solutions */
			continue
		}

		xTimesY.Mul(x, y)
		multiplicity.DivMod(xTimesY, n, testMod)

		if testMod.Cmp(misc.Zero) != 0 {
			continue
		}

		if multiplicity.Cmp(misc.One) == 1 {

			gcd.GCD(nil, nil, x, multiplicity)
			if x.Cmp(gcd) != 0 {
				x.Div(x, gcd)
			}

			multiplicity.Div(multiplicity, gcd)

			gcd.GCD(nil, nil, y, multiplicity)
			if y.Cmp(gcd) != 0 {
				y.Div(y, gcd)
			}
		}

		cancelChannel <- true
		return x, y
	}

	cancelChannel <- true
	return nil, nil
}