Анонс идеи аппаратного скремблера
Параллельно работе над Linux OnionPhone по просьбе трудящихся хочу взяться за разработку аппаратного решения для шифрованной телефонии через обычные акустические каналы со стандартной полосой 300-3000Гц (наземные телефоны, УКВ и КВ, в т.ч. SSB радиоканалы и, возможно, GSM/CDMA). Идея заключается в портировании открытого софта в подходящий DSP: низкобитрейтный кодек, софтверный модем и криптографию. Аппаратно потребуются: DSP (микроконтроллер) с АЦП/ЦАП (ШИМ) стандартной разрядности, производительностью не ниже 50 MIPS и со значительным объемом ПЗУ для кодовой книги аудиокодека, монохромный графический дисплей, подключаемый по трехпроводному SPI-интерфейсу (например, от Nokia 3310) для отображения результатов аутентификации, микроSD для хранения адресной книги (публичных ключей контактов), смарт-карта стандарта ISO7816 (например, GoldWaffer на PIC16F84+24LC16, ранее популярная для клонов сим-карт и карт платного спутникового телевидения) для хранения приватного ключа и возведения в его степень по модулю, и, возможно, внешнее ОЗУ.
В качестве голосового кодека думаю использовать или свободный Codec2, или лицензированный MELPe (стандарт NATO STANAG-4591) на битрейте 1200bps с подавителем шума NPP7, специально адаптированным для условий боя. В качестве модема – FDMDV из проекта Codec2, обеспечивающий битрейт 1450bps, быструю синхронизацию и восстановления после ошибок, устойчивый к частотным и временным сдвигам.
Хочу более подробно озвучить свои соображения по поводу криптографии: не с целью получить експертную оценку и потом ссылаться на форум, но чтобы как минимум исключить явные ляпы и, возможно, услышать конкретные советы по улучшению. Я старался не использовать совсем уж Bleeding edge, хотя все же предпочел Modern. Естественно, данный проект является исключительно образовательным (например, как основа для дипломной работы), так как шифрование гражданской радиосвязи в большинстве стран запрещено.
Задача.
В групповом попарном радиочате выполнять отбор сообщений для себя и их потоковое дешифрование с быстрой синхронизацией после потерь неизвестного количества байт. Индивидуальная аутентификация контаков друг перед другом должна выполняться с помощью уже имеющихся PGP-ключей, обеспечивать PFS и полную отрицаемость в отношении этих ключей, содержимого энергонезависимой памяти (в случае захвата устройства), а также между сеансами связи.
На первом этапе хочу сделать софтварную реализацию под Linux для i386 без использования FPU, приведенное описание протокола сделано под нее.
Планирую использовать ECDH на Бернштейновкой кривой 25519, хеширование Keccak, потоковое шифрование и PRNG с использованием Keccak Duplexing Sponge, для сидирования PRNG использовать HAVEGE (а в аппаратной реализации – RNG на шуме перехода стабилитрона).
Общее описание протокола.
При первичном включении генерируется индивидуальная долговременная ECDH-ключевая пара Aa, приватный ключ a сохраняется на диске (предполагается, что программа будет запускаться с TrueCrypt-контейнера). Публичный ECDH-ключ A (256 бит) дополняется пользовательской информацией I (256 бит) и подписывается с помощью PGP. В качестве публичного ключа используется:
PubKeyA = A | I | PGPSig{A | I}
Для идентификации используется отпечаток ключа в виде его 128-битного хеша:
IDA=H(PubKeyA)
Включение подписи в хеш блокирует UKS, характерную, например, для ранних версий OTR.
При появлении на радиоканале абоненты периодически, используя промежутки радиообмена, публикуют свои ключи, сопровождая их флагом ключа и CRC32. Последняя необходима только для исключения непреднамеренных ошибок передачи и не используется в протоколе. При размере ключа в 150-200 байт публикация займет около секунды. При получении валидного ключа он автоматически добавляется в адресную книгу. Позже в ручном режиме можно просмотреть полученные ключи, удалить лишние, проверить PGP-подпись, используя PGP PKI и пометить ключи как доверенные.
Публикация ключа полностью отрицаемая, т.к. ключ может быть переопубликован кем угодно на любом канале. Наличие ключа в адресной книге также отрицаемо, т.к. ключи принимаются и сохраняются автоматически. Например, приняв ключ на канале террористов, и затем опубликовав его на канале гомосексуалистов, можно всегда утверждать, что приняли его именно там, а ЗАС пользуетесь, т.к. стесняетесь ориентации.
Установка связи.
Для установки связи между A и B необходимо, чтобы оба участника уже имели ключи друг друга. Процедура установки связи сводится к обмену всего двумя посылками: А (инициатор) посылает запрос, а B (вызываемый) отвечает подтверждением. После этого между данными абонентами устанавливается приватный сеанс, и они могут общаться друг с другом без дополнительных согласований в пределах этого сеанса (но без PFS). Для обеспечения PFS абоненты просто переустанавливают сеанс, снова обмениваясь запросом и подтверждением.
A выполняет запрос для B:
– генерирует две DH-пары: аутентификационную и ключевую (Xx и X'x' соответственно);
– подсчитывает префикс:
P AB = H( IDA | Bx),
где IDA-собственный отпечаток, B – публичный DH-ключ получателя. Префикс усекается до 32 бит из соображений снижения битрейта. Он является только идентификатором, и даже если будет совпадение (2-32), то соединение не будет установлено из-за несовпадения ключей. Префикс полностью отрицаемый, т.к. любой может сгенерировать его, используя публичные отпечаток и DH-ключ участников.
– фиксирует таймстемп T, ограничивающий время для подбора злоумышленником и предотвращающий Replay-атаку.
– транслирует запрос в виде: P AB, T, X, X'
– добавляет в список ожидающих соединение запись IDB, T, x, x'
– удаляет слишком старые безответные записи из списка по таймстемпу.
B получает запрос от A и отвечает:
B cлушает канал и, приняв посылку с флагом запроса, сверяет таймстемп, затем "примеряет" ее к каждому контакту из адресной книги:
– однократно подсчитывает Xb, где b – собственный приватный ключ.
– для каждого абонента их адресной книги
извлекает IDn и подсчитывает Pn=H(IDn | Xb)
– при совпадении с префиксом считает, что получил запрос именно для себя предположительно от абонета n, иначе запрос адресован кому-то другому.
– аналогично генерирует две DH-пары (Yy и Y'y') и подсчитывает ответный префикс:
P BA=H( IDB | Ay),
где IDB-собственный отпечаток, A – публичный DH-ключ предполагаемого отправителя.
– транслирует ответ в виде: P BA, Y, Y'
– подсчитывает мастер-ключ данного соединения:
K=X'y'
Мастер-ключ выводится с использованием исключительно DH и не содержит материала долговременных ключей и ключей аутентификации. Это необходимое условие полной отрицаемости, в отличие от "разумной" отрицаемости, которую обеспечивают протоколы с неявной аутентификацией (например, FHMQV).
– подсчитывает аутентификаторы:
M A=H( Xb | Ay | X | Y | X' | Y' )
M B=H( Xb | Ay | X | Y | Y' | X' )
Учитывая идеальность хеширования Keccak, фактически DH-параметры мастер-ключа (X' и Y') подписываются (с перестановкой местами) общим ключом аутентификации. Это в точности соответствует протоколу SKEME, но в нем ключ аутентификации выводится с использованием протокола Abadi (обмен случайными значениями, зашифрованными публичными ключами участников), а в данном случае – с использованием протокла KEA+ (по смыслу то же, но с использованием DH-публичных ключей). SKEME обеспечивает полную отрицаемость и является доказуемо стойкой (по Кравчику). KEA+ также удовлетворяет требованиям отрицаемости, т.к. не использует непосредственой комбинации ключей A и B вне хеширования.
– инициализируется 32-битный счетчик-вектор для шифрования: С=0
– добавляет запись в список открытых соединений: IDA, T, С, K, M A, M B
A получает подтверждение от B:
А слушает канал, и приняв посылку с флагом ответа, аналогично "примеряет" ее к каждому контакту из адресной книги:
– однократно подсчитывает Ya, где a – собственный приватный ключ.
– для каждого абонента их адресной клиги извлекает IDn и подсчитывает
Pn=H(IDn | Ya)
– при совпадении с префиксом считает, что получил ответ именно для себя предположительно от абонета n, иначе ответ адресован кому-то другому.
– находит соответствующую запись в списке ожидающих соединение контактов и сверяет таймстемп получения ответа с таймстемпом отправки запроса, игнорируя ответ при слишком длинном интервале.
– подсчитывает мастер-ключ данного соединения:
K=Y'x'
– подсчитывает аутентификаторы:
M A=H( Xb | Ay | X | Y | X' | Y' )
M B=H( Xb | Ay | X | Y | Y' | X' )
– инициализируется 32-битный счетчик-вектор для шифрования С=0
– добавляет запись в список открытых соединений: IDA, T, C, K, M A, M B
– удаляет запись из списка ожидающих соединение
На данном этапе ни А, ни B пока не могут быть уверены ни в идентичности друг друга, ни в отсутствии MitM, т.к. они еще не обменялись аутентификаторами. Тем не менее они имеют общий мастер-ключ и могут начинать общение. Это исключает прерывание протокола при неудачной аутентификации, что необходимо для полной отрицаемости. Уведомление об аутентичности контакта будет скрытно выдано абоненту при приеме первой же голосовой посылки (любая передача теперь будет начинаться с аутентификатора). Также контролируется интервал времени по таймстемпу от начала протокола до получения первого аутентификатора, в случае слишком длинного интервала достоверность аутентификации снижается (т.к. злоумышленник имел время для вычислений).
Аутентификаторы также усекаются до 26 байт (этого требует низкий битрейт канала). Я старался внимательно проанализировать возможность использования коротких аутентификаторов и прише к выводу, что это допустимо в данной приложении, хотя буду рад услышать другие обоснованные мнения на этот счет и идеи.
При приеме данных с флагом голосового сообщения получатель ищет подходящий аутентификатор в списке открытых соединений. Если он там отсутствует, получатель считает, что сообщение адресовано не ему. Если аутентификатор обнаружен, и он не соответствует последнему контакту, то выводится сообщение о новом контакте в виде контактной информации из публичного ключа контакта и степени доверия, установленной ранее вручную в результате проверки PGP-подписи.
Вместе с аутентификатором в начале каждой передачи, а также с полусекундным интервалом на протяжении передачи, транслируется счетчик С (его младшие 26 бит). При приеме счетчика С его значение восстанавливается до полных 32 бит (только вперед!) и последовательность T | C | K используется для инициализации Keccak Duplexing Sponge. При получении последующих данных выжимается гамма, использующаяся для расшифровки потока. Т.к. транспорт не обеспечивает коррекцию ошибок по соображениям снижения битрейта и минимизации задержки, то регулярная реинициализация с полусекундным интервалом позволяет восстанавливать корректность расшифровки при потерях данных в случае длительной непрерывной передачи.
Также из соображений снижения битрейта и устойчивости связи аутентификация принятых данных не производится. Шнаер допускает такой подход при передаче голоса, т.к. голос сам по себе является достаточным аутентификатором. Такой же подход используется и в PGPFone Циммерманна. Голосовой кодек MELPe является военным стандартом и его рефференс-код тщательно проверен на предмет выполнения произвольного кода при подаче на вход фатальных битовых последовательностей. Любая манипуляция входными битами без знания ключа шифрования может вызвать лишь искажение голоса вплоть до получения шума, но не нарушение криптографии в целом. Преимущество данного подхода очевидно: спонтанное искажение единичных битов приведет лишь к искажению голоса, но не к полному выпадению неаутентифицированных блоков.
комментариев: 393 документов: 4 редакций: 0
Вы неверно поняли идею. Постараюсь объяснить подробно. Допустим, у нас поток символов уже выровнян на границу символа. Каждый символ несет, скажем, 7 бит информации. Наша задача – выдать блок 98 бит (14 символов), т.е. выровнять на границу блока.
Используем 11 последних бит блока как Golay-код от 12 первых бит.
Создаем массивы char data[14*2] для принятых символов, и float ber[14] для накопленных усредненных значений к-ва ошибок. Также создаем счетчик полученных символов, он же – указатель на лаг (от 0 до 13).
После получения очередного символа пишем 7 бит его значения в data по счетчику+14 (во вторую половину). Предполагаем, что это последний символ в блоке, исходя из чего, обрабатываем полученный последний символ + предыдущие 13 в массиве data как блок: корректируем, считаем к-во ошибок (оно может быть от 0 до 3), и это к-во усредняем в массиве ber[значение счетчика=лаг]:
ber[c]=err+ber[c]*0.95; //можно и с целочисленной арифметикой,
где err – к-во скорректированных ошибок в защищенных 12 битах (0-3
для Golay23).
То же самое проделываем для каждого следующего полученного символа, увеличивая значение счетчика.
При достижении счетчиком значения 14 ищем минимальное значение в массиве ber[14], и, используя найденный индекс как лаг, выдаем наиболее корректный блок из data с нужным смещением.
Затем копируем вторую половину data в первую, сбрасываем счетчик и продолжаем для следующего блока (массив ber не стираем, продолжаем усреднять).
Т.о. с каждым новым блоком значение по индексу правильного лага в ber[] становится все меньше по сравнению с другими. И единичная ошибка блока на эту тенденцию не повлияет.
Позже я навесил и другие рюшечки: сделал динамический диапазон слежения за лагами (тем самым считаю не 14 FEC, а меньше, что позволило увеличить к-во символов (уменьшить к-во битов в них) с приемлемым перфомансом, добавил автоопределение инверсии сигнала в канале (мне это было важно, т.к. использовалась полярность пульса) и т.д.
Все это реально работает, и к синхронизации претензий нет вообще. Ошибки у меня возникали из-за смещения позиции пульса кодеком посредине.
Понятно и логично. Тогда вероятность правильной синхронизации после приема первого же блока порядка 0.99, и схема будет в принципе работоспособна при BER до нескольких процентов.
Строго говоря, следовало бы усреднять не количество ошибок в данной позиции, а вероятность, что данная позиция является правильной. Это не вполне одно и то же; хотя, думаю, нет особой разницы в рамках задачи.
Это можно было бы сделать, модифицировав тот же FEC код, который используется для синхронизации. Чтобы был не инвариантен к инверсии.
Насколько я понимаю, позиция пульса задается непосредственно каким-то количеством бит? Тогда можно разделить биты на "сильные" и "слабые" по BER. К слабым битам применить FEC.
http://www.zas-comm.ru
комментариев: 393 документов: 4 редакций: 0
Приятно общаться с понимающим человеком. Именно так и сделал. По достижению какого-то минимума усредненной ошибки фиксирую данное состояние как текущее, инвертирую сигнал на входе и не считаю FEC для противоположного состояния.
Да, я пробовал разные варианты. Например, так: фрейм 18+18 сэмплов, в нем два пульса, каждый в своей половине в 6-ти возможных позициях. Т.е. имеем 36 вариантов, это 5 бит. Плюс по биту на полярность каждого пульса. Т.е. 7 бит на 36 сэмплов, 1555 bps. Очень хорошая схема для GSM FR. Выравнивание на позицию пульса плюс/минус один – процедурой GridSelection, а затем выравнивание на 3 пульса – способом, описанным выше (по FEC).
Или другой вариант (я его пытался пихать через AMR475): один пульс на каждые 40 сэмплов в 8-ми возможных позициях (каждые 5 сэмплов). Пульс широкий (в три сэмпла, боковые по 0.5 от центрального). 800bps, если учитывать знак пульса. Проблема в том, что AMR-кодек посредине "размазывает" пульс, добавляя к нему след из синусоид. Искажается как знак, так и позиция. Кроме того, появляются артефакты в неожиданных позициях. Я пробовал различные способы детектирования позиции, но ошибки все равно значительные.
Разнородные биты – полярность пульса (1 бит) и позиция. Но вот какие из них "слабее", непонятно. Статистически явной закономерности так просто обнаружить не удалось.
Чем более кодек приспособлен для речи, тем более он искажает сигналы, не похожие на речь. На импульсы накладывается реакция LPC фильтра. Можно попробовать компенсировать эту реакцию, представив ее как возбуждение LPC фильтра исходным импульсом. Выделив "звон" синусоид, рассчитать по нему коэффициенты фильтра. Отсюда найти исходное положение и величину возбуждающего импульcа.
Можно считать по максимуму правдоподобия: сделать на приемной стороне модель канала с таким же кодеком; пробовать разные позиции импульсов, найти позицию, в которой сигнал получается наиболее близким к принятому.
Такой приниматель оптимален; но возможно неприемлем по затратам MIPS.
http://www.zas-comm.ru
комментариев: 393 документов: 4 редакций: 0
Я и сам думал использовать демодулятор на основе AMR475 для прохода AMR475. Но проблема в том, что кодек посредине не синхронизирован по границам символов, более того, из-за неточности частоты дискретизации модулятора и системы GSM сдвиг постоянно "плывет".
В идеале сделать то же, что делает кодек: провести LPC-анализ фрейма, применить найденные коэффициенты в фильтре, выделить резидуальный сигнал, и в нем искать возбуждающий пульс. Пробовал, используя код GSM FR. Все хорошо, пока нет кодека посредине.
Еще есть идея. Раз кодек дописывает "хвост" синусоид к пульсу, основываясь на своей логике (хотя его там не должно быть, т.к. исходный сигнал, по идее, безголосый), то, может, есть смысл самому в модуляторе добавить эти затухаемые синусоидальные хвосты к пульсам. Так поведение кодека будет гораздо предсказуемее, и легче колдовать над алгоритмом демодулятора. Кроме того, если повезет, то частотой синусоиды в хвосте можно еще и пару бит кодить.
Кодек (типа AMR или любой другой вариант CELP) пытается апроксимировать входной сигнал набором имеющихся у него вариантов кодирования. Апроксимация по психоакустической модели; возможности кодирования оптимизированы под статистику речевого сигнала. Cоответственно, импульсы будут преобразованы в некие речеподобные всплески. Причем, кодирование будет зависеть от предыстории. Cамое простое решение в этом случае – декодирование по принципу максимума правдоподобия. Раз импульс кодируется во всплеск, набрать библиотеку таких всплесков для разного взаимного положения импульсов. На приеме коррелировать сигнал с библиотекой, искать максимум корреляции, т.е. найти исходный сигнал. Такой приемник оптимален, но может быть труднореализуем по затратам памяти и MIPS.
Более правильный путь – исходно использовать речеподобные символы; про то уже писал. Cмотрите как в кодеках передаются параметры pitch, gain и innovation раз в 5ms и параметры LPC раз в 20ms. Соответственно сконструировать сигнал и оптимальный приемник для этого сигнала. Продумать схему FEC. Довольно много работы для квалифицированного специалиста, научная ценность = 0, практическая полезность под вопросом.
http://www.zas-comm.ru
комментариев: 393 документов: 4 редакций: 0
Книгу я пока не читал, но описание работы ACELP-кодеков (семейство AMR) зачитал до дыр и вник в каждую процедуру, что и Вам советую сделать. Т.е. я разобрался, как обрабатывается речевой сигнал на этапе кодирования, формируется адаптивная кодовая книга, как производится поиск, и как устроена фиксированная кодовая книга. Посмотрел все в референс-коде на С. Это гораздо более тонкие механизмы, чем
Это совсем другой путь, символьный алфавит из работ Сапожникова. Мы обсуждаем путь Kondoz at all. Принцип модема Kondoz не является универсальным, а использует инженеринг конкретного кодека (в оригинале – GSM EFR=AMR122) для достижения результата. И задача – сделать то же для AMR475, жертвуя битрейтом.
Это совсем другие вопросы, и частично я с Вами согласен.
В отличие от JackPair, реально работающие НАТО-вские системы p2p кодирования голосовой GSM-связи используют CSD
(см. например презенташку Fabio Pietrosanti,) и это можно сделать за месяц, подключив в той же RaspberryPi недоверяемый китайский модуль Quectel M66 тремя проводами (RX, TX, корпус) через UART2USB переходник (например, FTDI).
Таким образом, имеем полную гарантию, что из модуля никуда никто не проникнет в систему, а на модуль будет подаваться уже криптоданные для паблика. Тем более, имеется доступ к расширенному инженерному меню (можно видеть соты, силу их сигнала, считать расстояния, лочить частоту и соту, выбирать аудиокодек; и даже недокументированные штуки (если еще не выпилили – менять хоть на лету IMEI и Serial командами через тот же трехпроводный интерфейс).
Всегда пожалуйста. Конкретные вопросы welcome.
Вы разобрались в "как" на примере частного случая. Осталось разобраться в главном: почему и зачем так делается; каковы свойства используемых процедур. Заодно изучить принципы оптимального приема, методы синхронизации, теорию помехоустойчивого кодирования, и уметь делать в реальной практике. Ничего особенного, просто еще одно ремесло.
Не существует разных путей чьего-то имени. Существуют технические решения разной степени сложности и оптимальности.
Предлагается математически корректное квазиоптимальное решение. Чем не устраивает?
Какие проблемы? Вы же во всем разобрались и вникли :)
Разные CELP-кодеки устроены по одному и тому же принципу; отличие в деталях. Поэтому сигнал в таких кодеках преобразуется примерно одинаковым образом. Очевидно что если информация проходит через низкобитрейтный CELP, то через высокобитрейтный пройдет тем более. GSM-FR вообще халява, а не кодек. Почти что прямая отцифровка.
Если есть доступ к цифровому каналу, задача тривиальна.
http://www.zas-comm.ru
Ни чуть не более удивительно, чем наблюдать, как вы лезете в криптографию с собственным кустарным шифром, не зная основ современной криптографии (хотя бы на уровне книжки Bellare & Rogaway). Видимо, там где вы изучали кодеки, крипто не учат, бывший СССР всё ж таки, тяжёлое наследение.
:) Верно подмечено.
Однако cлабый примитив можно усилить перестраховочными методами и пр., а плохому модему костыли не приставишь.
Увы, не вижу здесь людей, компетентных в криптографии. Даже детский шифр сломать оказалось слабо, не говоря уж об аргументированных ответах или содержательной критике.
http://www.zas-comm.ru
Простым образом нельзя (если вы полагаетесь на научный и доказательный подход, а не на криптофричество и любительство).
Современные криптографы не занимаются практическим криптоанализом.
Так толсто, впрочем, как всегда. Даннинг-Крюгер во всей красе. Даже боюсь спросить, кого вы считаете компетентным в криптографии. Мнение в FAQ — это как бы консолидированное мнение научного сообщества. Наверно, Шамир для вас был бы тоже некомпетентен.
Скажите хоть слово по делу, для разнообразия.
Тех, кто может показать, что неправильно, обьяснить, почему, и предложить, как сделать лучше. Разработать свой алгоритм, превосходящий другие. Указать на силу или слабость конструкции. Хотя бы на любительском уровне понимания.
Криптография это практика. Должны быть осязаемые результаты.
Читая книжки и рассматривая разные конструкции, у меня сложилось впечатление, что большинство практически применяемых шифров основаны на отфонарных решениях. Видны заплаты против известных методов анализа и некоторые математические оценки; но настоящей теории мало. Это так?
Unknown в т.ч. и это для вас делал, но вы же всё равно пишите
Серьёзных рекомендуемых шифров сейчас — пара штук, это TwoFish и Rijndael. По обоим есть серьёзные работы от их авторов, можно почитать.
Под настоящей теорией каждый своё понимает. Стараются основываться на теории сложности в той мере, в какой только можно.
комментариев: 393 документов: 4 редакций: 0
To Sfinx:
Нашел время вникнуть в работу Сапожникова,
ссылку на которую любезно предоставил Гость, за что еще раз спасибо! Вроде как в ней содержится ответ на Ваш вопрос. Как считаете, стоит ли попробовать сгенерировать алфавит? А Вы будете пробовать?
Для этого нужны годы на исследования вашей поделки. Кто их будет тратить?
Меньшинство из криптографов разрабатывает свои алгоритмы. Об этом написано в FAQ.
Тут не бывает любительского уровня понимания. Есть его присутствие (годы работы, вникание в тему, профильное образование и т.д.) и отсутствие.
В этом и состоит корень ваших заблуждений. Криптография — это пипец какая сложная теория. Поздно делать шифры на коленке из любительских соображений — это было позволительно году так в 1950-ом. Сейчас этим занимаются специально обученные люди.
В авиастроении так же. Можно на любительском уровне сказать, что можно улучшить в Boeing 737? Да так, чтоб сразу это пустить на production без дополнительных проверок, тестов, сертификаций «специально обученными людьми»? А если б можно было, полетели бы вы на самолёте собственной модификации? Но даже тут проще: однажды ваш самолёт грохнется, и всё ваше любительство вылезет наружу, а в крипто — это когда самолёты, казалось бы, летают, а через 20 лет вдруг выясняется, что все они упали, задним числом причём. Современное крипто потому такое и сложное, что страхует от будущих успехов в криптоанализе по-максимуму, а не оперирует только тем, что уже имеется.