16.1. Арифметика больших чисел
303
ющие пути кода, но и перебрать все граничные условия. Например, если у нас
есть тест для
a < b
, мы должны протестировать этот же фрагмент кода для
a
=
b
−
1
,
a
=
b
и
a
=
b
+ 1
(разумеется, если эти условия вообще могут быть
достигнуты).
И без того нелегкое положение еще более усложняется с появлением опти-
мизации. Поскольку упомянутые выше
функции создают узкое место в произ-
водительности системы, их всячески пытаются оптимизировать. Это, в свою
очередь, приводит к появлению множества частных случаев, путей кода и т.п.,
что еще более затрудняет тестирование.
Простая арифметическая ошибка может иметь поистине катастрофиче-
ские последствия для безопасности системы. Вот небольшой пример. Пусть
в код, вычисляющий значение цифровой подписи RSA, вкралась небольшая
ошибка, которая дает неверный результат при возведении в степень по моду-
лю
p
, но верный при возведении в степень по модулю
q
. (Предположим также,
что для ускорения этой процедуры применяются CRT-представления.) Под-
писывая свои сообщения, пользователь А вместо верной цифровой подписи
σ
отсылает подпись
σ
+
kq
, где
k
— некоторое число. (Чтобы результат, полу-
ченный пользователем А, был верным по модулю
q
, но неверным по модулю
p
, он должен иметь вид
σ
+
kq
.) Злоумышленник знает
σ
3
mod
n
— число, из
которого пользователь А извлекает корень третьей степени и которое зависит
только от сообщения. Но разность
(
σ
+
kq
)
3
−
σ
3
кратна
q
. Найдя наибольший
общий делитель этой разности и числа
n
, злоумышленник узнает
q
и таким
образом сможет разложить число
n
на простые множители. При одной мысли
об этом нас охватывает ужас!
Вы спросите, что же в таком случае делать? Во-первых, не пытайтесь
реализовать собственную библиотеку для работы с большими числами. Вос-
пользуйтесь какой-нибудь существующей библиотекой. Если вам некуда де-
вать свое время, лучше потратьте его на то, чтобы разобраться в существу-
ющей библиотеке и хорошенько ее протестировать. Во-вторых, разработайте
действительно хорошие тесты для своей библиотеки. Убедитесь, что вы про-
тестировали все возможные пути кода. В-третьих, вставьте дополнительные
тесты в само приложение. Для этого можно воспользоваться несколькими
методами.
16.1.1
Вупинг
Метод, описанный в этом разделе, имеет довольно непривычное назва-
ние —
вупинг (wooping)
. Во время одного жаркого спора между Дэвидом
Шомом (David Chaum) и Юрьеном Босом (Jurjen Bos) срочно понадобилось
придумать имя для специальной верификационной переменной. В пылу деба-