用于 Diffie-Hellman 密钥交换的 C++ GMP 随机数生成

C++ GMP random number generation for Diffie-Hellman Key Exchange

我需要为 Diffie-Hellman 密钥交换计算私钥 (privateKey)。我已经给出了一个大素数,现在我只需要选择一个小于 p 的数。这是我的代码:

        mpz_class privateKey;
        unsigned long seed;
        mpz_init(privateKey.get_mpz_t());

        gmp_randstate_t rstate;
        gmp_randinit_mt(rstate);
        gmp_randseed_ui(rstate, seed);

        mpz_urandomm(privateKey.get_mpz_t(), rstate, prime.get_mpz_t());

我真的不明白为什么我总是得到相同的 "random" 号码。

你从未初始化 seed 变量,所以你的程序显然是错误的,你的编译器应该已经警告过你了。如果没有,请查看如何正确配置您的编译器(例如,对于 GCC,请确保您至少通过 -O -Wall)。

如果您使用相同的种子初始化 RNG,您将始终获得相同的随机数。这可能是你程序中发生的事情:seed 没有初始化,所以它的值是之前这个地址在堆栈上的任何值,如果你在同一个函数中调用这个函数,结果总是一样的方式。

由于这是一个加密应用程序,您需要使用高熵源为随机数生成器播种。向你的操作系统询问它(没有办法在程序内部生成熵):在 Linux 上从 /dev/urandom 读取,在 Windows.

上调用 CryptGenRandom

此外,由于这是一个加密应用程序,请不要调用 gmp_randinit_mt。这创建了一个梅森扭曲器,它对于物理模拟来说足够快且足够好,但不适用于密码学,因为它的状态可以从其输出中重建。我不熟悉 GMP,但查看 documentation,我发现它提供了几种随机数生成算法,但 none 适用于安全应用程序。您可以像 /dev/urandomCryptGenRandom 一样直接使用 OS 源作为随机位的源,但是您需要使用它来按顺序实现 gmp_randstate_t 接口将它与 mpz_urandomm 连接起来。不知道有多难

如果这是学校练习,请按照老师告诉您的去做。如果这是针对实际应用程序,请使用现有的密码库,例如 libtom,它包含生成密码质量随机数和执行 Diffie-Hellman 计算所需的一切,非常容易集成到项目,并拥有允许将其集成到任何项目中的许可证。