Nostr WoT
NostrNIPEncryption

NIP-44 elimina o limite de 65535 bytes

Todo payload do NIP-44 carregava um prefixo de comprimento de 2 bytes que limita o texto plano a 65535 bytes. Uma mudança mesclada em 28 de junho de 2026 adiciona um prefixo de comprimento variável que eleva o teto para pouco menos de 4 GB, sem mudar de versão e sem quebrar nada já em produção.

Nostr WoT Newsroom

Matéria5 min read

Elaborado pela Redação da Nostr WoT a partir das fontes primárias citadas, e publicado automaticamente sem revisão humana individual.

NIP-44 elimina o limite de 65535 bytes

O NIP-44 é o esquema de criptografia sobre o qual a maior parte da mensagem privada da Nostr é construída, incluindo as mensagens diretas embrulhadas para presente do NIP-17. Desde que foi introduzido, ele tinha um teto fixo para quanto se pode criptografar em um único payload: 65535 bytes. Em 28 de junho de 2026, uma mudança de fiatjaf removeu esse teto, e vale a pena ser preciso sobre o que exatamente mudou.

De onde vinha o limite antigo

O teto de 65535 bytes nunca foi uma decisão deliberada de política. Foi consequência direta de como o NIP-44 preenche o texto plano com padding antes de criptografá-lo. O formato de padding armazenava o comprimento do texto plano como os primeiros dois bytes do blob preenchido, um inteiro sem sinal de 16 bits em big-endian, u16. Um u16 só consegue representar valores de 0 a 65535, então qualquer coisa maior simplesmente não podia ser expressa no prefixo de comprimento, independente de a cifra subjacente conseguir lidar com isso ou não. A própria seção de constantes da especificação deixava isso claro: max_plaintext_size era 65535, "64kB menos 1".

Essa mesma premissa de 2 bytes se propagou para fora. As regras de validação do NIP-44 sobre o payload codificado em base64 e sobre a string de bytes decodificada eram ambas checagens de intervalo, não apenas de comprimento mínimo: um payload base64 válido tinha que ficar entre 132 e 87472 caracteres, e uma mensagem decodificada válida entre 99 e 65603 bytes. Os dois limites superiores existiam apenas porque uma mensagem maior era estruturalmente impossível sob o prefixo de 2 bytes.

O que o novo esquema faz

A mudança mesclada mantém o prefixo de 2 bytes para tudo que ainda cabe nele, e adiciona um segundo formato, maior, para o que não cabe. A regra é um limiar em 65536 bytes:

  • Se o comprimento do texto plano for menor que 65536 bytes, o prefixo continua sendo de 2 bytes, exatamente o formato u16 antigo: [plaintext_length: u16][plaintext][zero_bytes].
  • Se o comprimento do texto plano for 65536 bytes ou mais, o prefixo passa a ter 6 bytes: dois bytes zerados seguidos de um u32 em big-endian, [0x00, 0x00][plaintext_length: u32][plaintext][zero_bytes].

Os dois bytes zerados no início do prefixo estendido não são preenchimento por si só, são o sinal. Um texto plano válido sempre tem pelo menos 1 byte, então um valor u16 exatamente zero nunca poderia ocorrer no formato antigo. Decodificar fica então inequívoco: ler os primeiros 2 bytes como u16; se forem zero, ler os próximos 4 bytes como u32 para obter o comprimento real; se não forem zero, esse valor é o comprimento e o prefixo sempre foi de 2 bytes.

max_plaintext_size passa de 65535 para 4.294.967.295, que é 2^32 menos 1, cerca de 4 GB. As checagens de intervalo sobre o comprimento do payload em base64 e decodificado perdem completamente seu limite superior e passam a ser checagens só de mínimo: pelo menos 132 caracteres base64, pelo menos 99 bytes decodificados, sem teto.

A especificação também ganhou uma nova seção de "considerações de implementação". Ela instrui as implementações a impor seu próprio tamanho máximo de payload adequado à sua plataforma, e a rejeitar payloads grandes demais cedo, antes da decodificação base64, especificamente para evitar negação de serviço ao tentar decodificar entradas enormes. Ela aponta que a descriptografia pode precisar de várias vezes o tamanho do payload em memória de trabalho, que sistemas baseados em JVM limitam arrays contíguos a cerca de 2 GB, bem abaixo do novo teto teórico de 4 GB, e que os cálculos de comprimento preenchido agora podem chegar a 2^32, então as implementações precisam de aritmética de 64 bits para calcular o padding corretamente.

Novos vetores de teste foram adicionados no limite, testando um texto plano de 65535 bytes contra um de 65536 bytes, para confirmar que as implementações trocam corretamente de formato de prefixo exatamente no ponto certo.

Mesma versão, sem mudança de versão

Isso continua sendo NIP-44 versão 2. A mudança não tocou no byte de versão nem adicionou um novo número de versão para negociar. Ela estende o formato de padding v2 existente com um segundo comprimento de prefixo que só é ativado quando a mensagem ultrapassa 65536 bytes. Um decodificador de versão 2 que foi atualizado para este NIP lida tanto com mensagens antigas quanto novas sob o mesmo identificador de versão.

Retrocompatível, segundo o próprio autor da PR

O corpo da PR afirma claramente: "This is backwards-compatible and no one has to change anything if they do not care about bigger messages" ("Isso é retrocompatível e ninguém precisa mudar nada se não se importar com mensagens maiores"). Nada muda para o caso comum. Qualquer texto plano com menos de 65536 bytes é codificado com exatamente o mesmo prefixo de 2 bytes de antes, byte a byte. Implementações que nunca precisam enviar algo maior não precisam ser atualizadas de forma alguma.

O corpo da PR também nomeia o caso concreto que motivou a mudança: "The only reasonable case where this necessity has shown up so far was signing of big kind:3 lists via NIP-46" ("O único caso razoável em que essa necessidade apareceu até agora foi a assinatura de listas grandes de kind:3 via NIP-46"). Listas de contatos kind:3 grandes, enviadas via a assinatura remota do NIP-46, eram a carga de trabalho que esbarrava no teto antigo.

O NIP-44 é a base da criptografia das mensagens diretas na Nostr, então um limite no tamanho do texto plano é um limite no que uma única mensagem criptografada pode carregar. Elevá-lo não toca em como a chave de conversação é derivada, como funciona a criptografia ChaCha20, nem em como o MAC é calculado. Muda o que cabe em uma mensagem.

Fontes

Toda afirmação nesta matéria tem um link para uma fonte primária.

  1. allow NIP-44 to encrypt more than 65535 bytes — nostr-protocol/nips (28 de junho de 2026)

Stay Updated

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

No spam, ever. Unsubscribe anytime.