13.7. Подписи
263
Самое простое решение — использовать псевдослучайное отображение,
которое будет “растягивать”
h
(
m
)
, отображая его на случайное число
s
из
диапазона
0
, . . . , n
−
1
. Затем подпись сообщения
m
будет вычисляться как
s
1
/e
(mod
n
)
. Отображение
h
(
m
)
на число по модулю
n
выполнить довольно
сложно (см. раздел 10.8). В нашем случае можно упростить проблему, отобра-
жая
h
(
m
)
на случайный элемент из диапазона
0
, . . . ,
2
k
−
1
, где
k
— наибольшее
число, такое, что
2
k
< n
. Числа из диапазона
0
, . . . ,
2
k
−
1
генерировать гораз-
до проще, поскольку для этого достаточно сгенерировать лишь
k
случайных
бит. В нашем конкретном случае подобное решение можно использовать без
опаски, однако не применяйте его повсеместно. Существует множество ситу-
аций, в которых подобное упрощение разрушит безопасность всей системы.
Мы будем использовать генератор псевдослучайных чисел Fortuna, опи-
санный в главе 10, “Генерация случайных чисел”. Многие разработчики ис-
пользуют
функцию хэширования
h
, чтобы построить небольшой генератор
случайных чисел, предназначенный специально для этой цели, но у нас уже
есть хороший генератор. Кроме того, нам все равно понадобится генератор
псевдослучайных чисел, чтобы выбирать простые числа для генерации клю-
чей RSA.
Для реализации схемы цифровых подписей понадобятся три функции: од-
на, чтобы отобразить сообщение
m
на
s
, вторая, чтобы подписать сообщение,
и третья, чтобы проверить подпись.
функция
MsgToRSANumber
вход:
n
Открытый ключ RSA, модуль, по которому выполняются
вычисления.
m
Сообщение, которое должно быть преобразовано в число по
модулю
n
.
выход:
s
Число по модулю
n
.
Создадим новый генератор псевдослучайных чисел.
G ←
InitializeGenerator
()
Обновим начальное число генератора с помощью хэш-кода сообщения.
ReSeed
(
G
,
SHA
d
−
256(
m
))
Вычислим
k
.
k
← b
log
2
n
c
x
←
PseudoRandomData
(
G
,
d
k/
8
e
)
Как обычно, мы рассматриваем строку байтов
x
как целое число, пред-
ставленное в формате, в котором наименее значимый байт запи-
сывается первым. Операция взятия по модулю будет выполняться
путем простого применения операции AND к последнему байту
x
.
s
←
x
mod 2
k