Вывожу age из использования

Что: 48a14b4730b560bda67562f33bae7d62fa795247

Когда: 2025-02-18 11:20:39+03:00

Темы: crypto keks

Вывожу age из использования

В 4eed9f47294d277e84f8ba1451b1b4ced04a09de упоминал, что начал делать
аналог CMS EnvelopedData контейнера. Всё уже настолько устаканилось, что
бОльшую часть всего перешифровал в cm/encrypted контейнеры.

Изначально у меня вовсю использовались слова типа "pki" и сертификаты.
Выпилил любое упоминание PKI, решив назвать все эти криптографические
форматы "cm"-ом -- cryptographic messages. И коротко и не пересекается с
чем-то другим распространённым. Сертификаты заменил просто на публичные
ключи. У которых, как и в случае с PGP, могут быть подписи, не без этого.

ChaPoly шифрование распараллелил, аналогично как делал в реализации на
основе деревьев Меркла (f77b37849893c17724125acc62916d01521e363d). Всё
равно до сих пор не понимаю где затык, но утилизировать все ядра не
выходит -- 2.5+GiB/sec потолок, хотя он достигается на 3-4 потоках
шифрования уже, половина ядер остаются у меня не использованными.

Чтобы рандомизировать шифрование, на всякий пожарный, решил nonce для
ChaPoly делать не просто счётчиком, но подмешивать в него неизвестное
злоумышленнику значение, как это делается в TLS 1.3.

Причесал работу с HKDF-ом, ибо где-то его Extract шаг не нужен, где-то
нужен. В целом зоопарк стал более упрощённым. ChaPoly для DEM-а не
отличается теперь от ChaPoly применяемом в KEM-ах (для key wrapping).

Доработал утилиты cmkeytool, cmenctool, cmsigtool, cmhshtool для более
удобной интерактивной работы с человеком. Собственно, их и применяю уже
для своих нужд, радуясь огромной скорости работы без бутылочного
горлышка в виде одного ядра.

Обнаружил, что вообще нет ни BLAKE3 реализаций на Си, ни BLAKE2
распараллеленных. Ни ChaPoly распараллеленного не смог найти (возможно
оно только в составе более сложного софта). Такое впечатление, что
распараллеливание толком никому не нужно и все удовлетворяются
скоростями на одном ядре. Но ChaPoly у меня даже до GiB/sec не
дотягивает. Аппаратно ускоренный AES-OCB в GnuPG вроде тоже что-то около
GiB/sec был, как и BLAKE2b. Это конечно относительно не мало, но всё же
SSD диски во много раз быстрее, как и суммарная производительность всех
ядер процессора. Понимаю что parallel код сложнее устроен, но он же
стоит того. А вот нифига свободных и открытых реализаций не видно, кроме
как на Rust попадаются.

Добавил возможность шифровать приватные ключи тем же самым cm/encrypted
контейнером но с применением KEM-а на основе парольной фразы. И
прозрачно использовать такие ключи при дешифровании. Типа весь основной
функционал age повторил удобный.

А ещё в KEKS появился новый тип данных: MAGIC. 16-байтная строчка
начинающаяся с "KEKS". "K" является тэгом, не используемый прежде
codepoint. 12 байт произвольных данных можно засунуть в неё.
Предполагается, что MAGIC будет просто добавляться в начало файла, чтобы
хоть как-то намекать на используемый в нём тип данных. Ведь ни в ASN.1,
ни в JSON невозможно это легко и просто понять. В ASN.1 любят делать
контейнеры типа {"type": "SignedData", "data": ...}, но с этим не очень
удобно работать если хочется делать аналог json.Unmarshal -- оно всё
загрузит в память. А MAGIC можно потоково декодировать просто как один
единственный KEKS-атом, а дальше продолжить чтение из io.Reader.

И для удобства использования и в cm/signed и в cm/encrypted применяется
BLOB вне основной структуры. В случае с cm/signed:
    MAGIC(cm/signed) || cm-signed-prehash || BLOB(detached-data) || cm-signed
и подписывается:
    [detached-data] || /load || sig-tbs
