Protocolo Datagram2

Proposal 163
Fechado
Author zzz, orignal, drzed, eyedeekay
Created 2023-01-24
Last Updated 2025-04-16
Target Version 0.9.66

Status

Aprovado na revisão em 2025-04-15. Alterações incorporadas nas especificações. Implementado em Java I2P a partir da API 0.9.66. Verifique a documentação de implementação para status.

Visão Geral

Extraído de Prop123 como uma proposta separada.

Assinaturas offline não podem ser verificadas no processamento de datagramas repliáveis. Necessita de uma bandeira para indicar assinaturas offline, mas não há lugar para colocar uma bandeira.

Será necessário um número e formato de protocolo I2CP completamente novo, a serem adicionados à especificação DATAGRAMS. Vamos chamá-lo de “Datagram2”.

Objetivos

  • Adicionar suporte para assinaturas offline
  • Adicionar resistência a replay
  • Adicionar versão sem assinaturas
  • Adicionar campos de bandeiras e opções para extensibilidade

Não-Objetivos

Suporte completo de protocolo de ponta a ponta para controle de congestionamento, etc. Isso seria construído sobre, ou como uma alternativa a, Datagram2, que é um protocolo de baixo nível. Não faria sentido projetar um protocolo de alto desempenho apenas sobre o Datagram2, por causa do campo “from” e da sobrecarga de assinatura. Qualquer protocolo desse tipo deve realizar um handshake inicial com Datagram2 e, em seguida, alternar para datagramas RAW.

Motivação

Remanescente do trabalho LS2, concluído em 2019.

A primeira aplicação a usar o Datagram2 deve ser anúncios UDP de bittorrent, conforme implementado em i2psnark e zzzot, veja Prop160.

Especificação de Datagramas Repliáveis

Para referência, segue uma revisão da especificação para datagramas repliáveis, copiada de Datagrams. O número padrão de protocolo I2CP para datagramas repliáveis é PROTO_DATAGRAM (17).

+----+----+----+----+----+----+----+----+
  | from                                  |
  +                                       +
  |                                       |
  ~                                       ~
  ~                                       ~
  |                                       |
  +                                       +
  |                                       |
  |                                       |
  +----+----+----+----+----+----+----+----+
  | signature                             |
  +                                       +
  |                                       |
  +                                       +
  |                                       |
  +                                       +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  | payload...
  +----+----+----+----//


  from :: um `Destination`
          comprimento: 387+ bytes
          O originador e assinante do datagrama

  signature :: uma `Signature`
               O tipo de assinatura deve corresponder ao tipo de chave pública de assinatura de $from
               comprimento: 40+ bytes, conforme implícito pelo tipo de assinatura.
               Para o tipo de chave DSA_SHA1 padrão:
                  A `Signature` DSA do hash SHA-256 do payload.
               Para outros tipos de chave:
                  A `Signature` do payload.
               A assinatura pode ser verificada pela chave pública de assinatura de $from

  payload ::  Os dados
              Comprimento: 0 até cerca de 31,5 KB (veja notas)

  Comprimento total: Comprimento do payload + 423+

Design

  • Definir novo protocolo 19 - Datagramas repliáveis com opções.
  • Definir novo protocolo 20 - Datagramas repliáveis sem assinatura.
  • Adicionar campo de bandeiras para assinaturas offline e expansão futura
  • Mover assinatura após o payload para processamento mais fácil
  • Nova especificação de assinatura diferente de datagrama repliável ou streaming, de modo que a verificação da assinatura falhará se interpretada como datagrama repliável ou streaming. Isso é conseguido movendo a assinatura após o payload, e incluindo o hash do destino na função de assinatura.
  • Adicionar prevenção de replay para datagramas, como foi feito em Prop164 para streaming.
  • Adicionar seção para opções arbitrárias
  • Reutilizar formato de assinatura offline de Common e Streaming.
  • A seção de assinatura offline deve ser antes das seções de payload e assinatura de comprimento variável, pois especifica o comprimento da assinatura.

