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