Cette traduction a été générée par apprentissage automatique et peut ne pas être exacte à 100%. Voir la version anglaise

Nouvelles entrées netDB

Proposal 123
Ouvrir
Author zzz, str4d, orignal
Created 2016-01-16
Last Updated 2020-07-18
Supercedes: 110, 120, 121, 122

Statut

Certaines parties de cette proposition sont terminées et implémentées dans les versions 0.9.38 et 0.9.39. Les spécifications des Structures Communes, I2CP, I2NP et autres ont maintenant été mises à jour pour refléter les changements actuellement pris en charge.

Les parties terminées restent sujettes à de légères révisions. D’autres parties de cette proposition sont encore en cours de développement et sujettes à des révisions importantes.

La recherche de service (types 9 et 11) est une priorité faible, non planifiée, et pourrait être séparée en une proposition distincte.

Aperçu

Il s’agit d’une mise à jour et d’une agrégation des 4 propositions suivantes :

  • 110 LS2
  • 120 Meta LS2 pour multihébergement massif
  • 121 LS2 Chiffré
  • 122 Recherche de service non authentifiée (anycast)

Ces propositions sont principalement indépendantes, mais par souci de cohérence, nous définissons et utilisons un format commun pour plusieurs d’entre elles.

Les propositions suivantes sont partiellement liées :

  • 140 Multihébergement Invisible (incompatible avec cette proposition)
  • 142 Nouveau Modèle de Cryptographie (pour une nouvelle cryptographie symétrique)
  • 144 ECIES-X25519-AEAD-Ratchet
  • 145 ECIES-P256
  • 146 Red25519
  • 148 EdDSA-BLAKE2b-Ed25519
  • 149 B32 pour LS2 Chiffré
  • 150 Protocole Garlic Farm
  • 151 ECDSA Blinding

Proposition

Cette proposition définit 5 nouveaux types DatabaseEntry et le processus pour les stocker et les récupérer depuis la base de données du réseau, ainsi que la méthode pour les signer et vérifier ces signatures.

Objectifs

  • Compatibilité ascendante
  • LS2 utilisable avec le multihébergement ancien style
  • Aucune nouvelle cryptographie ou primitive requise pour le support
  • Maintenir la découplage entre crypto et signature ; supporter toutes les versions actuelles et futures
  • Permettre des clés de signature hors ligne optionnelles
  • Réduire la précision des horodatages pour limiter le fingerprinting
  • Permettre une nouvelle cryptographie pour les destinations
  • Permettre un multihébergement massif
  • Corriger plusieurs problèmes avec le LS chiffré existant
  • Option de masquage (blinding) pour réduire la visibilité par les floodfills
  • Le chiffré supporte à la fois une clé unique et des clés multiples révocables
  • Recherche de service pour faciliter la recherche de outproxies, le bootstrap DHT d’application,
    et autres usages
  • Ne rien casser qui dépend des hachages binaires de destination de 32 octets, par exemple bittorrent
  • Ajouter de la flexibilité aux leasesets via des propriétés, comme nous en avons dans les routerinfos.
  • Placer l’horodatage de publication et l’expiration variable dans l’en-tête, pour que cela fonctionne même
    si le contenu est chiffré (ne pas dériver l’horodatage à partir de la location la plus ancienne)
  • Tous les nouveaux types vivent dans le même espace DHT et aux mêmes emplacements que les leasesets existants,
    afin que les utilisateurs puissent migrer du vieux LS vers LS2,
    ou changer entre LS2, Meta et Chiffré,
    sans changer la Destination ou son hachage.
  • Une Destination existante peut être convertie pour utiliser des clés hors ligne,
    ou revenir à des clés en ligne, sans changer la Destination ou son hachage.

Non-objectifs / Hors-scope

  • Nouvel algorithme de rotation DHT ou génération de nombres aléatoires partagés
  • Le type de chiffrement spécifique et le schéma de chiffrement de bout en bout
    utilisant ce nouveau type seraient dans une proposition séparée.
    Aucune nouvelle cryptographie n’est spécifiée ou discutée ici.
  • Nouveau chiffrement pour les RIs ou la construction de tunnels.
    Ce serait dans une proposition séparée.
  • Méthodes de chiffrement, transmission et réception des messages I2NP DLM / DSM / DSRM.
    Non modifiées.
  • Comment générer et gérer Meta, y compris la communication inter-routeurs, gestion, basculement et coordination.
    Le support pourrait être ajouté à I2CP, ou i2pcontrol, ou un nouveau protocole.
    Cela pourrait ou non être standardisé.
  • Comment implémenter et gérer réellement des tunnels à expiration prolongée, ou annuler des tunnels existants.
    C’est extrêmement difficile, et sans cela, vous ne pouvez pas avoir un arrêt gracieux raisonnable.
  • Changements du modèle de menace
  • Format de stockage hors ligne, ou méthodes pour stocker/récupérer/partager les données.
  • Les détails d’implémentation ne sont pas discutés ici et sont laissés à chaque projet.

Justification

LS2 ajoute des champs pour changer le type de chiffrement et pour les futurs changements de protocole.

LS2 Chiffré corrige plusieurs problèmes de sécurité du LS chiffré existant en utilisant un chiffrement asymétrique de l’ensemble des locations.

Meta LS2 fournit un multihébergement flexible, efficace, performant et à grande échelle.

Les enregistrements et listes de service fournissent des services anycast tels que la recherche de noms et le bootstrap DHT.

Types de données NetDB

Les numéros de type sont utilisés dans les messages I2NP Database Lookup/Store.

La colonne « end-to-end » indique si les requêtes/réponses sont envoyées à une Destination dans un message Garlic.

Types existants :

NetDB DataLookup TypeStore Type
any0any
LS11
RI20
exploratory3DSRM
Nouveaux types :
NetDB DataLookup TypeStore TypeStd. LS2 Header?Sent end-to-end?
LS213yesyes
Encrypted LS215nono
Meta LS217yesno
Service Recordn/a9yesno
Service List411nono

Notes

  • Les types de recherche sont actuellement les bits 3-2 du message Database Lookup.
    Tout type supplémentaire nécessiterait l’utilisation du bit 4.

  • Tous les types de stockage sont impairs car les bits supérieurs du champ type dans le message Database Store
    sont ignorés par les anciens routeurs.
    Nous préférons que l’analyse échoue comme un LS plutôt que comme un RI compressé.

  • Le type doit-il être explicite, implicite ou ni l’un ni l’autre dans les données couvertes par la signature ?

Processus de recherche / stockage

Les types 3, 5 et 7 peuvent être retournés en réponse à une recherche standard de leaseset (type 1). Le type 9 n’est jamais retourné en réponse à une recherche. Le type 11 est retourné en réponse à un nouveau type de recherche de service (type 11).

Seul le type 3 peut être envoyé dans un message Garlic client-à-client.

Format

Les types 3, 7 et 9 ont un format commun ::

Standard LS2 Header
- as defined below

Type-Specific Part
- as defined below in each part

Standard LS2 Signature:
- Length as implied by sig type of signing key

En-tête standard LS2

Partie spécifique au type

Considérations de confidentialité/sécurité

Signature standard LS2 :

En-tête standard LS2

Le type 5 (Chiffré) ne commence pas par une Destination et a un format différent. Voir ci-dessous.

Format

Standard LS2 Header:
  - Type (1 byte)
    Not actually in header, but part of data covered by signature.
    Take from field in Database Store Message.
  - Destination (387+ bytes)
  - Published timestamp (4 bytes, big endian, seconds since epoch, rolls over in 2106)
  - Expires (2 bytes, big endian) (offset from published timestamp in seconds, 18.2 hours max)
  - Flags (2 bytes)
    Bit order: 15 14 ... 3 2 1 0
    Bit 0: If 0, no offline keys; if 1, offline keys
    Bit 1: If 0, a standard published leaseset.
           If 1, an unpublished leaseset. Should not be flooded, published, or
           sent in response to a query. If this leaseset expires, do not query the
           netdb for a new one, unless bit 2 is set.
    Bit 2: If 0, a standard published leaseset.
           If 1, this unencrypted leaseset will be blinded and encrypted when published.
           If this leaseset expires, query the blinded location in the netdb for a new one.
           If this bit is set to 1, set bit 1 to 1 also.
           As of release 0.9.42.
    Bits 3-15: set to 0 for compatibility with future uses
  - If flag indicates offline keys, the offline signature section:
    Expires timestamp (4 bytes, big endian, seconds since epoch, rolls over in 2106)
    Transient sig type (2 bytes, big endian)
    Transient signing public key (length as implied by sig type)
    Signature of expires timestamp, transient sig type, and public key,
    by the destination public key,
    length as implied by destination public key sig type.
    This section can, and should, be generated offline.

Justification

  • tel que défini ci-dessous

  • tel que défini ci-dessous pour chaque partie

  • Longueur implicite par le type de signature de la clé de signature

  • Non publié/publié : À utiliser lors de l’envoi d’un stockage de base de données de bout en bout,
    le routeur émetteur peut souhaiter indiquer que ce leaseset ne doit pas être
    envoyé à d’autres. Nous utilisons actuellement des heuristiques pour maintenir cet état.