Especificação

Protocolo

O novo número de protocolo I2CP para Datagram2 é 19. Adicione-o como PROTO_DATAGRAM2 a I2CP.

O novo número de protocolo I2CP para Datagram3 é 20. Adicione-o como PROTO_DATAGRAM2 a I2CP.

Formato Datagram2

Adicione Datagram2 a DATAGRAMS como segue:

+----+----+----+----+----+----+----+----+
  |                                       |
  ~            from                       ~
  ~                                       ~
  |                                       |
  +----+----+----+----+----+----+----+----+
  |  flags  |     options (optional)      |
  +----+----+                             +
  ~                                       ~
  ~                                       ~
  +----+----+----+----+----+----+----+----+
  |                                       |
  ~     offline_signature (optional)      ~
  ~   expires, sigtype, pubkey, offsig    ~
  |                                       |
  +----+----+----+----+----+----+----+----+
  |                                       |
  ~            payload                    ~
  ~                                       ~
  |                                       |
  +----+----+----+----+----+----+----+----+
  |                                       |
  ~            signature                  ~
  ~                                       ~
  |                                       |
  +----+----+----+----+----+----+----+----+

  from :: um `Destination`
          comprimento: 387+ bytes
          O originador e (a menos que assinado offline) assinante do datagrama

  flags :: (2 bytes)
           Ordem dos bits: 15 14 ... 3 2 1 0
           Bits 3-0: Versão: 0x02 (0 0 1 0)
           Bit 4: Se 0, sem opções; se 1, mapeamento de opções incluído
           Bit 5: Se 0, sem assinatura offline; se 1, assinado offline
           Bits 15-6: não usados, configurar para 0 para compatibilidade com usos futuros

  options :: (2+ bytes se presentes)
           Se a bandeira indicar que opções estão presentes, um `Mapping`
           contendo opções de texto arbitrárias

  offline_signature ::
               Se a bandeira indicar chaves offline, a seção de assinatura offline,
               conforme especificado na Especificação de Estruturas Comuns,
               com os seguintes 4 campos. Comprimento: varia conforme os tipos de assinatura
               online e offline, tipicamente 102 bytes para Ed25519
               Esta seção pode e deve ser gerada offline.

    expires :: Timestamp de expiração
               (4 bytes, big endian, segundos desde a época, gira em 2106)

    sigtype :: Tipo de assinatura transitória (2 bytes, big endian)

    pubkey :: Chave pública de assinatura transitória (comprimento conforme implicado pelo tipo de assinatura),
              tipicamente 32 bytes para o tipo de assinatura Ed25519.

    offsig :: uma `Signature`
              Assinatura de timestamp de expiração, tipo de assinatura transitória,
              e chave pública, pela chave pública de destino,
              comprimento: 40+ bytes, conforme implícito pelo tipo de assinatura, tipicamente
              64 bytes para o tipo de assinatura Ed25519.

  payload ::  Os dados
              Comprimento: 0 até cerca de 61 KB (veja notas)

  signature :: uma `Signature`
               O tipo de assinatura deve corresponder ao tipo de chave pública de assinatura de $from
               (se não assinado offline) ou o tipo de assinatura transitória
               (se assinado offline)
               comprimento: 40+ bytes, conforme implícito pelo tipo de assinatura, tipicamente
               64 bytes para o tipo de assinatura Ed25519.
               A `Signature` do payload e outros campos especificados abaixo.
               A assinatura é verificada pela chave pública de assinatura de $from
               (se não assinado offline) ou a chave pública transitória
               (se assinado offline)

Comprimento total: mínimo 433 + comprimento do payload; comprimento típico para remetentes X25519 e sem assinaturas offline: 457 + comprimento do payload. Observe que a mensagem será tipicamente comprimida com gzip na camada I2CP, o que resultará em economias significativas se o destino “from” for compressível.

Nota: O formato de assinatura offline é o mesmo que na especificação de Estruturas Comuns Common e Streaming.

Assinaturas

