Nostr WoT
NostrNIPEncryption

NIP-44 снимает ограничение в 65535 байт

Каждый payload NIP-44 нёс 2-байтовый префикс длины, ограничивающий открытый текст 65535 байтами. Изменение, объединённое 28 июня 2026 года, добавляет префикс переменной длины, поднимающий потолок до чуть менее 4 ГБ, без смены версии и без поломки чего-либо уже развёрнутого.

Nostr WoT Newsroom

Статья4 min read

Материал подготовлен редакцией Nostr WoT на основе указанных первоисточников и опубликован автоматически, без индивидуальной проверки человеком.

NIP-44 снимает ограничение в 65535 байт

NIP-44, схема шифрования, на которой построена большая часть приватного обмена сообщениями в Nostr, включая упакованные в подарочную обёртку личные сообщения из NIP-17. С момента появления у него был жёсткий потолок на то, сколько можно зашифровать в одном payload: 65535 байт. 28 июня 2026 года изменение от fiatjaf сняло этот потолок, и стоит точно разобраться, что именно изменилось.

Откуда взялось старое ограничение

Потолок в 65535 байт никогда не был осознанным политическим решением. Он был прямым следствием того, как NIP-44 дополняет открытый текст перед шифрованием. Формат дополнения хранил длину открытого текста как первые два байта дополненного блока, беззнаковое 16-битное целое число в порядке big-endian, u16. u16 может представлять только значения от 0 до 65535, поэтому всё большее просто не могло быть выражено в префиксе длины, независимо от того, мог ли базовый шифр справиться с этим иначе. Собственный раздел констант спецификации прямо это указывал: max_plaintext_size составлял 65535, "64 КБ минус 1".

Это же предположение о 2 байтах распространялось дальше. Правила проверки NIP-44 для payload, закодированного в base64, и для декодированной байтовой строки были проверками диапазона, а не только минимальной длины: допустимый base64 payload должен был находиться в диапазоне от 132 до 87472 символов, а декодированное сообщение от 99 до 65603 байт. Оба верхних предела существовали исключительно потому, что более крупное сообщение было структурно невозможным при 2-байтовом префиксе.

Что делает новая схема

Объединённое изменение сохраняет 2-байтовый префикс для всего, что в него ещё помещается, и добавляет второй, более крупный формат для того, что не помещается. Правило основано на пороге в 65536 байт:

  • Если длина открытого текста меньше 65536 байт, префикс остаётся 2-байтовым, точно таким же, как старый формат u16: [plaintext_length: u16][plaintext][zero_bytes].
  • Если длина открытого текста составляет 65536 байт или больше, префикс становится 6-байтовым: два нулевых байта, за которыми следует u32 в big-endian, [0x00, 0x00][plaintext_length: u32][plaintext][zero_bytes].

Два нулевых байта в начале расширенного префикса не являются заполнением ради самого заполнения, это сигнал. Допустимый открытый текст всегда содержит хотя бы 1 байт, поэтому значение u16, равное ровно нулю, никогда не могло встретиться в старом формате. Декодирование становится однозначным: прочитать первые 2 байта как u16; если они нулевые, прочитать следующие 4 байта как u32 для получения реальной длины; если они не нулевые, это значение и есть длина, а префикс всегда был 2-байтовым.

max_plaintext_size меняется с 65535 на 4 294 967 295, то есть 2^32 минус 1, около 4 ГБ. Проверки диапазона для длины payload в base64 и декодированной длины полностью теряют верхний предел и становятся проверками только минимума: не менее 132 символов base64, не менее 99 декодированных байт, без потолка.

Спецификация также получила новый раздел "соображения по реализации". Он предписывает реализациям устанавливать собственный максимальный размер payload, подходящий их платформе, и отклонять слишком большие payload заранее, до декодирования base64, специально для предотвращения отказа в обслуживании при попытке декодировать огромные входные данные. Он отмечает, что расшифровка может потребовать в несколько раз больше рабочей памяти, чем размер payload, что системы на базе JVM ограничивают непрерывные массивы примерно 2 ГБ, что значительно ниже нового теоретического потолка в 4 ГБ, и что вычисления дополненной длины теперь могут достигать 2^32, поэтому реализациям нужна 64-битная арифметика для корректного расчёта дополнения.

На границе были добавлены новые тестовые векторы, проверяющие открытый текст длиной 65535 байт против текста длиной 65536 байт, чтобы подтвердить, что реализации переключают формат префикса точно в нужной точке.

Та же версия, без смены версии

Это по-прежнему NIP-44 версии 2. Изменение не затронуло байт версии и не добавило новый номер версии для согласования. Оно расширяет существующий формат дополнения v2 вторым, более длинным префиксом, который активируется только когда сообщение превышает 65536 байт. Декодировщик версии 2, обновлённый под этот NIP, обрабатывает и старые, и новые сообщения под одним и тем же идентификатором версии.

Обратная совместимость, по словам самого автора PR

В тексте PR прямо сказано: "This is backwards-compatible and no one has to change anything if they do not care about bigger messages" ("Это обратно совместимо, и никому не нужно ничего менять, если большие сообщения им не важны"). Для распространённого случая ничего не меняется. Любой открытый текст короче 65536 байт кодируется точно тем же 2-байтовым префиксом, что и раньше, байт в байт. Реализациям, которым никогда не нужно отправлять что-то большее, обновляться вообще не требуется.

В тексте PR также назван конкретный случай, послуживший поводом для изменения: "The only reasonable case where this necessity has shown up so far was signing of big kind:3 lists via NIP-46" ("Единственный разумный случай, в котором эта необходимость до сих пор проявлялась, это подписание больших списков kind:3 через NIP-46"). Именно большие списки контактов kind:3, отправляемые через удалённую подпись NIP-46, упирались в старый потолок.

NIP-44 лежит в основе шифрования личных сообщений в Nostr, поэтому ограничение на размер открытого текста напрямую ограничивает то, что может нести одно зашифрованное сообщение. Его повышение не затрагивает ни то, как выводится ключ разговора, ни то, как работает шифрование ChaCha20, ни то, как вычисляется MAC. Меняется лишь то, что помещается в одно сообщение.

Источники

Каждое утверждение в этом материале ссылается на первоисточник.

  1. allow NIP-44 to encrypt more than 65535 bytes — nostr-protocol/nips (28 июня 2026 г.)

Ещё от редакции

Stay Updated

Get the latest on new features, trust assertions, and services integration as they ship.

No spam, ever. Unsubscribe anytime.