Nostr WoT
NostrNIPEncryption

NIP-44 elimina el límite de 65535 bytes

Cada payload de NIP-44 ha llevado un prefijo de longitud de 2 bytes que limita el texto plano a 65535 bytes. Un cambio fusionado el 28 de junio de 2026 añade un prefijo de longitud variable que eleva el techo a poco menos de 4 GB, sin cambiar de versión y sin romper nada ya desplegado.

Nostr WoT Newsroom

Artículo5 min read

Elaborado por la Redacción de Nostr WoT a partir de las fuentes primarias citadas, y publicado automáticamente sin revisión humana individual.

NIP-44 elimina el límite de 65535 bytes

El NIP-44 es el esquema de cifrado sobre el que está construida la mayor parte de la mensajería privada de Nostr, incluidos los mensajes directos envueltos en regalo del NIP-17. Desde que se introdujo, ha tenido un techo fijo sobre cuánto se puede cifrar en un solo payload: 65535 bytes. El 28 de junio de 2026, un cambio de fiatjaf eliminó ese techo, y vale la pena precisar exactamente qué cambió.

De dónde venía el límite anterior

El límite de 65535 bytes nunca fue una decisión de política deliberada. Fue consecuencia directa de cómo NIP-44 rellena el texto plano antes de cifrarlo. El formato de relleno almacenaba la longitud del texto plano como los primeros dos bytes del blob rellenado, un entero sin signo de 16 bits en big-endian, u16. Un u16 solo puede representar valores de 0 a 65535, así que cualquier cosa mayor simplemente no podía expresarse en el prefijo de longitud, sin importar si el cifrador subyacente podía manejarla de otro modo. La propia sección de constantes de la especificación lo decía sin rodeos: max_plaintext_size era 65535, "64kB menos 1".

Esa misma suposición de 2 bytes se propagó hacia afuera. Las reglas de validación de NIP-44 sobre el payload codificado en base64 y sobre la cadena de bytes decodificada eran ambas comprobaciones de rango, no solo de longitud mínima: un payload base64 válido tenía que caer entre 132 y 87472 caracteres, y un mensaje decodificado válido entre 99 y 65603 bytes. Ambos límites superiores existían únicamente porque un mensaje más grande era estructuralmente imposible bajo el prefijo de 2 bytes.

Qué hace el nuevo esquema

El cambio fusionado conserva el prefijo de 2 bytes para todo lo que aún cabe en él, y añade un segundo formato, más grande, para lo que no cabe. La regla es un umbral en 65536 bytes:

  • Si la longitud del texto plano es menor de 65536 bytes, el prefijo sigue siendo de 2 bytes, exactamente el antiguo formato u16: [plaintext_length: u16][plaintext][zero_bytes].
  • Si la longitud del texto plano es de 65536 bytes o más, el prefijo pasa a ser de 6 bytes: dos bytes en cero seguidos de un u32 en big-endian, [0x00, 0x00][plaintext_length: u32][plaintext][zero_bytes].

Los dos bytes en cero al inicio del prefijo extendido no son relleno porque sí, son la señal. Un texto plano válido siempre tiene al menos 1 byte, así que un valor u16 de exactamente cero nunca podría ocurrir en el formato antiguo. Decodificar es entonces inequívoco: leer los primeros 2 bytes como u16; si son cero, leer los siguientes 4 bytes como u32 para obtener la longitud real; si no son cero, ese valor es la longitud y el prefijo siempre fue de 2 bytes.

max_plaintext_size pasa de 65535 a 4.294.967.295, que es 2^32 menos 1, unos 4 GB aproximadamente. Las comprobaciones de rango sobre la longitud del payload en base64 y decodificado pierden por completo su límite superior y se convierten en comprobaciones de mínimo únicamente: al menos 132 caracteres base64, al menos 99 bytes decodificados, sin techo.

La especificación también ganó una nueva sección de "consideraciones de implementación". Indica a las implementaciones que impongan su propio tamaño máximo de payload según su plataforma, y que rechacen los payloads sobredimensionados temprano, antes de la decodificación base64, para evitar denegación de servicio al intentar decodificar entradas enormes. Señala que descifrar puede requerir varias veces el tamaño del payload en memoria de trabajo, que los sistemas basados en JVM limitan los arreglos contiguos a unos 2 GB, muy por debajo del nuevo techo teórico de 4 GB, y que los cálculos de longitud rellenada ahora pueden alcanzar 2^32, por lo que las implementaciones necesitan aritmética de 64 bits para calcular el relleno correctamente.

Se añadieron nuevos vectores de prueba en el límite, comprobando un texto plano de 65535 bytes contra uno de 65536 bytes, para confirmar que las implementaciones cambian de formato de prefijo exactamente en el punto correcto.

Misma versión, sin cambio de versión

Esto sigue siendo NIP-44 versión 2. El cambio no tocó el byte de versión ni añadió un nuevo número de versión que negociar. Extiende el formato de relleno v2 existente con una segunda longitud de prefijo que solo se activa cuando el mensaje supera los 65536 bytes. Un decodificador de versión 2 que se haya actualizado a este NIP maneja tanto los mensajes antiguos como los nuevos bajo el mismo identificador de versión.

Retrocompatible, según el propio autor de la PR

El cuerpo de la PR lo dice sin rodeos: "This is backwards-compatible and no one has to change anything if they do not care about bigger messages" ("Esto es retrocompatible y nadie tiene que cambiar nada si no le importan los mensajes más grandes"). Nada cambia para el caso común. Cualquier texto plano menor de 65536 bytes se codifica con exactamente el mismo prefijo de 2 bytes que antes, byte por byte. Las implementaciones que nunca necesitan enviar algo más grande no necesitan actualizarse en absoluto.

El cuerpo de la PR también nombra el caso concreto que motivó el cambio: "The only reasonable case where this necessity has shown up so far was signing of big kind:3 lists via NIP-46" ("El único caso razonable donde esta necesidad se ha presentado hasta ahora fue la firma de listas grandes de kind:3 vía NIP-46"). Las listas de contactos kind:3 grandes, enviadas a través de la firma remota de NIP-46, eran la carga de trabajo que chocaba con el techo anterior.

NIP-44 es la base del cifrado de los mensajes directos en Nostr, así que un límite en el tamaño del texto plano es un límite en lo que puede llevar un solo mensaje cifrado. Elevarlo no toca cómo se deriva la clave de conversación, cómo funciona el cifrado ChaCha20, ni cómo se calcula el MAC. Cambia lo que cabe en un mensaje.

Fuentes

Toda afirmación de este artículo enlaza a una fuente primaria.

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

Stay Updated

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

No spam, ever. Unsubscribe anytime.