有人可以向我解释 Dixon 分解算法的这一部分吗?

Can someone explain to me this part of Dixon's factorization algorithm?

我一直在尝试在 python 中实现 Dixon 的因式分解方法,但我有点困惑。我知道你需要给出一些边界 B 和一些数字 N 并搜索 sqrtNN 之间的数字,其平方是 B-smooth,这意味着他们所有的因子在小于或等于 B 的素数集中。我的问题是,给定一定大小的 N,是什么决定了 B 以便算法产生 N 的非平凡因子? Here 是一篇关于该算法的维基百科文章,如果有帮助,这是我的实现代码:

def factor(N, B):
    def isBsmooth(n, b):
        factors = []
        for i in b:
            while n % i == 0:
                n = int(n / i)
                if not i in factors:
                    factors.append(i)
        if n == 1 and factors == b:
            return True
        return False

    factor1 = 1
    while factor1 == 1 or factor1 == N:
        Bsmooth = []
        BsmoothMod = []
        for i in range(int(N ** 0.5), N):
            if len(Bsmooth) < 2 and isBsmooth(i ** 2 % N, B):
                Bsmooth.append(i)
                BsmoothMod.append(i ** 2 % N)
        gcd1 = (Bsmooth[0] * Bsmooth[1]) % N
        gcd2 = int((BsmoothMod[0] * BsmoothMod[1]) ** 0.5)
        factor1 = gcd(gcd1 - gcd2, N)
        factor2 = int(N / factor1)
    return (factor1, factor2)

也许有人也可以帮我清理一下代码?看起来效率很低

本文讨论了 B 的最佳大小:https://web.archive.org/web/20160205002504/https://vmonaco.com/dixons-algorithm-and-the-quadratic-sieve/。简而言之,最优值被认为是 exp((logN loglogN)^(1/2)).

[我写这篇文章的目的不同,但您可能会发现它很有趣。 ]

给定x2y2 (mod n) with x ≠ ± y, gcd的时间大约是一半(xy,n)是n[=69的因数=]. Maurice Kraitchik 在 1920 年代观察到的这种 正方形同余 是多种因式分解方法的基础。 John Dixon 提出的其中一种方法在理论上很重要,因为它的次指数 运行 时间可以得到证明,尽管它在实践中太慢而无用。

Dixon 的方法从选择边界 b 开始。 e√(log n log log n) 和识别小于 b 的所有素数的 factor base,它们是 n 的二次留数(它们的 jacobi 符号是 1).

function factorBase(n, b)
  fb := [2]
  for p in tail(primes(b))
    if jacobi(n, p) == 1
      append p to fb
  return fb

然后在 1 < r < n 范围内重复选择一个整数 r,计算其平方 modulo n,如果平方在因子基上平滑,则将其添加到 relations 列表中,停止当因子库中的关系多于因子时,为那些失败的情况加上少量储备。这个想法是使用线性代数来识别一组关系,其中因子基素数组合形成一个正方形。然后对关系中所有因子基素数的乘积取平方根,取相关r的乘积,计算gcd来识别因子

struct rel(x, ys)

function dixon(n, fb, count)
  r, rels := floor(sqrt(n)), []
  while count > 0
    fs := smooth((r * r) % n, fb)
    if fs is not null
      append rel(r, fs) to rels
      count := count - 1
    r := r + 1
  return rels

一个数n是光滑的,如果它的所有因子都在因子基中,这是通过试分确定的; smooth 函数 returns 一个因子列表,如果 n 没有完全分解因子基数,则该列表为空。

function smooth(n, fb)
  fs := []
  for f in fb
    while n % f == 0
      append f to fs
      n := n / f
    if n == 1 return fs
  return []

通过将累积关系提交给平方求解器同余的线性代数来确定一个因子。

例如考虑143的因式分解,选择r = 17,所以r2 ≡ 3 (mod 143)。然后选择r = 19,所以r2 ≡ 75 ≡ 3 · 5 2。这两个关系可以合并为 (17 · 19)2 ≡ 32 · 52 ≡ 152 (mod 143), 两个因子为 gcd(17·19 − 15, 143) = 11 和 gcd(17·19 + 15, 143) = 13. 这有时会失败;例如,关系 212 ≡ 22 (mod 143) 可以与 19 上的关系组合,但是两者产生的因子 1 和 143 是微不足道的。