Problèmes

  • Publié : Remplace la logique complexe nécessaire pour déterminer la « version » du
    leaseset. Actuellement, la version est l’expiration de la location expirant en dernier, et un routeur de publication doit incrémenter cette expiration d’au moins 1 ms lorsqu’il
    publie un leaseset qui supprime uniquement une ancienne location.

  • Expiration : Permet à l’expiration d’une entrée netdb d’être antérieure à celle de
    sa location expirant en dernier. Peut ne pas être utile pour LS2, où les leasesets
    sont censés rester avec une expiration maximale de 11 minutes, mais
    pour d’autres nouveaux types, c’est nécessaire (voir Meta LS et Service Record ci-dessous).

  • Les clés hors ligne sont optionnelles, pour réduire la complexité initiale/requise de l’implémentation.

Notes

  • Pourrait réduire encore plus la précision de l’horodatage (10 minutes ?) mais devrait ajouter
    un numéro de version. Cela pourrait casser le multihébergement, sauf si nous avons un chiffrement préservant l’ordre ?
    Probablement impossible sans horodatages du tout.

  • Alternative : horodatage de 3 octets (époque / 10 minutes), version de 1 octet, expiration de 2 octets

  • Le type est-il explicite ou implicite dans les données / signature ? Constantes « Domaine » pour la signature ?

Nouveaux types DatabaseEntry

LeaseSet 2

Le type 11 (Service List) est une agrégation de plusieurs Service Records et a un format différent. Voir ci-dessous.

  • Les routeurs ne devraient pas publier un LS plus d’une fois par seconde.
    S’ils le font, ils doivent artificiellement incrémenter l’horodatage de publication de 1
    par rapport au LS précédemment publié.

TBD

Standard LS flag (1)

Les types 3, 7 et 9 utilisent l’en-tête standard LS2, spécifié ci-dessous :

Standard LS2 type (3)

Changements par rapport au LeaseSet existant :

Hash of destination
This hash is then used to generate the daily "routing key", as in LS1

Recherche avec

10 minutes, as in a regular LS.

Stockage avec

Destination

Format

Standard LS2 Header as specified above

  Standard LS2 Type-Specific Part
  - Properties (Mapping as specified in common structures spec, 2 zero bytes if none)
  - Number of key sections to follow (1 byte, max TBD)
  - Key sections:
    - Encryption type (2 bytes, big endian)
    - Encryption key length (2 bytes, big endian)
      This is explicit, so floodfills can parse LS2 with unknown encryption types.
    - Encryption key (number of bytes specified)
  - Number of lease2s (1 byte)
  - Lease2s (40 bytes each)
    These are leases, but with a 4-byte instead of an 8-byte expiration,
    seconds since the epoch (rolls over in 2106)

  Standard LS2 Signature:
  - Signature
    If flag indicates offline keys, this is signed by the transient pubkey,
    otherwise, by the destination pubkey
    Length as implied by sig type of signing key
    The signature is of everything above.

Justification

  • Les implémentations de routeurs pourraient mettre en cache les clés temporaires et la signature pour
    éviter la vérification à chaque fois. En particulier, les floodfills et les routeurs aux
    deux extrémités de connexions longues pourraient bénéficier de cela.

  • Les clés et signature hors ligne ne conviennent que pour les destinations à longue durée de vie,
    c’est-à-dire les serveurs, pas les clients.

Discussion

Stockage à

Expiration typique

Publié par

  • Ajout de l’horodatage de publication, de l’horodatage d’expiration, des flags et des propriétés
  • Ajout du type de chiffrement
  • Suppression de la clé de révocation

Cette proposition continue d’utiliser la clé publique dans le leaseset comme clé de chiffrement de bout en bout, et laisse le champ de clé publique dans la Destination inutilisé, comme actuellement. Le type de chiffrement n’est pas spécifié dans le certificat de clé de Destination, il restera 0.

  • Propriétés : Extension et flexibilité futures.
    Placées en premier au cas où nécessaires pour l’analyse des données restantes.

Nouveaux problèmes de chiffrement

Une alternative rejetée consiste à spécifier le type de chiffrement dans le certificat de clé de Destination, utiliser la clé publique dans la Destination, et ne pas utiliser la clé publique dans le leaseset. Nous n’avons pas l’intention de faire cela.

  • Plusieurs paires type de chiffrement/clé publique sont
    destinées à faciliter la transition vers de nouveaux types de chiffrement. L’autre façon de faire
    est de publier plusieurs leasesets, éventuellement en utilisant les mêmes tunnels,
    comme nous le faisons actuellement pour les destinations DSA et EdDSA.
    L’identification du type de chiffrement entrant sur un tunnel
    peut être faite avec le mécanisme existant de session tag,
    et/ou par déchiffrement d’essai avec chaque clé. La longueur des messages entrants
    peut également fournir un indice.

  • L’emplacement de la clé publique réelle ne change pas.

  • Le type de chiffrement ou la clé publique peut changer sans changer la Destination.

  • Supprime le champ de révocation inutilisé

  • Compatibilité de base avec d’autres types DatabaseEntry dans cette proposition

  • Permet plusieurs types de chiffrement

  • L’emplacement de la clé publique et du type de chiffrement diffère de RouterInfo

  • Maintient la clé publique inutilisée dans le leaseset

  • Nécessite une implémentation à travers le réseau ; dans l’alternative, des types de chiffrement expérimentaux peuvent être utilisés, si autorisés par les floodfills
    (mais voir les propositions connexes 136 et 137 concernant le support des types de signature expérimentaux).
    La proposition alternative pourrait être plus facile à implémenter et tester pour des types de chiffrement expérimentaux.

Notes

  • Le type de chiffrement représente la combinaison
    de courbe, longueur de clé et schéma de bout en bout,
    incluant KDF et MAC, le cas échéant.

  • Nous avons inclus un champ de longueur de clé, afin que le LS2 soit
    analysable et vérifiable par le floodfill même pour des types de chiffrement inconnus.

  • Le premier nouveau type de chiffrement proposé sera
    probablement ECIES/X25519. Comment il est utilisé de bout en bout
    (soit une version légèrement modifiée d’ElGamal/AES+SessionTag
    soit quelque chose de complètement nouveau, par exemple ChaCha/Poly) sera spécifié
    dans une ou plusieurs propositions séparées.
    Voir aussi les propositions ECIES 144 et 145.

LS2 Chiffré

Avantages de LS2 :

  • L’expiration de 8 octets dans les locations passe à 4 octets.

Inconvénients de LS2 :

Certains points sont hors-scope pour cette proposition, mais nous mettons ici des notes car nous n’avons pas encore de proposition de chiffrement séparée. Voir aussi les propositions ECIES 144 et 145.

  • Si nous implémentons jamais la révocation, nous pouvons le faire avec un champ d’expiration à zéro,
    ou des locations nulles, ou les deux. Pas besoin d’une clé de révocation séparée.

Objectifs :

Standard LS flag (1)

Le LS2 chiffré n’est jamais envoyé dans un message garlic de bout en bout. Utilisez le LS2 standard comme ci-dessus.

Encrypted LS2 type (5)

Changements par rapport au LeaseSet chiffré existant :

Hash of blinded sig type and blinded public key
Two byte sig type (big endian, e.g. 0x000b) || blinded public key
This hash is then used to generate the daily "routing key", as in LS1

Recherche avec

10 minutes, as in a regular LS, or hours, as in a meta LS.

Stockage avec

Destination

Définitions

Stockage à

Expiration typique

n-byte output from a cryptographically-secure random number generator.