всё это позволяет не делать потоковое декодирование данных, а частями
засовывать в io.Reader/hash.Hash и подобные. KEKS позволяет потоково
работать, как и сама Go реализация, но это не так удобно и просто как
сделать .Unmarshal. В случае с cm/encrypted:
    MAGIC(cm/encrypted) || cm-encrypted || BLOB(encrypted-data)

Для себя применяю (d0120e47839413c5e3a04c9c6e31bab5f3996de9) Classic
McEliece в качестве KEM-а (не считая Balloon-BLAKE2b для шифрования по
парольной фразе).

А ещё обнаружил, что в http://libpqcrypto.org/command.html софте от DJB
вовсю используются не только stdout файловые дескрипторы. В моём
cmenctool я один из таких дополнительных "файлов" использовал для вывода
bind значения (сейчас его не стало). А в libpqcrypto они вообще
используются вовсю для передачи и приватных и публичных ключей. Чем
дальше, тем больше у меня появляется схожих идей и ещё больше одобрения
того как делается DJB софт.

комментарий 0:

From: kmeaw
Date: 2025-02-19 13:15:32Z

> А ещё в KEKS появился новый тип данных: MAGIC. 16-байтная строчка
> начинающаяся с "KEKS". "K" является тэгом, не используемый прежде
> codepoint. 12 байт произвольных данных можно засунуть в неё.
> Предполагается, что MAGIC будет просто добавляться в начало файла,
> чтобы хоть как-то намекать на используемый в нём тип данных.

Можем быть чуть-чуть расширить константу, чтобы она указывала на
DNS-имя или даже URL? Тогда человек, никогда ранее не слышавший про
KEKS, сможет узнать про него.

А остальные (16-n) байт можно потратить на какую-нибудь хеш-функцию,
чтобы указать на конкретный раздел в спецификации.

Например, MAGIC(cm/signed)-> "KEKS.info/"||HEX(BLAKE2b("cm/signed"))||LF
                          -> "KEKS.info/1d939\n"

Или выбрать n поменьше (KEKS.ru?), чтобы туда без хеширования payload
влез.

Недостаток тут, конечно, в том, что какая-то другая организация будет
это имя контролировать.

комментарий 1:

From: Sergey Matveev
Date: 2025-02-19 13:38:11Z


>Можем быть чуть-чуть расширить константу, чтобы она указывала на
>DNS-имя или даже URL? Тогда человек, никогда ранее не слышавший про
>KEKS, сможет узнать про него.

Эти мысли посещали меня. Я думал о теме URL как замене OID-ов (из мира
ASN.1) и текстовых идентификаторов. Но всё скатилось в то, что, верно
замечено, домен это сущность контролируемая кем-то другим и с ними всё
не просто в наше время. Поэтому я забил на идею использования URL-ов для
этих целей. Но и ничто не мешает, само собой, в качестве алгоритма
внутри структур указывать строчки в виде URL-ов.

>Например, MAGIC(cm/signed)-> "KEKS.info/"||HEX(BLAKE2b("cm/signed"))||LF
>-> "KEKS.info/1d939\n"

Вот почти точь-в-точь такие же мысли и меня посещали. Но... мы
привязываемся к доменам и всякой бюрократии и зависимости от геополитики.
В принципе то потеря домена не сломает конечно ничего, а просто
останется некрасивый рудимент в формате в виде "KEKS.info"/whatever
константы уже ничего не значащей.

>Или выбрать n поменьше (KEKS.ru?), чтобы туда без хеширования payload
>влез.

Конкретно .ru без Госуслуг уже вроде и не зарегистрировать. А их я по
множеству причин отказываюсь "заводить". Куча других зарубежных доменов
(регистраторов): могут по национальному признаку "отжать" домен или по
каким-то другим дурным причинам (как я когда-то потерял контроль на
несколько дней над своими доменами из-за Gandi.net). Наши регистраторы
могут решить вообще для всех доменов форсировать использование
Госуслуг/whatever, а зарубежным нет вменяемых способов оплатить. Всё
сложно :-). Поэтому эти идеи с доменом/URL-ом я похоронил.