Мне нужно рассчитать закрытый ключ (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());
Я не очень понимаю, почему я всегда получаю одно и то же «случайное» число.
Вы никогда не инициализируете seed
переменная, так что ваша программа явно ошибочна, и ваш компилятор должен был предупредить вас об этом. Если этого не произошло, посмотрите, как правильно настроить компилятор (например, для GCC убедитесь, что вы передали хотя бы -O -Wall
).
Вы всегда получите одно и то же случайное число, если инициализируете ГСЧ с одним и тем же начальным числом. Это, вероятно, то, что происходит в вашей программе: seed
не инициализируется, поэтому его значением является то, что было в стеке по этому адресу ранее, и это оказывается всегда одинаковым, если вы вызываете эту функцию одинаковым образом.
Поскольку это криптографическое приложение, вам нужно заполнить генератор случайных чисел источником с высокой энтропией. Спросите об этом у вашей операционной системы (нет способа генерировать энтропию в программе): читайте из /dev/urandom
в Linux звоните CryptGenRandom
на винде.
Кроме того, так как это криптографическое приложение, не звоните gmp_randinit_mt
, Это создает твистер Мерсенна, который быстр и достаточно хорош для физического моделирования, но не подходит для криптографии, потому что его состояние может быть восстановлено из его выходных данных. Я не знаком с GMP, но, глядя на документация, Я вижу, что он предлагает несколько алгоритмов для генерации случайных чисел, но ни один не подходит для приложений безопасности. Вы можете использовать источник ОС как /dev/urandom
или же CryptGenRandom
непосредственно в качестве источника случайных битов, но тогда вам нужно будет использовать это для реализации gmp_randstate_t
интерфейс для того, чтобы подключить его mpz_urandomm
, Я не знаю, насколько это сложно.
Если это школьное упражнение, делайте то, что говорит ваш учитель. Если это для реального приложения, используйте существующую библиотеку криптографии, такую как libtom, который поставляется со всем необходимым для генерации случайных чисел криптографического качества и выполнения вычислений Диффи-Хеллмана, его очень легко интегрировать в проект и имеет лицензию, которая позволяет интегрировать его в любой проект.
Других решений пока нет …