A assinatura é sobre os seguintes campos.

  • Prelúdio: O hash de 32 bytes do destino alvo (não incluído no datagrama)
  • flags
  • options (se presentes)
  • offline_signature (se presente)
  • payload

No datagrama repliável, para o tipo de chave DSA_SHA1, a assinatura era sobre o hash SHA-256 do payload, não o payload em si; aqui, a assinatura é sempre sobre os campos acima (NÃO o hash), independentemente do tipo de chave.

Verificação de ToHash

Os receptores devem verificar a assinatura (usando seu hash de destino) e descartar o datagrama em caso de falha, para prevenção de replay.

Formato Datagram3

Adicione Datagram3 a DATAGRAMS como segue:

+----+----+----+----+----+----+----+----+
  |                                       |
  ~            fromhash                   ~
  ~                                       ~
  |                                       |
  +----+----+----+----+----+----+----+----+
  |  flags  |     options (optional)      |
  +----+----+                             +
  ~                                       ~
  ~                                       ~
  +----+----+----+----+----+----+----+----+
  |                                       |
  ~            payload                    ~
  ~                                       ~
  |                                       |
  +----+----+----+----+----+----+----+----+

  fromhash :: um `Hash`
              comprimento: 32 bytes
              O originador do datagrama

  flags :: (2 bytes)
           Ordem dos bits: 15 14 ... 3 2 1 0
           Bits 3-0: Versão: 0x03 (0 0 1 1)
           Bit 4: Se 0, sem opções; se 1, mapeamento de opções incluído
           Bits 15-5: não usados, configurar para 0 para compatibilidade com usos futuros

  options :: (2+ bytes se presentes)
           Se a bandeira indicar que opções estão presentes, um `Mapping`
           contendo opções de texto arbitrárias

  payload ::  Os dados
              Comprimento: 0 até cerca de 61 KB (veja notas)

Comprimento total: mínimo 34 + comprimento do payload.

SAM

Adicione STYLE=DATAGRAM2 e STYLE=DATAGRAM3 à especificação SAMv3. Atualize as informações sobre assinaturas offline.

Sobrecarga

Este design adiciona 2 bytes de sobrecarga para datagramas repliáveis para bandeiras. Isso é aceitável.

Análise de Segurança

Incluir o hash alvo na assinatura deve ser efetivo em prevenir ataques de replay.

O formato Datagram3 não possui assinaturas, então o remetente não pode ser verificado, e ataques de replay são possíveis. Qualquer validação necessária deve ser feita na camada de aplicação, ou pelo roteador na camada de ratchet.

Notas

  • O comprimento prático é limitado pelas camadas inferiores dos protocolos - a especificação de mensagem de túnel TUNMSG limita as mensagens a cerca de 61,2 KB e os transportes TRANSPORT atualmente limitam as mensagens a cerca de 64 KB, então o comprimento dos dados aqui é limitado a cerca de 61 KB.
  • Veja notas importantes sobre a confiabilidade de datagramas grandes API. Para melhores resultados, limite o payload a cerca de 10 KB ou menos.

Compatibilidade

Nenhuma. As aplicações devem ser reescritas para rotear mensagens I2CP Datagram2 com base no protocolo e/ou porta. Mensagens Datagram2 que são mal roteadas e interpretadas como mensagens de datagrama repliáveis ou de streaming falharão com base na assinatura, formato, ou ambos.

Migração

Cada aplicação UDP deve detectar suporte e migrar separadamente. A aplicação UDP mais proeminente é o bittorrent.

Bittorrent

DHT de Bittorrent: Provavelmente precisa de bandeira de extensão, por exemplo, i2p_dg2, coordenar com BiglyBT

Anúncios UDP de Bittorrent Prop160: Design desde o início. Coordenar com BiglyBT, i2psnark, zzzot

Outros

Bote: Improvável de migrar, não mantido ativamente

Streamr: Ninguém está usando, nenhuma migração planejada

Aplicativos UDP SAM: Nenhum conhecido

Referências