【问题标题】:Python: Solution for high int-precision needed (generate primes)Python:需要高精度整数的解决方案(生成素数)
【发布时间】:2018-05-04 18:34:28
【问题描述】:

目前我尝试从 NIST(附录 B3.2.1)的 FIPS186-4 中显示的算法实现 generate_random_prime() 函数,请参阅 here

但由于 Python 的精度,步骤 4.4 似乎存在很大问题(如果 p

要显示我的代码的相关部分和问题,请参见以下示例:

import os
from decimal import Decimal
import math

for i in range(100):
    nlen = 2048 #my key-size should be 2048bit
    p = int.from_bytes(os.urandom(int(2048/2/8)), byteorder = "little") #see Ann1 and Ann2

    print(p < Decimal(math.sqrt(2))*(Decimal(2**(int(2048/2))) - 1)

Ann1: 2048/2/8 因为字节 Ann2:我知道 os.urandom 不是最好的生成器——我稍后会使用一个经过批准的生成器……对于测试阶段,我认为它应该是可以接受的……

结果总是“真”——所以算法永远不会离开步骤 4.4。

我认为问题是Decimal(math.sqrt(2))*(Decimal(2**(int(2048/2))) - 1),因为它的结果是Decimal('2.542322012307292741109308792E+308')。通过int(Decimal(math.sqrt(2))*(Decimal(2**(int(2048/2))) - 1))转换为int,结果为

254232201230729274110930879200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

四舍五入! - 这是总是 True 结果的原因吗?我认为在这种情况下,永远不可能得到小于Decimal(math.sqrt(2))*(Decimal(2**(int(2048/2))) - 1)的p

我该如何解决这个问题?

__ 编辑:发现一个错误: Decimal(math.sqrt(2))*(Decimal(2**(int(2048/2))) - 1) 应该是 Decimal(math.sqrt(2))*(Decimal(2**(int(2048/2-1)))),所以这个结果应该是 Decimal('1.271161006153646370554654396E+308') 而不是 Decimal('2.542322012307292741109308791E+308')

【问题讨论】:

  • 你为什么要使用十进制?
  • 我不是一个非常高级的python程序员......但在某些情况下我会因为大整数和小数而出错,所以我在任何情况下都尝试使用小数......
  • 该算法中的每个步骤,包括步骤 4.4,都假定使用整数实现。不是浮点数,不是十进制,只是整数。您不需要对 sqrt(2)*(...) 进行高度准确的近似,您只需要一个可以快速计算的相当准确的 上限。或者您可以为常见的素数大小(如 1024 位和 2048 位)预先计算此值。

标签: python math int decimal primes


【解决方案1】:

您不断在浮点数、整数和Decimal 之间进行转换。放弃对float的所有使用;这包括不使用产生float 值的函数,例如math.sqrt()

改为使用Decimal 对象,仅将最终值转换为整数:

int(Decimal(2).sqrt() * 2 ** ((nlen // 2) - 1))

注意//的使用,使用整数除法,而不是真正的除法(再次产生浮点数)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2019-03-21
    • 1970-01-01
    相关资源
    最近更新 更多