In addition to the requirement of CSRNG being cryptographically-secure (and thus
suitable for generating key material), it MUST be safe
for some n-byte output to be used for key material when the byte sequences immediately
preceding and following it are exposed on the network (such as in a salt, or encrypted
padding). Implementations that rely on a potentially-untrustworthy source should hash
any output that is to be exposed on the network. See [PRNG references](http://projectbullrun.org/dual-ec/ext-rand.html) and [Tor dev discussion](https://lists.torproject.org/pipermail/tor-dev/2015-November/009954.html).

Publié par

SHA-256 hash function that takes a personalization string p and data d, and
produces an output of length 32 bytes.

Use SHA-256 as follows::

    H(p, d) := SHA-256(p || d)

Nous définissons les fonctions suivantes correspondant aux blocs cryptographiques utilisés pour le LS2 chiffré :

The ChaCha20 stream cipher as specified in [RFC 7539 Section 2.4](https://tools.ietf.org/html/rfc7539#section-2.4), with the initial counter
set to 1. S_KEY_LEN = 32 and S_IV_LEN = 12.

ENCRYPT(k, iv, plaintext)
    Encrypts plaintext using the cipher key k, and nonce iv which MUST be unique for
    the key k. Returns a ciphertext that is the same size as the plaintext.

    The entire ciphertext must be indistinguishable from random if the key is secret.

DECRYPT(k, iv, ciphertext)
    Decrypts ciphertext using the cipher key k, and nonce iv. Returns the plaintext.

CSRNG(n)

The RedDSA signature scheme (corresponding to SigType 11) with key blinding.
It has the following functions:

DERIVE_PUBLIC(privkey)
    Returns the public key corresponding to the given private key.

SIGN(privkey, m)
    Returns a signature by the private key privkey over the given message m.

VERIFY(pubkey, m, sig)
    Verifies the signature sig against the public key pubkey and message m. Returns
    true if the signature is valid, false otherwise.

It must also support the following key blinding operations:

GENERATE_ALPHA(data, secret)
    Generate alpha for those who know the data and an optional secret.
    The result must be identically distributed as the private keys.

BLIND_PRIVKEY(privkey, alpha)
    Blinds a private key, using a secret alpha.

BLIND_PUBKEY(pubkey, alpha)
    Blinds a public key, using a secret alpha.
    For a given keypair (privkey, pubkey) the following relationship holds::

        BLIND_PUBKEY(pubkey, alpha) ==
        DERIVE_PUBLIC(BLIND_PRIVKEY(privkey, alpha))

H(p, d)

X25519 public key agreement system. Private keys of 32 bytes, public keys of 32
bytes, produces outputs of 32 bytes. It has the following
functions:

GENERATE_PRIVATE()
    Generates a new private key.

DERIVE_PUBLIC(privkey)
    Returns the public key corresponding to the given private key.

DH(privkey, pubkey)
    Generates a shared secret from the given private and public keys.

STREAM

A cryptographic key derivation function which takes some input key material ikm (which
should have good entropy but is not required to be a uniformly random string), a salt
of length 32 bytes, and a context-specific 'info' value, and produces an output
of n bytes suitable for use as key material.

Use HKDF as specified in [RFC 5869](https://tools.ietf.org/html/rfc5869), using the HMAC hash function SHA-256
as specified in [RFC 2104](https://tools.ietf.org/html/rfc2104). This means that SALT_LEN is 32 bytes max.

Format

SIG

  • Les clés de chiffrement sont dans l’ordre de préférence du serveur, la plus préférée en premier.
    Le comportement par défaut du client est de sélectionner la première clé avec
    un type de chiffrement pris en charge. Les clients peuvent utiliser d’autres algorithmes de sélection
    basés sur le support du chiffrement, les performances relatives et d’autres facteurs.

DH

Layer 0 data + Enc(layer 1 data + Enc(layer 2 data)) + Signature

HKDF(salt, ikm, info, n)

Le format du LS2 chiffré consiste en trois couches imbriquées :

Couche 0 (externe)

Le format global ressemble à ::

1 byte

Not actually in header, but part of data covered by signature.
Take from field in Database Store Message.

Notez que le LS2 chiffré est masqué. La Destination n’est pas dans l’en-tête. L’emplacement de stockage DHT est SHA-256(type de signature || clé publique masquée), et tourne quotidiennement.

2 bytes, big endian
This will always be type 11, identifying a Red25519 blinded key.

N’utilise PAS l’en-tête LS2 standard spécifié ci-dessus.

Length as implied by sig type

Type

4 bytes, big endian

Seconds since epoch, rolls over in 2106

Type de signature de la clé publique masquée

2 bytes, big endian

Offset from published timestamp in seconds, 18.2 hours max

Clé publique masquée

2 bytes

Bit order: 15 14 ... 3 2 1 0

Bit 0: If 0, no offline keys; if 1, offline keys

Other bits: set to 0 for compatibility with future uses

Horodatage de publication

Present if flag indicates offline keys

Expires timestamp
    4 bytes, big endian

    Seconds since epoch, rolls over in 2106

Transient sig type
    2 bytes, big endian

Transient signing public key
    Length as implied by sig type

Signature
    Length as implied by blinded public key sig type

    Over expires timestamp, transient sig type, and transient public key.

    Verified with the blinded public key.

Expiration

2 bytes, big endian

Flags

lenOuterCiphertext bytes

Encrypted layer 1 data. See below for key derivation and encryption algorithms.

Données de clé temporaire

Length as implied by sig type of the signing key used

The signature is of everything above.

If the flag indicates offline keys, the signature is verified with the transient
public key. Otherwise, the signature is verified with the blinded public key.

Couche 1 (intermédiaire)

lenOuterCiphertext

1 byte

Bit order: 76543210

Bit 0: 0 for everybody, 1 for per-client, auth section to follow

Bits 3-1: Authentication scheme, only if bit 0 is set to 1 for per-client, otherwise 000
          000: DH client authentication (or no per-client authentication)
          001: PSK client authentication

Bits 7-4: Unused, set to 0 for future compatibility

outerCiphertext

Present if flag bit 0 is set to 1 and flag bits 3-1 are set to 000.

ephemeralPublicKey
    32 bytes

clients
    2 bytes, big endian

    Number of authClient entries to follow, 40 bytes each

authClient
    Authorization data for a single client.
    See below for the per-client authorization algorithm.

    clientID_i
        8 bytes

    clientCookie_i
        32 bytes

Signature

Present if flag bit 0 is set to 1 and flag bits 3-1 are set to 001.

authSalt
    32 bytes

clients
    2 bytes, big endian

    Number of authClient entries to follow, 40 bytes each

authClient
    Authorization data for a single client.
    See below for the per-client authorization algorithm.

    clientID_i
        8 bytes

    clientCookie_i
        32 bytes

Flags

Length implied by lenOuterCiphertext (whatever data remains)

Encrypted layer 2 data. See below for key derivation and encryption algorithms.

Couche 2 (interne)

Données d’auth DH client

1 byte

Either 3 (LS2) or 7 (Meta LS2)

Données d’auth PSK client

LeaseSet2 data for the given type.

Includes the header and signature.

Dérivation de clé masquée

innerCiphertext

Type

Objectifs

  • Ajouter le masquage (blinding)
  • Permettre plusieurs types de signature
  • Ne pas nécessiter de nouvelles primitives cryptographiques
  • Chiffrer éventuellement à chaque destinataire, révocable
  • Supporter le chiffrement de LS2 standard et Meta LS2 uniquement

Sécurité

Données

Définitions

Nous utilisons le schéma suivant pour le masquage de clé, basé sur Ed25519 et ZCash RedDSA . Les signatures Re25519 sont sur la courbe Ed25519, en utilisant SHA-512 pour le hachage.

The Ed25519 base point (generator) 2^255 - 19 as in [Ed25519](http://cr.yp.to/papers.html#ed25519)

Nous n’utilisons pas Tor’s rend-spec-v3.txt appendix A.2 , qui a des objectifs de conception similaires, car ses clés publiques masquées peuvent être en dehors du sous-groupe d’ordre premier, avec des implications de sécurité inconnues.

The Ed25519 order 2^252 + 27742317777372353535851937790883648493
as in [Ed25519](http://cr.yp.to/papers.html#ed25519)

La sécurité d’un schéma de masquage exige que la distribution d’alpha soit la même que celle des clés privées non masquées. Cependant, lorsque nous masquons une clé privée Ed25519 (type de signature 7) vers une clé privée Red25519 (type de signature 11), la distribution est différente. Pour répondre aux exigences de zcash section 4.1.6.1 , Red25519 (type de signature 11) devrait être utilisé pour les clés non masquées également, afin que « la combinaison d’une clé publique ré-randomisée et de signature(s) sous cette clé ne révèle pas la clé à partir de laquelle elle a été ré-randomisée ». Nous autorisons le type 7 pour les destinations existantes, mais recommandons le type 11 pour les nouvelles destinations qui seront chiffrées.

Convert a private key to public, as in Ed25519 (mulitply by G)

B

A 32-byte random number known to those who know the destination.

L

Generate alpha for the current date, for those who know the destination and the secret.
The result must be identically distributed as Ed25519 private keys.

DERIVE_PUBLIC(a)

The unblinded 32-byte EdDSA or RedDSA signing private key used to sign the destination

alpha

The unblinded 32-byte EdDSA or RedDSA signing public key in the destination,
= DERIVE_PUBLIC(a), as in Ed25519

GENERATE_ALPHA(destination, date, secret)

The blinded 32-byte EdDSA signing private key used to sign the encrypted leaseset
This is a valid EdDSA private key.

a

The blinded 32-byte EdDSA signing public key in the Destination,
may be generated with DERIVE_PUBLIC(a'), or from A and alpha.
This is a valid EdDSA public key, on the curve and on the prime-order subgroup.

A

Flip the order of the input bytes to little-endian

a'

32 bytes = (LEOS2IP(SHA512(x))) mod B, same as in Ed25519 hash-and-reduce

Calculs de masquage

A'

LEOS2IP(x)

// GENERATE_ALPHA(destination, date, secret)

  // secret is optional, else zero-length
  A = destination's signing public key
  stA = signature type of A, 2 bytes big endian (0x0007 or 0x000b)
  stA' = signature type of blinded public key A', 2 bytes big endian (0x000b)
  keydata = A || stA || stA'
  datestring = 8 bytes ASCII YYYYMMDD from the current date UTC
  secret = UTF-8 encoded string
  seed = HKDF(H("I2PGenerateAlpha", keydata), datestring || secret, "i2pblinding1", 64)
  // treat seed as a 64 byte little-endian value
  alpha = seed mod L

H*(x)

// BLIND_PRIVKEY()

  alpha = GENERATE_ALPHA(destination, date, secret)
  // If for a Ed25519 private key (type 7)
  seed = destination's signing private key
  a = left half of SHA512(seed) and clamped as usual for Ed25519
  // else, for a Red25519 private key (type 11)
  a = destination's signing private key
  // Addition using scalar arithmentic
  blinded signing private key = a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod L
  blinded signing public key = A' = DERIVE_PUBLIC(a')

Un nouveau secret alpha et des clés masquées doivent être générés chaque jour (UTC). Le secret alpha et les clés masquées sont calculés comme suit.

// BLIND_PUBKEY()

  alpha = GENERATE_ALPHA(destination, date, secret)
  A = destination's signing public key
  // Addition using group elements (points on the curve)
  blinded public key = A' = BLIND_PUBKEY(A, alpha) = A + DERIVE_PUBLIC(alpha)

GENERATE_ALPHA(destination, date, secret), pour toutes les parties :

Signature

BLIND_PRIVKEY(), pour le propriétaire publiant le leaseset :

BLIND_PUBKEY(), pour les clients récupérant le leaseset :

Les deux méthodes de calcul de A’ donnent le même résultat, comme requis.

Le leaseset non masqué est signé par la clé privée de signature Ed25519 ou Red25519 non masquée et vérifié avec la clé publique de signature Ed25519 ou Red25519 non masquée (types de signature 7 ou 11) comme d’habitude.

Calculs de signature/vérification

Si la clé publique de signature est hors ligne, le leaseset non masqué est signé par la clé privée de signature temporaire Ed25519 ou Red25519 non masquée et vérifié avec la clé publique de signature temporaire Ed25519 ou Red25519 non masquée (types de signature 7 ou 11) comme d’habitude. Voir ci-dessous pour des notes supplémentaires sur les clés hors ligne pour les leasesets chiffrés.

Pour la signature du leaseset chiffré, nous utilisons Red25519, basé sur RedDSA pour signer et vérifier avec des clés masquées. Les signatures Red25519 sont sur la courbe Ed25519, en utilisant SHA-512 pour le hachage.

Red25519 est identique à Ed25519 standard sauf spécifié ci-dessous.

La partie externe du leaseset chiffré utilise des clés et signatures Red25519.

Red25519 est presque identique à Ed25519. Deux différences :

T = 80 random bytes
  r = H*(T || publickey || message)
  // rest is the same as in Ed25519

Les clés privées Red25519 sont générées à partir de nombres aléatoires puis doivent être réduites mod L, où L est défini ci-dessus. Les clés privées Ed25519 sont générées à partir de nombres aléatoires puis « clampées » en utilisant un masquage bit à bit sur les octets 0 et 31. Cela n’est pas fait pour Red25519. Les fonctions GENERATE_ALPHA() et BLIND_PRIVKEY() définies ci-dessus génèrent des clés privées Red25519 correctes en utilisant mod L.

// same as in Ed25519

Chiffrement et traitement

Dérivation des sous-identifiants

Dans Red25519, le calcul de r pour la signature utilise des données aléatoires supplémentaires, et utilise la valeur de la clé publique plutôt que le hachage de la clé privée. À cause des données aléatoires, chaque signature Red25519 est différente, même en signant les mêmes données avec la même clé.

A = destination's signing public key
  stA = signature type of A, 2 bytes big endian (0x0007 or 0x000b)
  stA' = signature type of A', 2 bytes big endian (0x000b)
  keydata = A || stA || stA'
  credential = H("credential", keydata)

Signature :

Vérification :

subcredential = H("subcredential", credential || blindedPublicKey)

Dans le cadre du processus de masquage, nous devons nous assurer qu’un LS2 chiffré ne peut être déchiffré que par quelqu’un qui connaît la clé publique de signature de la Destination correspondante. La Destination complète n’est pas requise. Pour y parvenir, nous dérivons un identifiant à partir de la clé publique de signature :

Chiffrement couche 1

La chaîne de personnalisation garantit que l’identifiant ne collisionne avec aucun hachage utilisé comme clé de recherche DHT, comme le hachage de Destination brut.

outerInput = subcredential || publishedTimestamp

Pour une clé masquée donnée, nous pouvons ensuite dériver un sous-identifiant :

outerSalt = CSRNG(32)

Le sous-identifiant est inclus dans les processus de dérivation de clé ci-dessous, ce qui lie ces clés à la connaissance de la clé publique de signature de la Destination.

keys = HKDF(outerSalt, outerInput, "ELS2_L1K", 44)
  outerKey = keys[0:31]
  outerIV = keys[32:43]

D’abord, l’entrée pour le processus de dérivation de clé est préparée :

outerCiphertext = outerSalt || ENCRYPT(outerKey, outerIV, outerPlaintext)

Déchiffrement couche 1

Ensuite, un sel aléatoire est généré :

outerSalt = outerCiphertext[0:31]

Puis la clé utilisée pour chiffrer la couche 1 est dérivée :

outerInput = subcredential || publishedTimestamp
  keys = HKDF(outerSalt, outerInput, "ELS2_L1K", 44)
  outerKey = keys[0:31]
  outerIV = keys[32:43]

Enfin, le texte clair de la couche 1 est chiffré et sérialisé :

outerPlaintext = DECRYPT(outerKey, outerIV, outerCiphertext[32:end])

Chiffrement couche 2

Le sel est analysé à partir du texte chiffré de la couche 1 :

Puis la clé utilisée pour chiffrer la couche 1 est dérivée :

innerInput = authCookie || subcredential || publishedTimestamp
  innerSalt = CSRNG(32)
  keys = HKDF(innerSalt, innerInput, "ELS2_L2K", 44)
  innerKey = keys[0:31]
  innerIV = keys[32:43]
  innerCiphertext = innerSalt || ENCRYPT(innerKey, innerIV, innerPlaintext)

Déchiffrement couche 2

Enfin, le texte chiffré de la couche 1 est déchiffré :

Lorsque l’autorisation client est activée, authCookie est calculé comme décrit ci-dessous. Lorsque l’autorisation client est désactivée, authCookie est un tableau d’octets de longueur nulle.

innerInput = authCookie || subcredential || publishedTimestamp
  innerSalt = innerCiphertext[0:31]
  keys = HKDF(innerSalt, innerInput, "ELS2_L2K", 44)
  innerKey = keys[0:31]
  innerIV = keys[32:43]
  innerPlaintext = DECRYPT(innerKey, innerIV, innerCiphertext[32:end])

Autorisation par-client

Le chiffrement procède de manière similaire à la couche 1 :

Lorsque l’autorisation client est activée, authCookie est calculé comme décrit ci-dessous. Lorsque l’autorisation client est désactivée, authCookie est un tableau d’octets de longueur nulle.

Autorisation client DH

Le déchiffrement procède de manière similaire à la couche 1 :

Lorsque l’autorisation client est activée pour une Destination, le serveur maintient une liste de clients qu’il autorise à déchiffrer les données du LS2 chiffré. Les données stockées par-client dépendent du mécanisme d’autorisation, et incluent une forme de matériel de clé que chaque client génère et envoie au serveur via un mécanisme sécurisé hors bande.

authCookie = CSRNG(32)
  esk = GENERATE_PRIVATE()
  epk = DERIVE_PUBLIC(esk)

Il existe deux alternatives pour implémenter l’autorisation par-client :

sharedSecret = DH(esk, cpk_i)
  authInput = sharedSecret || cpk_i || subcredential || publishedTimestamp
  okm = HKDF(epk, authInput, "ELS2_XCA", 52)
  clientKey_i = okm[0:31]
  clientIV_i = okm[32:43]
  clientID_i = okm[44:51]
  clientCookie_i = ENCRYPT(clientKey_i, clientIV_i, authCookie)

Chaque client génère une paire de clés DH [csk_i, cpk_i], et envoie la clé publique cpk_i au serveur.

Traitement du serveur ^^^^^^^^^^^^^^^^^ Le serveur génère un nouveau authCookie et une paire de clés DH éphémère :

sharedSecret = DH(csk_i, epk)
  authInput = sharedSecret || cpk_i || subcredential || publishedTimestamp
  okm = HKDF(epk, authInput, "ELS2_XCA", 52)
  clientKey_i = okm[0:31]
  clientIV_i = okm[32:43]
  clientID_i = okm[44:51]

Puis pour chaque client autorisé, le serveur chiffre authCookie à sa clé publique :

authCookie = DECRYPT(clientKey_i, clientIV_i, clientCookie_i)

Autorisation client par clé pré-partagée (PSK)

Le serveur place chaque tuple [clientID_i, clientCookie_i] dans la couche 1 du LS2 chiffré, avec epk.

Traitement du client ^^^^^^^^^^^^^^^^^ Le client utilise sa clé privée pour dériver son identifiant client attendu clientID_i, la clé de chiffrement clientKey_i, et le vecteur d’initialisation clientIV_i :

authCookie = CSRNG(32)
  authSalt = CSRNG(32)

Puis le client recherche dans les données d’autorisation de la couche 1 une entrée contenant clientID_i. Si une entrée correspondante existe, le client la déchiffre pour obtenir authCookie :

authInput = psk_i || subcredential || publishedTimestamp
  okm = HKDF(authSalt, authInput, "ELS2PSKA", 52)
  clientKey_i = okm[0:31]
  clientIV_i = okm[32:43]
  clientID_i = okm[44:51]
  clientCookie_i = ENCRYPT(clientKey_i, clientIV_i, authCookie)

Chaque client génère une clé secrète de 32 octets psk_i, et l’envoie au serveur. Alternativement, le serveur peut générer la clé secrète, et l’envoyer à un ou plusieurs clients.

Traitement du serveur ^^^^^^^^^^^^^^^^^ Le serveur génère un nouveau authCookie et un sel :

authInput = psk_i || subcredential || publishedTimestamp
  okm = HKDF(authSalt, authInput, "ELS2PSKA", 52)
  clientKey_i = okm[0:31]
  clientIV_i = okm[32:43]
  clientID_i = okm[44:51]

Puis pour chaque client autorisé, le serveur chiffre authCookie à sa clé pré-partagée :

authCookie = DECRYPT(clientKey_i, clientIV_i, clientCookie_i)

Considérations de sécurité

Le serveur place chaque tuple [clientID_i, clientCookie_i] dans la couche 1 du LS2 chiffré, avec authSalt.

Traitement du client ^^^^^^^^^^^^^^^^^ Le client utilise sa clé pré-partagée pour dériver son identifiant client attendu clientID_i, la clé de chiffrement clientKey_i, et le vecteur d’initialisation clientIV_i :

Puis le client recherche dans les données d’autorisation de la couche 1 une entrée contenant clientID_i. Si une entrée correspondante existe, le client la déchiffre pour obtenir authCookie :

Les deux mécanismes d’autorisation client ci-dessus fournissent une confidentialité pour l’appartenance aux clients. Une entité qui connaît uniquement la Destination peut voir combien de clients sont abonnés à tout moment, mais ne peut pas suivre quels clients sont ajoutés ou révoqués.

  • Chiffrer l’ensemble pour la sécurité
  • Chiffrer de manière sécurisée, pas seulement avec AES.
  • Chiffrer à chaque destinataire

Les serveurs DEVRAIENT randomiser l’ordre des clients chaque fois qu’ils génèrent un LS2 chiffré, pour empêcher les clients de connaître leur position dans la liste et d’inférer quand d’autres clients ont été ajoutés ou révoqués.

  • Une couche externe contenant les informations en clair nécessaires pour le stockage et la récupération.
  • Une couche intermédiaire qui gère l’authentification du client.
  • Une couche interne qui contient les données LS2 réelles.

Un serveur PEUT choisir de cacher le nombre de clients abonnés en insérant des entrées aléatoires dans la liste des données d’autorisation.

  • La clé publique de signature dans la destination non masquée doit être
    Ed25519 (type de signature 7) ou Red25519 (type de signature 11) ;
    aucun autre type de signature n’est supporté
  • Si la clé publique de signature est hors ligne, la clé publique de signature temporaire doit aussi être Ed25519
  • Le masquage est computationnellement simple
  • Utiliser des primitives cryptographiques existantes
  • Les clés publiques masquées ne peuvent pas être démascarquées
  • Les clés publiques masquées doivent être sur la courbe Ed25519 et dans le sous-groupe d’ordre premier
  • Doit connaître la clé publique de signature de la destination
    (destination complète non requise) pour dériver la clé publique masquée
  • Optionnellement fournir un secret supplémentaire requis pour dériver la clé publique masquée

Avantages de l’autorisation client DH ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  • La sécurité du schéma ne dépend pas uniquement de l’échange hors bande du matériel de clé client.
    La clé privée du client n’a jamais besoin de quitter son appareil, donc un
    adversaire capable d’intercepter l’échange hors bande, mais incapable de casser l’algorithme DH,
    ne peut pas déchiffrer le LS2 chiffré, ni déterminer combien de temps le client a accès.

LS chiffré avec adresses Base 32

Inconvénients de l’autorisation client DH ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Avantages de l’autorisation client PSK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

LS chiffré avec clés hors ligne

Inconvénients de l’autorisation client PSK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Voir proposition 149.

Vous ne pouvez pas utiliser un LS2 chiffré pour bittorrent, à cause des réponses compactes d’annonce qui font 32 octets. Les 32 octets contiennent uniquement le hachage. Il n’y a pas de place pour indiquer que le leaseset est chiffré, ou les types de signature.

Notes

  • Nécessite N + 1 opérations DH côté serveur pour N clients.

  • Nécessite une opération DH côté client.

  • Nécessite que le client génère la clé secrète.

  • Ne nécessite aucune opération DH.

  • Permet au serveur de générer la clé secrète.

  • Permet au serveur de partager la même clé avec plusieurs clients, si souhaité.

  • La sécurité du schéma dépend critique de l’échange hors bande du matériel de clé client.
    Un adversaire qui intercepte l’échange pour un client particulier peut déchiffrer
    tout LS2 chiffré ultérieur pour lequel ce client est autorisé, ainsi que déterminer
    quand l’accès du client est révoqué.

  • Un service utilisant des leasesets chiffrés publierait la version chiffrée aux
    floodfills. Cependant, par souci d’efficacité, il enverrait des leasesets non chiffrés aux
    clients dans le message garlic encapsulé, une fois authentifié (via liste blanche, par
    exemple).

  • Les floodfills peuvent limiter la taille maximale à une valeur raisonnable pour éviter les abus.

Meta LS2

Pour les leasesets chiffrés avec clés hors ligne, les clés privées masquées doivent également être générées hors ligne, une pour chaque jour.

Comme le bloc de signature hors ligne optionnel est dans la partie en clair du leaseset chiffré, n’importe qui scrapant les floodfills pourrait l’utiliser pour suivre le leaseset (mais pas le déchiffrer) sur plusieurs jours. Pour l’éviter, le propriétaire des clés devrait générer de nouvelles clés temporaires pour chaque jour également. Les clés temporaires et masquées peuvent être générées à l’avance, et livrées au routeur par lots.

Il n’y a pas de format de fichier défini dans cette proposition pour empaqueter plusieurs clés temporaires et masquées et les fournir au client ou au routeur. Il n’y a pas d’amélioration du protocole I2CP définie dans cette proposition pour supporter les leasesets chiffrés avec clés hors ligne.

Ceci est utilisé pour remplacer le multihébergement. Comme tout leaseset, ceci est signé par le créateur. C’est une liste authentifiée de hachages de destination.

Le Meta LS2 est le nœud supérieur, et éventuellement des nœuds intermédiaires, d’une structure en arbre. Il contient plusieurs entrées, chacune pointant vers un LS, LS2 ou un autre Meta LS2 pour supporter un multihébergement massif. Un Meta LS2 peut contenir un mélange d’entrées LS, LS2 et Meta LS2. Les feuilles de l’arbre sont toujours un LS ou LS2. L’arbre est un DAG ; les boucles sont interdites ; les clients effectuant des recherches doivent détecter et refuser de suivre les boucles.

Un Meta LS2 peut avoir une expiration beaucoup plus longue qu’un LS ou LS2 standard. Le niveau supérieur peut avoir une expiration plusieurs heures après la date de publication. Le temps d’expiration maximal sera appliqué par les floodfills et clients, et est à déterminer.

L’utilisation de Meta LS2 est le multihébergement massif, mais sans plus de protection contre la corrélation des routeurs aux leasesets (au redémarrage du routeur) que celle fournie actuellement avec LS ou LS2. Ceci équivaut au cas d’usage « facebook », qui n’a probablement pas besoin de protection contre la corrélation. Ce cas d’usage a probablement besoin de clés hors ligne, qui sont fournies dans l’en-tête standard à chaque nœud de l’arbre.

Le protocole backend pour la coordination entre les routeurs feuilles, les signataires intermédiaires et principaux de Meta LS n’est pas spécifié ici. Les exigences sont extrêmement simples - juste vérifier que le pair est en ligne, et publier un nouveau LS toutes les quelques heures. La seule complexité est pour choisir de nouveaux éditeurs pour les Meta LS de niveau supérieur ou intermédiaire en cas de panne.

Le mélange de leasesets où des locations de plusieurs routeurs sont combinées, signées et publiées dans un seul leaseset est documenté dans la proposition 140, « multihébergement invisible ». Cette proposition est irréalisable telle quelle, car les connexions en streaming ne seraient pas « collantes » à un seul routeur, voir http://zzz.i 2p/topics/2335 .

Le protocole backend, et l’interaction avec les composants internes du routeur et du client, serait très complexe pour le multihébergement invisible.

Standard LS flag (1)

Pour éviter de surcharger le floodfill pour le Meta LS de niveau supérieur, l’expiration devrait être d’au moins plusieurs heures. Les clients doivent mettre en cache le Meta LS de niveau supérieur, et le conserver entre les redémarrages s’il n’est pas expiré.

Meta LS2 type (7)

Nous devons définir un algorithme pour que les clients parcourent l’arbre, y compris des solutions de secours, afin que l’utilisation soit dispersée. Une fonction de distance de hachage, coût et aléatoire. Si un nœud a à la fois LS ou LS2 et Meta LS, nous devons savoir quand il est autorisé d’utiliser ces leasesets, et quand continuer à parcourir l’arbre.

Hash of destination
This hash is then used to generate the daily "routing key", as in LS1

Recherche avec

Hours. Max 18.2 hours (65535 seconds)

Stockage avec

"master" Destination or coordinator, or intermediate coordinators

Format

Standard LS2 Header as specified above

  Meta LS2 Type-Specific Part
  - Properties (Mapping as specified in common structures spec, 2 zero bytes if none)
  - Number of entries (1 byte) Maximum TBD
  - Entries. Each entry contains: (40 bytes)
    - Hash (32 bytes)
    - Flags (2 bytes)
      TBD. Set all to zero for compatibility with future uses.
    - Type (1 byte) The type of LS it is referencing;
      1 for LS, 3 for LS2, 5 for encrypted, 7 for meta, 0 for unknown.
    - Cost (priority) (1 byte)
    - Expires (4 bytes) (4 bytes, big endian, seconds since epoch, rolls over in 2106)
  - Number of revocations (1 byte) Maximum TBD
  - Revocations: Each revocation contains: (32 bytes)
    - Hash (32 bytes)

  Standard LS2 Signature:
  - Signature (40+ bytes)
    The signature is of everything above.

Stockage à

Notes

  • Après déchiffrement, plusieurs vérifications doivent être effectuées, notamment que
    l’horodatage interne et l’expiration correspondent à ceux du niveau supérieur.

  • ChaCha20 a été choisi plutôt qu’AES. Bien que les vitesses soient similaires si le
    support matériel AES est disponible, ChaCha20 est 2,5 à 3 fois plus rapide lorsque
    le support matériel AES n’est pas disponible, comme sur les appareils ARM bas de gamme.

  • Nous ne nous soucions pas assez de la vitesse pour utiliser BLAKE2b avec clé. Il a une taille de sortie
    suffisamment grande pour accommoder le plus grand n requis (ou nous pouvons l’appeler une fois par
    clé souhaitée avec un argument compteur). BLAKE2b est beaucoup plus rapide que SHA-256, et
    BLAKE2b avec clé réduirait le nombre total d’appels à la fonction de hachage.
    Cependant, voir la proposition 148, où il est proposé que nous passions à BLAKE2b pour d’autres raisons.
    Voir Secure key derivation performance .

Enregistrement de service

Expiration typique

Publié par

Flags et propriétés : pour usage futur

n/a, see Service List

Ceci est un enregistrement individuel indiquant qu’une destination participe à un service. Il est envoyé du participant au floodfill. Il n’est jamais envoyé individuellement par un floodfill, mais seulement comme partie d’une liste de service. L’enregistrement de service est également utilisé pour révoquer la participation à un service, en fixant l’ expiration à zéro.

Service Record type (9)

Ce n’est pas un LS2 mais il utilise le format d’en-tête et de signature standard LS2.

Hash of service name
This hash is then used to generate the daily "routing key", as in LS1

Recherche avec

Hours. Max 18.2 hours (65535 seconds)

Stockage avec

Destination

Format

Standard LS2 Header as specified above

  Service Record Type-Specific Part
  - Port (2 bytes, big endian) (0 if unspecified)
  - Hash of service name (32 bytes)

  Standard LS2 Signature:
  - Signature (40+ bytes)
    The signature is of everything above.

Notes

  • Un service distribué utilisant ceci aurait un ou plusieurs « maîtres » avec la
    clé privée de la destination du service. Ils détermineraient (hors bande) la
    liste actuelle des destinations actives et publieraient le Meta LS2. Pour
    la redondance, plusieurs maîtres pourraient multihéberger (c’est-à-dire publier simultanément) le
    Meta LS2.

  • Un service distribué pourrait commencer avec une destination unique ou utiliser le
    multihébergement ancien style, puis passer à un Meta LS2. Une recherche LS standard pourrait retourner
    n’importe lequel parmi LS, LS2 ou Meta LS2.

  • Lorsqu’un service utilise un Meta LS2, il n’a pas de tunnels (locations).

Liste de service

Stockage à

Expiration typique

Publié par

Ceci n’est rien comme un LS2 et utilise un format différent.

La liste de service est créée et signée par le floodfill. Elle est non authentifiée dans le sens où n’importe qui peut rejoindre un service en publiant un Enregistrement de service à un floodfill.

Une Liste de service contient des Enregistrements de service courts, pas des Enregistrements complets. Ceux-ci contiennent des signatures mais seulement des hachages, pas des destinations complètes, donc ils ne peuvent pas être vérifiés sans la destination complète.

Service List lookup type (11)

La sécurité, s’il y en a une, et la désirabilité des listes de service sont à déterminer. Les floodfills pourraient limiter la publication et les recherches à une liste blanche de services, mais cette liste blanche peut varier selon l’implémentation ou les préférences de l’opérateur. Il peut ne pas être possible d’atteindre un consensus sur une liste blanche commune de base entre les implémentations.

Service List type (11)

Si le nom du service est inclus dans l’enregistrement de service ci-dessus, les opérateurs de floodfill peuvent s’y opposer ; si seul le hachage est inclus, il n’y a pas de vérification, et un enregistrement de service pourrait « entrer » avant tout autre type netdb et être stocké dans le floodfill.

Hash of service name
This hash is then used to generate the daily "routing key", as in LS1

Recherche avec

Hours, not specified in the list itself, up to local policy

Stockage avec

Nobody, never sent to floodfill, never flooded.

Format

Stockage à

- Type (1 byte)
    Not actually in header, but part of data covered by signature.
    Take from field in Database Store Message.
  - Hash of the service name (implicit, in the Database Store message)
  - Hash of the Creator (floodfill) (32 bytes)
  - Published timestamp (8 bytes, big endian)

  - Number of Short Service Records (1 byte)
  - List of Short Service Records:
    Each Short Service Record contains (90+ bytes)
    - Dest hash (32 bytes)
    - Published timestamp (8 bytes, big endian)
    - Expires (4 bytes, big endian) (offset from published in ms)
    - Flags (2 bytes)
    - Port (2 bytes, big endian)
    - Sig length (2 bytes, big endian)
    - Signature of dest (40+ bytes)

  - Number of Revocation Records (1 byte)
  - List of Revocation Records:
    Each Revocation Record contains (86+ bytes)
    - Dest hash (32 bytes)
    - Published timestamp (8 bytes, big endian)
    - Flags (2 bytes)
    - Port (2 bytes, big endian)
    - Sig length (2 bytes, big endian)
    - Signature of dest (40+ bytes)

  - Signature of floodfill (40+ bytes)
    The signature is of everything above.

Expiration typique

  • Si l’expiration est à zéro, le floodfill devrait révoquer l’enregistrement et ne plus
    l’inclure dans la liste de service.

Publié par

  • Stockage : Le floodfill peut strictement limiter le stockage de ces enregistrements et
    limiter le nombre d’enregistrements stockés par hachage et leur expiration. Une liste blanche
    de hachages peut également être utilisée.

N’utilise PAS l’en-tête standard LS2 spécifié ci-dessus.

  • Tout autre type netdb au même hachage a priorité, donc un enregistrement de service ne peut jamais
    écraser un LS/RI, mais un LS/RI écrasera tous les enregistrements de service à ce hachage.

Notes

  • Nous utilisons la longueur de la signature plutôt que le sig type afin de pouvoir prendre en charge des types de signature inconnus.

  • Une liste de services n’expire pas ; les destinataires peuvent prendre leur propre décision en fonction de leur politique ou de l’expiration des enregistrements individuels.

  • Les listes de services ne sont pas inondées, seuls les enregistrements de service individuels le sont. Chaque floodfill crée, signe et met en cache une liste de services. Le floodfill applique sa propre politique pour la durée de cache et le nombre maximal d’enregistrements de service et de révocation.

Modifications requises de la Common Structures Spec

Certificats de clés

Hors périmètre de cette proposition. Ajouter aux propositions ECIES 144 et 145.

Nouvelles structures intermédiaires

Ajout de nouvelles structures pour Lease2, MetaLease, LeaseSet2Header et OfflineSignature. Effectif depuis la version 0.9.38.

Nouveaux types de NetDB

Ajouter des structures pour chaque nouveau type de leaseSet, intégrées depuis ci-dessus. Pour LeaseSet2, EncryptedLeaseSet et MetaLeaseSet, effectif à partir de la version 0.9.38. Pour Service Record et Service List, préliminaires et non planifiés.

Nouveau type de signature

Ajouter le type 11 RedDSA_SHA512_Ed25519. La clé publique est de 32 octets ; la clé privée est de 32 octets ; le hash est de 64 octets ; la signature est de 64 octets.

Modifications requises de la spécification de chiffrement

Hors du périmètre de cette proposition. Voir les propositions 144 et 145.

Modifications requises pour I2NP

Ajouter une note : LS2 ne peut être publié qu’auprès de floodfills disposant d’une version minimale.

Message de consultation de la base de données

Ajouter le type de recherche de liste de services.

Modifications

Flags byte: Lookup type field, currently bits 3-2, expands to bits 4-2.
  Lookup type 0x04 is defined as the service list lookup.

  Add note: Service list loookup may only be sent to floodfills with a minimum version.
  Minimum version is 0.9.38.

Message de stockage de base de données

Ajouter tous les nouveaux types de store.

Modifications

Type byte: Type field, currently bit 0, expands to bits 3-0.
  Type 3 is defined as a LS2 store.
  Type 5 is defined as a encrypted LS2 store.
  Type 7 is defined as a meta LS2 store.
  Type 9 is defined as a service record store.
  Type 11 is defined as a service list store.
  Other types are undefined and invalid.

  Add note: All new types may only be published to floodfills with a minimum version.
  Minimum version is 0.9.38.

Modifications requises pour I2CP

Options I2CP

Nouvelles options interprétées côté router, envoyées dans le SessionConfig Mapping :


  i2cp.leaseSetType=nnn       The type of leaseset to be sent in the Create Leaseset Message
                              Value is the same as the netdb store type in the table above.
                              Interpreted client-side, but also passed to the router in the
                              SessionConfig, to declare intent and check support.

  i2cp.leaseSetEncType=nnn[,nnn]  The encryption types to be used.
                                  Interpreted client-side, but also passed to the router in
                                  the SessionConfig, to declare intent and check support.
                                  See proposals 144 and 145.

  i2cp.leaseSetOfflineExpiration=nnn  The expiration of the offline signature, ASCII,
                                      seconds since the epoch.

  i2cp.leaseSetTransientPublicKey=[type:]b64  The base 64 of the transient private key,
                                              prefixed by an optional sig type number
                                              or name, default DSA_SHA1.
                                              Length as inferred from the sig type

  i2cp.leaseSetOfflineSignature=b64   The base 64 of the offline signature.
                                      Length as inferred from the destination
                                      signing public key type

  i2cp.leaseSetSecret=b64     The base 64 of a secret used to blind the
                              address of the leaseset, default ""

  i2cp.leaseSetAuthType=nnn   The type of authentication for encrypted LS2.
                              0 for no per-client authentication (the default)
                              1 for DH per-client authentication
                              2 for PSK per-client authentication

  i2cp.leaseSetPrivKey=b64    A base 64 private key for the router to use to
                              decrypt the encrypted LS2,
                              only if per-client authentication is enabled

Nouvelles options interprétées côté client :


  i2cp.leaseSetType=nnn     The type of leaseset to be sent in the Create Leaseset Message
                            Value is the same as the netdb store type in the table above.
                            Interpreted client-side, but also passed to the router in the
                            SessionConfig, to declare intent and check support.

  i2cp.leaseSetEncType=nnn[,nnn]  The encryption types to be used.
                                  Interpreted client-side, but also passed to the router in
                                  the SessionConfig, to declare intent and check support.
                                  See proposals 144 and 145.

  i2cp.leaseSetSecret=b64     The base 64 of a secret used to blind the
                              address of the leaseset, default ""

  i2cp.leaseSetAuthType=nnn       The type of authentication for encrypted LS2.
                                  0 for no per-client authentication (the default)
                                  1 for DH per-client authentication
                                  2 for PSK per-client authentication

  i2cp.leaseSetBlindedType=nnn   The sig type of the blinded key for encrypted LS2.
                                 Default depends on the destination sig type.

  i2cp.leaseSetClient.dh.nnn=b64name:b64pubkey   The base 64 of the client name (ignored, UI use only),
                                                 followed by a ':', followed by the base 64 of the public
                                                 key to use for DH per-client auth. nnn starts with 0

  i2cp.leaseSetClient.psk.nnn=b64name:b64privkey   The base 64 of the client name (ignored, UI use only),
                                                   followed by a ':', followed by the base 64 of the private
                                                   key to use for PSK per-client auth. nnn starts with 0

Configuration de session

Il convient de noter que pour les signatures hors ligne, les options i2cp.leaseSetOfflineExpiration, i2cp.leaseSetTransientPublicKey et i2cp.leaseSetOfflineSignature sont requises, et la signature est effectuée par la clé privée de signature transitoire.

Message de demande de LeaseSet

Router vers client. Aucun changement. Les leases sont envoyés avec des timestamps de 8 octets, même si le leaseSet retourné sera un LS2 avec des timestamps de 4 octets. Noter que la réponse peut être un message Create Leaseset ou Create Leaseset2.

Requête de message leaseset variable

Router vers client. Aucun changement. Les leases sont envoyés avec des timestamps de 8 octets, même si le leaseSet retourné sera un LS2 avec des timestamps de 4 octets. Noter que la réponse peut être un message Create Leaseset ou Create Leaseset2.

Créer un message Leaseset2

Client vers router. Nouveau message, à utiliser en remplacement de Create Leaseset Message.

Justification

Afin que le router puisse analyser le type de stockage, ce type doit être présent dans le message, à moins qu’il ne soit transmis au router au préalable dans la configuration de session. Pour le code d’analyse commun, il est plus simple de le trouver dans le message lui-même.

  • Pour que le router connaisse le type et la longueur de la clé privée, elle doit se trouver après le lease set, sauf si le parseur connaît le type au préalable dans la configuration de session. Pour du code de parsing courant, il est plus facile de le connaître à partir du message lui-même.

  • La clé privée de signature, précédemment définie pour la révocation et inutilisée, n’est pas présente dans LS2.

Type de message

Le type de message du message Create Leaseset2 est 41.

Format

Session ID
  Type byte: Type of lease set to follow
             Type 1 is a LS
             Type 3 is a LS2
             Type 5 is a encrypted LS2
             Type 7 is a meta LS2
  LeaseSet: type specified above
  Number of private keys to follow (1 byte)
  Encryption Private Keys: For each public key in the lease set,
                           in the same order
                           (Not present for Meta LS2)
                           - Encryption type (2 bytes, big endian)
                           - Encryption key length (2 bytes, big endian)
                           - Encryption key (number of bytes specified)

Notes

  • La version minimale du router est 0.9.39.
  • Une version préliminaire avec le type de message 40 était présente dans 0.9.38, mais le format a été modifié. Le type 40 est abandonné et n’est pas pris en charge.

Problèmes

  • D’autres changements sont nécessaires pour prendre en charge les LS chiffrés et les LS meta.

Message d’information sur le blinding

Du client au router. Nouveau message.

Justification

  • Le router doit savoir si une destination est aveuglée. Si elle est aveuglée et utilise une authentification secrète ou propre à chaque client, il doit également disposer de ces informations.

  • Un Host Lookup d’une adresse b32 au nouveau format (« b33 ») indique au router que l’adresse est aveuglée, mais il n’existe aucun mécanisme permettant de transmettre la clé secrète ou privée au router dans le message Host Lookup. Bien que l’on puisse étendre le message Host Lookup pour y ajouter cette information, il est plus propre de définir un nouveau message.

  • Nous avons besoin d’une approche programmatique permettant au client d’indiquer au router. Autrement, l’utilisateur devrait configurer manuellement chaque destination.

Utilisation

Avant qu’un client n’envoie un message à une destination aveuglée, il doit soit rechercher le « b33 » dans un message Host Lookup, soit envoyer un message Blinding Info. Si la destination aveuglée exige un secret ou une authentification par client, le client doit envoyer un message Blinding Info.

Le router n’envoie pas de réponse à ce message.

Type de message

Le type de message du Blinding Info Message est 42.

Format

Session ID
  Flags:       1 byte
               Bit order: 76543210
               Bit 0: 0 for everybody, 1 for per-client
               Bits 3-1: Authentication scheme, if bit 0 is set to 1 for per-client, otherwise 000
                         000: DH client authentication (or no per-client authentication)
                         001: PSK client authentication
               Bit 4: 1 if secret required, 0 if no secret required
               Bits 7-5: Unused, set to 0 for future compatibility
  Type byte:   Endpoint type to follow
               Type 0 is a Hash
               Type 1 is a host name String
               Type 2 is a Destination
               Type 3 is a Sig Type and Signing Public Key
  Blind Type:  2 byte blinded sig type (big endian)
  Expiration:  4 bytes, big endian, seconds since epoch
  Endpoint:    Data as specified above
               For type 0: 32 byte binary hash
               For type 1: host name String
               For type 2: binary Destination
               For type 3: 2 byte sig type (big endian)
                           Signing Public Key (length as implied by sig type)
  Private Key: Only if flag bit 0 is set to 1
               A 32-byte ECIES_X25519 private key
  Secret:      Only if flag bit 4 is set to 1
               A secret String

Notes

  • La version minimale du router est 0.9.43

Problèmes

Message de réponse de l’hôte (enc)

Pour prendre en charge les recherches de noms d’hôte « b33 » et renvoyer une indication si le router ne dispose pas des informations requises, nous définissons des codes de résultat supplémentaires pour le Host Reply Message, comme suit :

2: Lookup password required
   3: Private key required
   4: Lookup password and private key required
   5: Leaseset decryption failure

Les valeurs 1 à 255 sont déjà définies comme des erreurs, il n’y a donc pas de problème de rétrocompatibilité.

Message de redirection Meta

Router vers le client. Nouveau message.

Justification

Un client ne sait pas a priori qu’un Hash donné correspondra à un Meta LS.

Si une recherche de leaseset pour une Destination renvoie un Meta LS, le router effectue la résolution récursive. Pour les datagrammes, le côté client n’a pas besoin de le savoir ; toutefois, pour le streaming, où le protocole vérifie la destination dans le SYN ACK, il doit savoir quelle est la « vraie » destination. Par conséquent, un nouveau message est nécessaire.

Utilisation

Le router maintient un cache pour la destination réelle utilisée à partir d’un meta LS. Lorsqu’un client envoie un message à une destination qui se résout en un meta LS, le router vérifie le cache pour la destination réelle utilisée en dernier. Si le cache est vide, le router sélectionne une destination depuis le meta LS et recherche le leaseset. Si la recherche du leaseset réussit, le router ajoute cette destination au cache et envoie au client un Meta Redirect Message. Cette opération n’est effectuée qu’une seule fois, sauf si la destination expire et doit être changée. Le client doit également mettre en cache les informations si nécessaire. Le Meta Redirect Message n’est PAS envoyé en réponse à chaque SendMessage.

Le router n’envoie ce message qu’aux clients dont la version est 0.9.47 ou supérieure.

Le client n’envoie pas de réponse à ce message.

Type de message

Le type de message du Meta Redirect Message est 43.

Format

Session ID (2 bytes) The value from the Send Message.
  Message ID generated by the router (4 bytes)
  4 byte nonce previously generated by the client
               (the value from the Send Message, may be zero)
  Flags:       2 bytes, bit order 15...0
               Unused, set to 0 for future compatibility
               Bit 0: 0 - the destination is no longer meta
                      1 - the destination is now meta
               Bits 15-1: Unused, set to 0 for future compatibility
  Original Destination (387+ bytes)
  (following fields only present if flags bit 0 is 1)
  MFlags:      2 bytes
               Unused, set to 0 for future compatibility
               From the Meta Lease for the actual Destination
  Expiration:  4 bytes, big endian, seconds since epoch
               From the Meta Lease for the actual Destination
  Cost (priority) 1 byte
               From the Meta Lease for the actual Destination
  Actual (real) Destination (387+ bytes)

Modifications pour la prise en charge de Meta

La manière de générer et de prendre en charge Meta, y compris la communication et la coordination entre routers, ne relève pas du champ d’application de cette proposition. Voir la proposition connexe 150.

Modifications pour prendre en charge les clés hors ligne

Les signatures hors ligne ne peuvent être vérifiées ni dans le streaming ni dans les datagrammes avec réponse. Voir les sections ci-dessous.

Modifications requises du fichier de clé privée

Le format du fichier de clé privée (eepPriv.dat) ne fait pas partie officielle de nos spécifications, mais il est documenté dans les javadocs de Java I2P et d’autres implémentations le prennent en charge. Cela permet la portabilité des clés privées entre différentes implémentations.

Des modifications sont nécessaires pour stocker la clé publique transiente et les informations de signature hors ligne.

Modifications

If the signing private key is all zeros, the offline information section follows:

  - Expires timestamp
    (4 bytes, big endian, seconds since epoch, rolls over in 2106)
  - Sig type of transient Signing Public Key (2 bytes, big endian)
  - Transient Signing Public key
    (length as specified by transient sig type)
  - Signature of above three fields by offline key
    (length as specified by destination sig type)
  - Transient Signing Private key
    (length as specified by transient sig type)

Modifications requises de la CLI du fichier de clé privée

Ajouter la prise en charge des options suivantes :

-d days              (specify expiration in days of offline sig, default 365)
      -o offlinedestfile   (generate the online key file,
                            using the offline key file specified)
      -r sigtype           (specify sig type of transient key, default Ed25519)

Modifications du streaming requises

Les signatures hors ligne ne peuvent actuellement pas être vérifiées en streaming. La modification ci-dessous ajoute le bloc de signature hors ligne aux options. Cela évite de devoir récupérer cette information via I2CP.

Modifications

Add new option:
  Bit:          11
  Flag:         OFFLINE_SIGNATURE
  Option order: 4
  Option data:  Variable bytes
  Function:     Contains the offline signature section from LS2.
                FROM_INCLUDED must also be set.
                Expires timestamp
                (4 bytes, big endian, seconds since epoch, rolls over in 2106)
                Transient sig type (2 bytes, big endian)
                Transient signing public key (length as implied by sig type)
                Signature of expires timestamp, transient sig type,
                and public key, by the destination public key,
                length as implied by destination public key sig type.

  Change option:
  Bit:          3
  Flag:         SIGNATURE_INCLUDED
  Option order: Change from 4 to 5

  Add information about transient keys to the
  Variable Length Signature Notes section:
  The offline signature option does not needed to be added for a CLOSE packet if
  a SYN packet containing the option was previously acked.
  More info TODO

Notes

  • Une alternative consiste simplement à ajouter un flag, et à récupérer la clé publique transiente via I2CP (Voir les sections Host Lookup / Host Reply Message ci-dessus)

Modifications requises pour les datagrammes repliables

Les signatures hors ligne ne peuvent pas être vérifiées dans le traitement des datagrammes répondables. Il faudrait un flag pour indiquer une signature hors ligne, mais il n’y a nulle part où le placer. Cela nécessitera un tout nouveau numéro de protocole et un nouveau format.

Modifications

Define new protocol 19 - Repliable datagram with options?
  - Destination (387+ bytes)
  - Flags (2 bytes)
    Bit order: 15 14 ... 3 2 1 0
    Bit 0: If 0, no offline keys; if 1, offline keys
    Bits 1-15: set to 0 for compatibility with future uses
  - If flag indicates offline keys, the offline signature section:
    Expires timestamp
    (4 bytes, big endian, seconds since epoch, rolls over in 2106)
    Transient sig type (2 bytes, big endian)
    Transient signing public key (length as implied by sig type)
    Signature of expires timestamp, transient sig type,
    and public key, by the destination public key,
    length as implied by destination public key sig type.
    This section can, and should, be generated offline.
  - Data

Notes

  • L’alternative consiste simplement à ajouter un flag et à récupérer la clé publique transitoire via I2CP (Voir les sections Host Lookup / Host Reply Message ci-dessus)
  • Y a-t-il d’autres options que nous devrions ajouter maintenant que nous disposons d’octets de flag ?

Modifications requises pour SAM V3

SAM doit être amélioré pour prendre en charge les signatures hors ligne dans le DESTINATION en base 64.

Modifications

Note that in the SESSION CREATE DESTINATION=$privkey,
  the $privkey raw data (before base64 conversion)
  may be optionally followed by the Offline Signature as specified in the
  Common Structures Specification.

  If the signing private key is all zeros, the offline information section follows:

  - Expires timestamp
    (4 bytes, big endian, seconds since epoch, rolls over in 2106)
  - Sig type of transient Signing Public Key (2 bytes, big endian)
  - Transient Signing Public key
    (length as specified by transient sig type)
  - Signature of above three fields by offline key
    (length as specified by destination sig type)
  - Transient Signing Private key (length as specified by transient sig type)

Noter que les signatures hors ligne ne sont prises en charge que pour STREAM et RAW, et non pour DATAGRAM (jusqu’à ce qu’un nouveau protocole DATAGRAM soit défini).

Il est à noter que le SESSION STATUS renverra une Signing Private Key composée uniquement de zéros et les données Offline Signature exactement telles que fournies dans le SESSION CREATE.

Notez que DEST GENERATE et SESSION CREATE DESTINATION=TRANSIENT ne peuvent pas être utilisés pour créer une destination signée hors ligne.

Problèmes

Passer la version à 3.4, ou la laisser à 3.1/3.2/3.3 pour qu’elle puisse être ajoutée sans nécessiter tout ce qui concerne les versions 3.2/3.3 ?

Autres modifications à déterminer. Voir la section I2CP Host Reply Message ci-dessus.

Modifications requises pour BOB

BOB devrait être amélioré pour prendre en charge les signatures hors ligne et/ou Meta LS. Ceci est de faible priorité et ne sera probablement jamais spécifié ni implémenté. SAM V3 est l’interface préférée.

Publication, migration, compatibilité

LS2 (autre qu’un LS2 chiffré) est publié au même emplacement DHT que le LS1. Il n’existe aucun moyen de publier à la fois un LS1 et un LS2, à moins que le LS2 ne se trouve à un emplacement différent.

Le LS2 chiffré est publié à l’emplacement du hash du type de clé aveuglée et des données de clé. Ce hash est ensuite utilisé pour générer la « clé de routage » quotidienne, comme dans LS1.

LS2 ne serait utilisé que lorsque de nouvelles fonctionnalités sont requises (nouvelle cryptographie, LS chiffré, méta, etc.). LS2 ne peut être publié qu’auprès de floodfills d’une version spécifiée ou supérieure.

Les routeurs publiant des LS2 sauraient que tout client se connectant prend en charge LS2. Ils pourraient envoyer le LS2 dans le garlic.

Les clients n’enverraient des LS2 dans des garlics que s’ils utilisent la nouvelle crypto. Les clients partagés utiliseraient-ils LS1 indéfiniment ? TODO : comment avoir des clients partagés qui prennent en charge à la fois l’ancienne et la nouvelle crypto ?

Déploiement

0.9.38 inclut la prise en charge du floodfill pour LS2 standard, y compris les clés hors ligne.

La version 0.9.39 inclut la prise en charge I2CP de LS2 et d’Encrypted LS2, la signature/vérification avec le type de sig 11, la prise en charge floodfill pour Encrypted LS2 (types de sig 7 et 11, sans clés hors ligne), ainsi que le chiffrement/déchiffrement de LS2 (sans autorisation par client).

La version 0.9.40 doit inclure la prise en charge du chiffrement/déchiffrement des LS2 avec autorisation par client, la prise en charge de Meta LS2 par floodfill et I2CP, la prise en charge des LS2 chiffrés avec des clés hors ligne, ainsi que la prise en charge de b32 pour les LS2 chiffrés.

Remerciements

La conception du LS2 chiffré est fortement influencée par les descripteurs de services cachés v3 de Tor , qui poursuivaient des objectifs de conception similaires.

Références