我在使用 OpenSSL 的 BIGNUM 库提出“正确答案”时遇到了一些问题。我正在使用 OpenSSL 1.0.1c(2012 年 5 月,标准 Mint 存储库中提供的最新包)。
我将 BIGNUM 用于使用有限域(又名伽罗瓦域)的密码学项目。基本上我有一个大素数 (q) 和一个安全素数 (p, 其中 p = 2q + 1)。我的领域是 q 阶的 Fp。
我需要生成一个“g”。我发现最简单的方法是选择一个随机的“h”(1 < h < p-1),然后执行 g = h^((p-1)/q) mod p。有了“g”,我就可以通过执行 g^q mod p = 1 来证明它在 FF 中。
当我在纸上为任何合理的小数字这样做时,它是正确的。但是,当我使用 OpenSSL 和大素数时,它不起作用!当我测试我的 g^q mod p == 1 的结果是否时,使用 BN_is_one() 会不断失败。如果我打印出这个值,它总是一个大的不相关的素数。
到底是怎么回事?我不确定这里发生了什么,或者我是否误解了什么。
我的代码片段如下:
BN_generate_prime(q, KEYSIZE - 1, 0, 0, 0, 0, 0); //generate "q"
// Calculate "p" = 2q + 1
BN_lshift1(p, q);
BN_add(p, p, one); //one = BN_one()
// 1: gExp = (p-1)/q
// 2: h => 1 < h < (p-1)
// 3: g = h^gExp mod p
BN_div(gExp, NULL, pMinusOne, q, ctx); // (1)
BN_pseudo_rand_range(h, pMinusOne); // (2)
BN_mod_exp(g, h, gExp, p, ctx); // (3)
BN_mod_exp(temp, g, q, p, ctx); // g^q mod p = 1, or it should