【问题标题】:Assistance finding prime numbers for cryptosystem协助寻找密码系统的素数
【发布时间】:2010-02-21 18:14:18
【问题描述】:

我是一名大学生,我有一个任务需要找到大素数。教授给了我以下“简单”算法来找到 2 个可能素数。

  1. 生成随机 a 和 p 其中 1
  2. 确认 gcd(a,p) 为 = 1 -- 这是假设删除 Carmichael 数字 Edit(意味着等于 1)
  3. 执行“模幂运算” 如果 x ^ (p-1) % p = 1 其中 x 从零开始并递增到 p-1 对于 p 和 a

第三步的例子。

假设 p = 5

1^4 %5 = 1

2^4 %5 = 1

3^4 %5 = 1

4^4 %5 = 1

这表明 5 是素数。

我通过这个作业意识到计算素数不是开玩笑。我在上述算法中看到的问题是,如果我猜测大数并使用模幂来测试它们,我可能会尝试将大数提升为大数。这让我心中产生了疑问。我也研究了确定性有限自动机和埃拉托色尼筛法。有没有人有任何建议来改进给定的算法或提供任何帮助?谢谢你的时间。

【问题讨论】:

    标签: cryptography primes


    【解决方案1】:

    您所遵循的算法称为Fermat primality test。但是,您的解释有几个问题:

    • 你说“确认 gcd(a,p)

    • 进行测试的方式是,对于某个 p 值,您选择 a 的几个随机值并检查 a ^ (p-1) % p == 1。如果其中一个是不是 1,那么 p 不是素数。您选择的值越多,准确度就越高。

    • 你当然不能像你说的那样检查 x 的所有值 - 因为要检查的太多了。

    • 有一种执行模幂运算的快速方法,即使对于大底数和指数也是如此。请参阅Wikipedia article。您仍然需要一种方法来对大整数执行乘法和取模。

    • 埃拉托色尼筛法仅对寻找小素数有用。

    • 此测试可能会错误地确定卡迈克尔数是素数。其他算法如Rabin-Miller则没有这个问题。

    【讨论】:

    • 我真的不明白 gcd 测试如何帮助检测卡迈克尔数比它检测其他具有至少 3 个质因数的复合非卡迈克尔数更好。它只是随机寻找共同因素。
    • 由于 gcd(a,p) != 1 意味着 a^(p-1) % p != 1,因此完全没有必要检查 gcd(a,p)==1。如果您实际上是在寻找 Carmichael 数字,则可能需要进行此测试。
    【解决方案2】:

    在 C# 中有点简单。我不知道它在速度方面是否会更快。

    bool IsPrime(long n)
        {
            if (n == 1)
            {
                return false;
            }
    
            if (n < 4)
            {
                return true;
            }
    
            if ((n % 2) == 0)
            {
                return false;
            }
    
            if (n < 9)
            {
                return true;
            }
    
            if ((n % 3) == 0)
            {
                return false;
            }
    
            long r = (long)Math.Floor(Math.Sqrt(n));
            long f = 5;
            while (f <= r)
            {
                if ((n % f) == 0)
                {
                    return false;
                }
    
                if ((n % (f + 2)) == 0)
                {
                    return false;
                }
    
                f += 6;
            }
    
            return true;
        }
    

    【讨论】:

    • -1:鉴于他们需要大素数以及教授建议使用随机算法,这将是完全不切实际的。
    • -1:除了 long 的低端数字之外它不会更快,并且由于作业不允许选择更慢但更简单的算法测试,因此不回答问题。
    • Moron:修改它以使用 BigNum 类会很简单。 GregS:OP 从未提到不能使用不同的算法。 (但就像我说的那样;我不知道上面的效率有多高。)
    • Bignum 类不是这里的问题。对于密码学所需大小的质数,你可以让它运行数百万年,它仍然不会返回。
    • 即使将long 替换为BitInteger 也没有用。对于相当小的素数,例如 2^256,这需要大约 2^128 次迭代,这将花费非常长的时间。
    【解决方案3】:

    前段时间我用C#写了一些函数供个人使用。希望对你有好处

    公共长 tmp; public long[] tabnum = new long[1];

    public void priminum(long NUM) { 长恢复; 长长的;

     // 2 is only number pair prime
     tabnum[0] = 2;
    
     for (tmp = 3; tmp <= NUM; tmp++)
     {
         if ((tmp % 2) == 0) continue;// if num it's pair is not prime
    
         for (long Y = 0; Y < tmp; Y++)
         {
              riso = Math.DivRem(tabnum[Y], tmp, out Resto);
              if (Resto == 0) break;
              if(riso <= tabnum[Y]) 
              {
                     Array.Resize(ref tabnum, tabnum.Length + 1);
                     tabnum[tabnum.Length - 1] = tmp;
                     List1.Items.Add(tmp.ToString("###,###"));
                     break;
               } 
          }
      }
    

    }

    如果数字是素数,下一个函数返回真

    private bool IsPrimo(ulong tmpNum) { 乌龙Y;

     if (tmpNum == 2) return true;
    
     if ((tmpNum % 2) == 0) return false;
    
     for (Y = 2; Y <= tmpNum; Y++)
     {
          if ((tmpNum % Y) == 0) break;
          if ((tmpNum / Y) <= Y) return true;
     }
    
     return false;
    

    }

    【讨论】:

    • 这对于查找密码学所需规模的大素数没有用处。
    • 比其他的还要差。
    • “比另一个还差”。谢谢,但工作。数量大是不行的,我知道这一点。你有另一个最好的算法吗? :)
    猜你喜欢
    • 2011-06-10
    • 2014-12-15
    • 2012-03-28
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多