Common structures Specification

Data types common to all I2P protocols

This document describes some data types common to all I2P protocols, like I2NP , I2CP , SSU , etc.

Common type specification

Integer

Description

Represents a non-negative integer.

Contents

1 to 8 bytes in network byte order (big endian) representing an unsigned integer.

Date

Description

The number of milliseconds since midnight on January 1, 1970 in the GMT timezone. If the number is 0, the date is undefined or null.

Contents

8 byte Integer

String

Description

Represents a UTF-8 encoded string.

Contents

1 or more bytes where the first byte is the number of bytes (not characters!) in the string and the remaining 0-255 bytes are the non-null terminated UTF-8 encoded character array. Length limit is 255 bytes (not characters). Length may be 0.

PublicKey

Description

This structure is used in ElGamal or other asymmetric encryption, representing only the exponent, not the primes, which are constant and defined in the cryptography specification ELGAMAL . Other encryption schemes are in the process of being defined, see the table below.

Contents

Key type and length are inferred from context or are specified in the Key Certificate of a Destination or RouterInfo, or the fields in a LeaseSet2 or other data structure. The default type is ElGamal. As of release 0.9.38, other types may be supported, depending on context. Keys are big-endian unless otherwise noted.

X25519 keys are supported in Destinations and LeaseSet2 as of release 0.9.44. X25519 keys are supported in RouterIdentities as of release 0.9.48.

TypeLength (bytes)SinceUsage
ElGamal256Deprecated for Router Identities as of 0.9.58; use for Destinations, as the public key field is unused there; discouraged for leasesets
P25664TBDReserved, see proposal 145
P38496TBDReserved, see proposal 145
P521132TBDReserved, see proposal 145
X25519320.9.38Little-endian. See ECIES and ECIES-ROUTERS
MLKEM512_X25519320.9.67See ECIES-HYBRID, for Leasesets only, not for RIs or Destinations
MLKEM768_X25519320.9.67See ECIES-HYBRID, for Leasesets only, not for RIs or Destinations
MLKEM1024_X25519320.9.67See ECIES-HYBRID, for Leasesets only, not for RIs or Destinations
MLKEM5128000.9.67See ECIES-HYBRID, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM76811840.9.67See ECIES-HYBRID, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM102415680.9.67See ECIES-HYBRID, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM512_CT7680.9.67See ECIES-HYBRID, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM768_CT10880.9.67See ECIES-HYBRID, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM1024_CT15680.9.67See ECIES-HYBRID, for handshakes only, not for Leasesets, RIs or Destinations

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/PublicKey.html

PrivateKey

Description

This structure is used in ElGamal or other asymmetric decryption, representing only the exponent, not the primes which are constant and defined in the cryptography specification ELGAMAL . Other encryption schemes are in the process of being defined, see the table below.

Contents

Key type and length are inferred from context or are stored separately in a data structure or a private key file. The default type is ElGamal. As of release 0.9.38, other types may be supported, depending on context. Keys are big-endian unless otherwise noted.

TypeLength (bytes)SinceUsage
ElGamal256Deprecated for Router Identities as of 0.9.58; use for Destinations, as the public key field is unused there; discouraged for leasesets
P25632TBDReserved, see proposal 145
P38448TBDReserved, see proposal 145
P52166TBDReserved, see proposal 145
X25519320.9.38Little-endian. See ECIES and ECIES-ROUTERS
MLKEM512_X25519320.9.67See ECIES-HYBRID, for Leasesets only, not for RIs or Destinations
MLKEM768_X25519320.9.67See ECIES-HYBRID, for Leasesets only, not for RIs or Destinations
MLKEM1024_X25519320.9.67See ECIES-HYBRID, for Leasesets only, not for RIs or Destinations
MLKEM51216320.9.67See ECIES-HYBRID, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM76824000.9.67See ECIES-HYBRID, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM102431680.9.67See ECIES-HYBRID, for handshakes only, not for Leasesets, RIs or Destinations

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/PrivateKey.html

SessionKey

Description

This structure is used for symmetric AES256 encryption and decryption.

Contents

32 bytes

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/SessionKey.html

SigningPublicKey

Description

This structure is used for verifying signatures.

Contents

Key type and length are inferred from context or are specified in the Key Certificate of a Destination. The default type is DSA_SHA1. As of release 0.9.12, other types may be supported, depending on context.

TypeLength (bytes)SinceUsage
DSA_SHA1128Deprecated for Router Identities as of 09.58; discouraged for Destinations
ECDSA_SHA256_P256640.9.12Deprecated Older Destinations
ECDSA_SHA384_P384960.9.12Deprecated Rarely used for Destinations
ECDSA_SHA512_P5211320.9.12Deprecated Rarely used for Destinations
RSA_SHA256_20482560.9.12Deprecated Offline signing, never used for Router Identities or Destinations
RSA_SHA384_30723840.9.12Deprecated Offline signing, never used for Router Identities or Destinations
RSA_SHA512_40965120.9.12Offline signing, never used for Router Identities or Destinations
EdDSA_SHA512_Ed25519320.9.15Recent Router Identities and Destinations
EdDSA_SHA512_Ed25519ph320.9.25Offline signing, never used for Router Identities or Destinations
RedDSA_SHA512_Ed25519320.9.39For Destinations and encrypted leasesets only, never used for Router Identities

Notes

  • When a key is composed of two elements (for example points X,Y), it is serialized by padding each element to length/2 with leading zeros if necessary.

  • All types are Big Endian, except for EdDSA and RedDSA, which are stored and transmitted in a Little Endian format.

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/SigningPublicKey.html

SigningPrivateKey

Description

This structure is used for creating signatures.

Contents

Key type and length are specified when created. The default type is DSA_SHA1. As of release 0.9.12, other types may be supported, depending on context.

TypeLength (bytes)SinceUsage
DSA_SHA120Deprecated for Router Identities as of 09.58; discouraged for Destinations
ECDSA_SHA256_P256320.9.12Deprecated Older Destinations
ECDSA_SHA384_P384480.9.12Deprecated Rarely used for Destinations
ECDSA_SHA512_P521660.9.12Deprecated Rarely used for Destinations
RSA_SHA256_20485120.9.12Deprecated Offline signing, never used for Router Identities or Destinations
RSA_SHA384_30727680.9.12Deprecated Offline signing, never used for Router Identities or Destinations
RSA_SHA512_409610240.9.12Offline signing, never used for Router Identities or Destinations
EdDSA_SHA512_Ed25519320.9.15Recent Router Identities and Destinations
EdDSA_SHA512_Ed25519ph320.9.25Offline signing, never used for Router Identities or Destinations
RedDSA_SHA512_Ed25519320.9.39For Destinations and encrypted leasesets only, never used for Router Identities

Notes

  • When a key is composed of two elements (for example points X,Y), it is serialized by padding each element to length/2 with leading zeros if necessary.

  • All types are Big Endian, except for EdDSA and RedDSA, which are stored and transmitted in a Little Endian format.

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/SigningPrivateKey.html

Signature

Description

This structure represents the signature of some data.

Contents

Signature type and length are inferred from the type of key used. The default type is DSA_SHA1. As of release 0.9.12, other types may be supported, depending on context.

TypeLength (bytes)SinceUsage
DSA_SHA140Deprecated for Router Identities as of 09.58; discouraged for Destinations
ECDSA_SHA256_P256640.9.12Deprecated Older Destinations
ECDSA_SHA384_P384960.9.12Deprecated Rarely used for Destinations
ECDSA_SHA512_P5211320.9.12Deprecated Rarely used for Destinations
RSA_SHA256_20482560.9.12Deprecated Offline signing, never used for Router Identities or Destinations
RSA_SHA384_30723840.9.12Deprecated Offline signing, never used for Router Identities or Destinations
RSA_SHA512_40965120.9.12Offline signing, never used for Router Identities or Destinations
EdDSA_SHA512_Ed25519640.9.15Recent Router Identities and Destinations
EdDSA_SHA512_Ed25519ph640.9.25Offline signing, never used for Router Identities or Destinations
RedDSA_SHA512_Ed25519640.9.39For Destinations and encrypted leasesets only, never used for Router Identities

Notes

  • When a signature is composed of two elements (for example values R,S), it is serialized by padding each element to length/2 with leading zeros if necessary.

  • All types are Big Endian, except for EdDSA and RedDSA, which are stored and transmitted in a Little Endian format.

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/Signature.html

Hash

Description

Represents the SHA256 of some data.

Contents

32 bytes

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/Hash.html

Session Tag

Note: Session Tags for ECIES-X25519 destinations (ratchet) and ECIES-X25519 routers are 8 bytes. See ECIES and ECIES-ROUTERS .

Description

A random number

Contents

32 bytes

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/SessionTag.html

TunnelId

Description

Defines an identifier that is unique to each router in a tunnel. A Tunnel ID is generally greater than zero; do not use a value of zero except in special cases.

Contents

4 byte Integer

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/TunnelId.html

Certificate

Description

A certificate is a container for various receipts or proof of works used throughout the I2P network.

Contents

1 byte Integer specifying certificate type, followed by a 2 byte Integer specifying the size of the certificate payload, then that many bytes.

+----+----+----+----+----+-/
|type| length  | payload
+----+----+----+----+----+-/

type :: Integer
        length -> 1 byte

length :: Integer
          length -> 2 bytes

payload :: data
           length -> $length bytes

Notes

  • For Router Identities , the Certificate is always NULL through version 0.9.15. As of 0.9.16, a Key Certificate is used to specify the key types. As of 0.9.48, X25519 encryption public key types are allowed. See below.

  • For Garlic Cloves , the Certificate is always NULL, no others are currently implemented.

  • For Garlic Messages , the Certificate is always NULL, no others are currently implemented.

  • For Destinations , the Certificate may be non-NULL. As of 0.9.12, a Key Certificate may be used to specify the signing public key type. See below.

  • Implementers are cautioned to prohibit excess data in Certificates. The appropriate length for each certificate type should be enforced.

Certificate Types

The following certificate types are defined:

TypeType CodePayload LengthTotal LengthNotes
Null003
HashCash1variesvariesDeprecated, unused. Payload contains an ASCII colon-separated hashcash string.
Hidden203Deprecated, unused. Hidden routers generally do not announce that they are hidden.
Signed340 or 7243 or 75Deprecated, unused. Payload contains a 40-byte DSA signature, optionally followed by the 32-byte Hash of the signing Destination.
Multiple4variesvariesDeprecated, unused. Payload contains multiple certificates.
Key54+7+Since 0.9.12. See below for details.

Key Certificates

Key certificates were introduced in release 0.9.12. Prior to that release, all PublicKeys were 256-byte ElGamal keys, and all SigningPublicKeys were 128-byte DSA-SHA1 keys. A key certificate provides a mechanism to indicate the type of the PublicKey and SigningPublicKey in the Destination or RouterIdentity, and to package any key data in excess of the standard lengths.

By maintaining exactly 384 bytes before the certificate, and putting any excess key data inside the certificate, we maintain compatibility for any software that parses Destinations and Router Identities.

The key certificate payload contains:

DataLength
Signing Public Key Type (Integer)2
Crypto Public Key Type (Integer)2
Excess Signing Public Key Data0+
Excess Crypto Public Key Data0+

Warning: The key type order is the opposite of what you may expect; the Signing Public Key Type is first.

The defined Signing Public Key types are:

TypeType CodeTotal Public Key LengthSinceUsage
DSA_SHA101280.9.12Deprecated for Router Identities as of 0.9.58; discouraged for Destinations
ECDSA_SHA256_P2561640.9.12Deprecated Older Destinations
ECDSA_SHA384_P3842960.9.12Deprecated Rarely if ever used for Destinations
ECDSA_SHA512_P52131320.9.12Deprecated Rarely if ever used for Destinations
RSA_SHA256_204842560.9.12Deprecated Offline only; never used in Key Certificates for Router Identities or Destinations
RSA_SHA384_307253840.9.12Deprecated Offline only; never used in Key Certificates for Router Identities or Destinations
RSA_SHA512_409665120.9.12Offline only; never used in Key Certificates for Router Identities or Destinations
EdDSA_SHA512_Ed255197320.9.15Recent Router Identities and Destinations
EdDSA_SHA512_Ed25519ph8320.9.25Offline only; never used in Key Certificates for Router Identities or Destinations
reserved (GOST)964Reserved, see Prop134
reserved (GOST)10128Reserved, see Prop134
RedDSA_SHA512_Ed2551911320.9.39For Destinations and encrypted leasesets only; never used for Router Identities
reserved (MLDSA)12Reserved, see Prop169
reserved (MLDSA)13Reserved, see Prop169
reserved (MLDSA)14Reserved, see Prop169
reserved (MLDSA)15Reserved, see Prop169
reserved (MLDSA)16Reserved, see Prop169
reserved (MLDSA)17Reserved, see Prop169
reserved (MLDSA)18Reserved, see Prop169
reserved (MLDSA)19Reserved, see Prop169
reserved (MLDSA)20Reserved, see Prop169
reserved65280-65534Reserved for experimental use
reserved65535Reserved for future expansion

The defined Crypto Public Key types are:

TypeType CodeTotal Public Key LengthSinceUsage
ElGamal0256Deprecated for Router Identities as of 0.9.58; use for Destinations, as the public key field is unused there
P256164Reserved, see proposal 145
P384296Reserved, see proposal 145
P5213132Reserved, see proposal 145
X255194320.9.38See ECIES and proposal 156
MLKEM512_X255195320.9.67See ECIES-HYBRID, for Leasesets only, not for RIs or Destinations
MLKEM768_X255196320.9.67See ECIES-HYBRID, for Leasesets only, not for RIs or Destinations
MLKEM1024_X255197320.9.67See ECIES-HYBRID, for Leasesets only, not for RIs or Destinations
reserved (NONE)255Reserved, see Prop169
reserved65280-65534Reserved for experimental use
reserved65535Reserved for future expansion

When a Key Certificate is not present, the preceeding 384 bytes in the Destination or RouterIdentity are defined as the 256-byte ElGamal PublicKey followed by the 128-byte DSA-SHA1 SigningPublicKey. When a Key Certificate is present, the preceeding 384 bytes are redefined as follows:

  • Complete or first portion of Crypto Public Key

  • Random padding if the total lengths of the two keys are less than 384 bytes

  • Complete or first portion of Signing Public Key

The Crypto Public Key is aligned at the start and the Signing Public Key is aligned at the end. The padding (if any) is in the middle. The lengths and boundaries of the initial key data, the padding, and the excess key data portions in the certificates are not explicitly specified, but are derived from the lengths of the specified key types. If the total lengths of the Crypto and Signing Public Keys exceed 384 bytes, the remainder will be contained in the Key Certificate. If the Crypto Public Key length is not 256 bytes, the method for determining the boundary between the two keys is to be specified in a future revision of this document.

Example layouts using an ElGamal Crypto Public Key and the Signing Public Key type indicated:

Signing Key TypePadding LengthExcess Signing Key Data in Cert
DSA_SHA100
ECDSA_SHA256_P256640
ECDSA_SHA384_P384320
ECDSA_SHA512_P52104
RSA_SHA256_20480128
RSA_SHA384_30720256
RSA_SHA512_40960384
EdDSA_SHA512_Ed25519960
EdDSA_SHA512_Ed25519ph960

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/Certificate.html

Notes

  • Implementers are cautioned to prohibit excess data in Key Certificates. The appropriate length for each certificate type should be enforced.

  • A KEY certificate with types 0,0 (ElGamal,DSA_SHA1) is allowed but discouraged. It is not well-tested and may cause issues in some implementations. Use a NULL certificate in the canonical representation of a (ElGamal,DSA_SHA1) Destination or RouterIdentity, which will be 4 bytes shorter than using a KEY certificate.

Mapping

Description

A set of key/value mappings or properties

Contents

A 2-byte size Integer followed by a series of String=String; pairs.

WARNING: Most uses of Mapping are in signed structures, where the Mapping entries must be sorted by key, so the signature is immutable. Failure to sort by key will result in signature failures!

Mapping Structure

Notes

  • The encoding isn’t optimal - we either need the ‘=’ and ‘;’ characters, or the string lengths, but not both

  • Some documentation says that the strings may not include ‘=’ or ‘;’ but this encoding supports them

  • Strings are defined to be UTF-8 but in the current implementation, I2CP uses UTF-8 but I2NP does not. For example, UTF-8 strings in a RouterInfo options mapping in a I2NP Database Store Message will be corrupted.

  • The encoding allows duplicate keys, however in any usage where the mapping is signed, duplicates may cause a signature failure.

  • Mappings contained in I2NP messages (e.g. in a RouterAddress or RouterInfo) must be sorted by key so that the signature will be invariant. Duplicate keys are not allowed.

  • Mappings contained in an I2CP SessionConfig must be sorted by key so that the signature will be invariant. Duplicate keys are not allowed.

  • The sort method is defined as in Java String.compareTo(), using the Unicode value of the characters.

  • While it is application-dependent, keys and values are generally case-sensitive.

  • Key and value string length limits are 255 bytes (not characters) each, plus the length byte. Length byte may be 0.

  • Total length limit is 65535 bytes, plus the 2 byte size field, or 65537 total.

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/DataHelper.html

Common structure specification

KeysAndCert

Description

An encryption public key, a signing public key, and a certificate, used as either a RouterIdentity or a Destination.

Contents

A PublicKey followed by a SigningPublicKey and then a Certificate .

KeysAndCert Structure

Padding Generation Guidelines

These guidelines were proposed in Proposal 161 and implemented in API version 0.9.57. These guidelines are backward-compatible with all versions since 0.6 (2005). See Proposal 161 for background and further information.

For any currently-used combination of key types other than ElGamal + DSA-SHA1, padding will be present. Additionally, for destinations, the 256-byte public key field has been unused since version 0.6 (2005).

Implementers should generate the random data for Destination public keys, and Destination and Router Identity padding, so that it is compressible in various I2P protocols while still being secure, and without having Base 64 representations appear to be corrupt or insecure. This provides most of the benefits of removing the padding fields without any disruptive protocol changes.

Strictly speaking, the 32-byte signing public key alone (in both Destinations and Router Identities) and the 32-byte encryption public key (in Router Identities only) is a random number that provides all the entropy necessary for the SHA-256 hashes of these structures to be cryptographically strong and randomly distributed in the network database DHT.

However, out of an abundance of caution, we recommend a minimum of 32 bytes of random data be used in the ElG public key field and padding. Additionally, if the fields were all zeros, Base 64 destinations would contain long runs of AAAA characters, which may cause alarm or confusion to users.

Repeat the 32 bytes of random data as necessary so the full KeysAndCert structure is highly compressible in I2P protocols such as I2NP Database Store Message, Streaming SYN, SSU2 handshake, and repliable Datagrams.

Examples:

  • A Router Identity with X25519 encryption type and Ed25519 signature type will contain 10 copies (320 bytes) of the random data, for a savings of approximately 288 bytes when compressed.

  • A Destination with Ed25519 signature type will contain 11 copies (352 bytes) of the random data, for a savings of approximately 320 bytes when compressed.

Implementations must, of course, store the full 387+ byte structure because the SHA-256 hash of the structure covers the full contents.

Notes

  • Do not assume that these are always 387 bytes! They are 387 bytes plus the certificate length specified at bytes 385-386, which may be non-zero.

  • As of release 0.9.12, if the certificate is a Key Certificate, the boundaries of the key fields may vary. See the Key Certificate section above for details.

  • The Crypto Public Key is aligned at the start and the Signing Public Key is aligned at the end. The padding (if any) is in the middle.

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/KeysAndCert.html

RouterIdentity

Description

Defines the way to uniquely identify a particular router

Contents

Identical to KeysAndCert.

See KeysAndCert for guidelines on generating the random data for the padding field.

Notes

  • The certificate for a RouterIdentity was always NULL until release 0.9.12.

  • Do not assume that these are always 387 bytes! They are 387 bytes plus the certificate length specified at bytes 385-386, which may be non-zero.

  • As of release 0.9.12, if the certificate is a Key Certificate, the boundaries of the key fields may vary. See the Key Certificate section above for details.

  • The Crypto Public Key is aligned at the start and the Signing Public Key is aligned at the end. The padding (if any) is in the middle.

  • RouterIdentities with a key certificate and a ECIES_X25519 public key are supported as of release 0.9.48. Prior to that, all RouterIdentities were ElGamal.

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/router/RouterIdentity.html

Destination

Description

A Destination defines a particular endpoint to which messages can be directed for secure delivery.

Contents

Identical to KeysAndCert , except that the public key is never used, and may contain random data instead of a valid ElGamal Public Key.

See KeysAndCert for guidelines on generating the random data for the public key and padding fields.

Notes

  • The public key of the destination was used for the old i2cp-to-i2cp encryption which was disabled in version 0.6 (2005), it is currently unused except for the IV for LeaseSet encryption, which is deprecated. The public key in the LeaseSet is used instead.

  • Do not assume that these are always 387 bytes! They are 387 bytes plus the certificate length specified at bytes 385-386, which may be non-zero.

  • As of release 0.9.12, if the certificate is a Key Certificate, the boundaries of the key fields may vary. See the Key Certificate section above for details.

  • The Crypto Public Key is aligned at the start and the Signing Public Key is aligned at the end. The padding (if any) is in the middle.

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/Destination.html

Lease

Description

Defines the authorization for a particular tunnel to receive messages targeting a Destination .

Contents

SHA256 Hash of the RouterIdentity of the gateway router, then the TunnelId , and finally an end Date .

Lease Structure

Notes

  • Total size: 44 bytes

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/Lease.html

LeaseSet

Description

Contains all of the currently authorized Leases for a particular Destination , the PublicKey to which garlic messages can be encrypted, and then the SigningPublicKey that can be used to revoke this particular version of the structure. The LeaseSet is one of the two structures stored in the network database (the other being RouterInfo ), and is keyed under the SHA256 of the contained Destination .

Contents

Destination , followed by a PublicKey for encryption, then a SigningPublicKey which can be used to revoke this version of the LeaseSet, then a 1 byte Integer specifying how many Lease structures are in the set, followed by the actual Lease structures and finally a Signature of the previous bytes signed by the Destination ’s SigningPrivateKey .

LeaseSet Structure

Notes

  • The public key of the destination was used for the old I2CP-to-I2CP encryption which was disabled in version 0.6, it is currently unused.

  • The encryption key is used for end-to-end ElGamal/AES+SessionTag encryption ELGAMAL-AES . It is currently generated anew at every router startup, it is not persistent.

  • The signature may be verified using the signing public key of the destination.

  • A LeaseSet with zero Leases is allowed but is unused. It was intended for LeaseSet revocation, which is unimplemented. All LeaseSet2 variants require at least one Lease.

  • The signing_key is currently unused. It was intended for LeaseSet revocation, which is unimplemented. It is currently generated anew at every router startup, it is not persistent. The signing key type is always the same as the destination’s signing key type.

  • The earliest expiration of all the Leases is treated as the timestamp or version of the LeaseSet. Routers will generally not accept a store of a LeaseSet unless it is “newer” than the current one. Take care when publishing a new LeaseSet where the oldest Lease is the same as the oldest Lease in the previous LeaseSet. The publishing router should generally increment the expiration of the oldest Lease by at least 1 ms in that case.

  • Prior to release 0.9.7, when included in a DatabaseStore Message sent by the originating router, the router set all the published leases’ expirations to the same value, that of the earliest lease. As of release 0.9.7, the router publishes the actual lease expiration for each lease. This is an implementation detail and not part of the structures specification.

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/LeaseSet.html

Lease2

Description

Defines the authorization for a particular tunnel to receive messages targeting a Destination . Same as Lease but with a 4-byte end_date. Used by LeaseSet2 . Supported as of 0.9.38; see proposal 123 for more information.

Contents

SHA256 Hash of the RouterIdentity of the gateway router, then the TunnelId , and finally a 4 byte end date.

+----+----+----+----+----+----+----+----+
| tunnel_gw                             |
+                                       +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|     tunnel_id     |      end_date     |
+----+----+----+----+----+----+----+----+

tunnel_gw :: Hash of the `RouterIdentity` of the tunnel gateway
             length -> 32 bytes

tunnel_id :: `TunnelId`
             length -> 4 bytes

end_date :: 4 byte date
            length -> 4 bytes
            Seconds since the epoch, rolls over in 2106.

Notes

  • Total size: 40 bytes

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/Lease2.html

OfflineSignature

Description

This is an optional part of the LeaseSet2Header . Also used in streaming and I2CP. Supported as of 0.9.38; see proposal 123 for more information.

Contents

Contains an expiration, a sigtype and transient SigningPublicKey , and a Signature .

+----+----+----+----+----+----+----+----+
|     expires       | sigtype |         |
+----+----+----+----+----+----+         +
|       transient_public_key            |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
|           signature                   |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+

expires :: 4 byte date
           length -> 4 bytes
           Seconds since the epoch, rolls over in 2106.

sigtype :: 2 byte type of the transient_public_key
           length -> 2 bytes

transient_public_key :: `SigningPublicKey`
                        length -> As inferred from the sigtype

signature :: `Signature`
             length -> As inferred from the sigtype of the signing public key
                       in the `Destination` that preceded this offline signature.
             Signature of expires timestamp, transient sig type, and public key,
             by the destination public key.

Notes

  • This section can, and should, be generated offline.

LeaseSet2Header

Description

This is the common part of the LeaseSet2 and MetaLeaseSet . Supported as of 0.9.38; see proposal 123 for more information.

Contents

Contains the Destination , two timestamps, and an optional OfflineSignature .

+----+----+----+----+----+----+----+----+
| destination                           |
+                                       +
|                                       |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
|     published     | expires |  flags  |
+----+----+----+----+----+----+----+----+
| offline_signature (optional)          |
+                                       +
|                                       |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+

destination :: `Destination`
               length -> >= 387+ bytes

published :: 4 byte date
             length -> 4 bytes
             Seconds since the epoch, rolls over in 2106.

expires :: 2 byte time
           length -> 2 bytes
           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 15-3: set to 0 for compatibility with future uses

offline_signature :: `OfflineSignature`
                     length -> varies
                     Optional, only present if bit 0 is set in the flags.

Notes

  • Total size: 395 bytes minimum

  • Maximum actual expires time is about 660 (11 minutes) for LeaseSet2 and 65535 (the full 18.2 hours) for MetaLeaseSet .

  • LeaseSet (1) did not have a ‘published’ field, so versioning required a search for the earliest lease. LeaseSet2 adds a ‘published’ field with a resolution of one second. Routers should rate-limit sending new leasesets to floodfills to a rate much slower than once a second (per destination). If this is not implemented, then the code must ensure that each new leaseset has a ‘published’ time at least one second later than the one before, or else floodills will not store or flood the new leaseset.

LeaseSet2

Description

Contained in a I2NP DatabaseStore message of type 3. Supported as of 0.9.38; see proposal 123 for more information.

Contains all of the currently authorized Lease2 for a particular Destination , and the PublicKey to which garlic messages can be encrypted. A LeaseSet is one of the two structures stored in the network database (the other being RouterInfo ), and is keyed under the SHA256 of the contained Destination .

Contents

LeaseSet2Header , followed by a options, then one or more PublicKey for encryption, Integer specifying how many Lease2 structures are in the set, followed by the actual Lease2 structures and finally a Signature of the previous bytes signed by the Destination ’s SigningPrivateKey or the transient key.

+----+----+----+----+----+----+----+----+
|         ls2_header                    |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
|          options                      |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
|numk| keytype0| keylen0 |              |
+----+----+----+----+----+              +
|          encryption_key_0             |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
| keytypen| keylenn |                   |
+----+----+----+----+                   +
|          encryption_key_n             |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
| num| Lease2 0                         |
+----+                                  +
|                                       |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
| Lease2($num-1)                        |
+                                       +
|                                       |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
| signature                             |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+

ls2header :: `LeaseSet2Header`
             length -> varies

options :: `Mapping`
           length -> varies, 2 bytes minimum

numk :: `Integer`
        length -> 1 byte
        Number of key types, key lengths, and `PublicKey`s to follow
        value: 1 <= numk <= max TBD

keytype :: The encryption type of the `PublicKey` to follow.
           length -> 2 bytes

keylen :: The length of the `PublicKey` to follow.
          Must match the specified length of the encryption type.
          length -> 2 bytes

encryption_key :: `PublicKey`
                  length -> keylen bytes

num :: `Integer`
       length -> 1 byte
       Number of `Lease2`s to follow
       value: 0 <= num <= 16

leases :: [`Lease2`]
          length -> $num*40 bytes

signature :: `Signature`
             length -> 40 bytes or as specified in destination's key
                       certificate, or by the sigtype of the transient public key,
                       if present in the header

Encryption Key Preference

For published (server) leasesets, the encryption keys are in order of server preference, most-preferred first. If clients support more than one encryption type, it is recommended that they honor the server preference and select the first supported type as the encryption method to use to connect to the server. Generally, the newer (higher-numbered) key types are more secure or efficient and are preferred, so the keys should be listed in reverse order of key type.

However, clients may, implementation-dependent, select based on their preference instead, or use some method to determine the “combined” preference. This may be useful as a configuration option, or for debugging.

The key order in unpublished (client) leasesets effectively does not matter, because connections will usually not be attempted to unpublished clients. Unless this order is used to determine a combined preference, as described above.

Options

As of API 0.9.66, a standard format for service record options is defined. See proposal 167 for details. Options other than service records, using a different format, may be defined in the future.

LS2 options MUST be sorted by key, so the signature is invariant.

Service record options are defined as follows:

  • serviceoption := optionkey optionvalue
  • optionkey := _service._proto
  • service := The symbolic name of the desired service. Must be lower case. Example: “smtp”. Allowed chars are [a-z0-9-] and must not start or end with a ‘-’. Standard identifiers from REGISTRY or Linux /etc/services must be used if defined there.
  • proto := The transport protocol of the desired service. Must be lower case, either “tcp” or “udp”. “tcp” means streaming and “udp” means repliable datagrams. Protocol indicators for raw datagrams and datagram2 may be defined later. Allowed chars are [a-z0-9-] and must not start or end with a ‘-’.
  • optionvalue := self | srvrecord[,srvrecord]*
  • self := “0” ttl port [appoptions]
  • srvrecord := “1” ttl priority weight port target [appoptions]
  • ttl := time to live, integer seconds. Positive integer. Example: “86400”. A minimum of 86400 (one day) is recommended, see Recommendations section below for details.
  • priority := The priority of the target host, lower value means more preferred. Non-negative integer. Example: “0” Only useful if more than one record, but required even if just one record.
  • weight := A relative weight for records with the same priority. Higher value means more chance of getting picked. Non-negative integer. Example: “0” Only useful if more than one record, but required even if just one record.
  • port := The I2CP port on which the service is to be found. Non-negative integer. Example: “25” Port 0 is supported but not recommended.
  • target := The hostname or b32 of the destination providing the service. A valid hostname as in NAMING . Must be lower case. Example: “aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p” or “example.i2p”. b32 is recommended unless the hostname is “well known”, i.e. in official or default address books.
  • appoptions := arbitrary text specific to the application, must not contain " " or “,”. Encoding is UTF-8.

Examples:

In LS2 for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p, pointing to one SMTP server:

“_smtp._tcp” “1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p”

In LS2 for aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p, pointing to two SMTP servers:

“_smtp._tcp” “1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p,86400 1 0 25 cccccccccccccccccccccccccccccccccccccccccccc.b32.i2p”

In LS2 for bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p, pointing to itself as a SMTP server:

“_smtp._tcp” “0 999999 25”

Notes

  • The public key of the destination was used for the old I2CP-to-I2CP encryption which was disabled in version 0.6, it is currently unused.

  • The encryption keys are used for end-to-end ElGamal/AES+SessionTag encryption ELGAMAL-AES (type 0) or other end-to-end encryption schemes. See ECIES and proposals 145 and 156. They may be generated anew at every router startup or they may be persistent. X25519 (type 4, see ECIES ) is supported as of release 0.9.44.

  • The signature is over the data above, PREPENDED with the single byte containing the DatabaseStore type (3).

  • The signature may be verified using the signing public key of the destination, or the transient signing public key, if an offline signature is included in the leaseset2 header.

  • The key length is provided for each key, so that floodfills and clients may parse the structure even if not all encryption types are known or supported.

  • See note on the ‘published’ field in LeaseSet2Header

  • The options mapping, if the size is greater than one, must be sorted by key, so the signature is invariant.

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/LeaseSet2.html

MetaLease

Description

Defines the authorization for a particular tunnel to receive messages targeting a Destination . Same as Lease2 but with flags and cost instead of a tunnel id. Used by MetaLeaseSet . Contained in a I2NP DatabaseStore message of type 7. Supported as of 0.9.38; see proposal 123 for more information.

Contents

SHA256 Hash of the RouterIdentity of the gateway router, then flags and cost, and finally a 4 byte end date.

+----+----+----+----+----+----+----+----+
| tunnel_gw                             |
+                                       +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|    flags     |cost|      end_date     |
+----+----+----+----+----+----+----+----+

tunnel_gw :: Hash of the `RouterIdentity` of the tunnel gateway,
             or the hash of another `MetaLeaseSet`.
             length -> 32 bytes

flags :: 3 bytes of flags
         Bit order: 23 22 ... 3 2 1 0
         Bits 3-0: Type of the entry.
         If 0, unknown.
         If 1, a `LeaseSet`.
         If 3, a `LeaseSet2`.
         If 5, a `MetaLeaseSet`.
         Bits 23-4: set to 0 for compatibility with future uses
         length -> 3 bytes

cost :: 1 byte, 0-255. Lower value is higher priority.
        length -> 1 byte

end_date :: 4 byte date
            length -> 4 bytes
            Seconds since the epoch, rolls over in 2106.

Notes

  • Total size: 40 bytes

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/MetaLease.html

MetaLeaseSet

Description

Contained in a I2NP DatabaseStore message of type 7. Defined as of 0.9.38; scheduled to be working as of 0.9.40; see proposal 123 for more information.

Contains all of the currently authorized MetaLease for a particular Destination , and the PublicKey to which garlic messages can be encrypted. A LeaseSet is one of the two structures stored in the network database (the other being RouterInfo ), and is keyed under the SHA256 of the contained Destination .

Contents

LeaseSet2Header , followed by a options, Integer specifying how many Lease2 structures are in the set, followed by the actual Lease2 structures and finally a Signature of the previous bytes signed by the Destination ’s SigningPrivateKey or the transient key.

+----+----+----+----+----+----+----+----+
|         ls2_header                    |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
|          options                      |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
| num| MetaLease 0                      |
+----+                                  +
|                                       |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
| MetaLease($num-1)                     |
+                                       +
|                                       |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
|numr|                                  |
+----+                                  +
|          revocation_0                 |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
|          revocation_n                 |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
| signature                             |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+

ls2header :: `LeaseSet2Header`
             length -> varies

options :: `Mapping`
           length -> varies, 2 bytes minimum

num :: `Integer`
        length -> 1 byte
        Number of `MetaLease`s to follow
        value: 1 <= num <= max TBD

leases :: `MetaLease`s
          length -> $numr*40 bytes

numr :: `Integer`
        length -> 1 byte
        Number of `Hash`es to follow
        value: 0 <= numr <= max TBD

revocations :: [`Hash`]
               length -> $numr*32 bytes

signature :: `Signature`
             length -> 40 bytes or as specified in destination's key
                       certificate, or by the sigtype of the transient public key,
                       if present in the header

Notes

  • The public key of the destination was used for the old I2CP-to-I2CP encryption which was disabled in version 0.6, it is currently unused.

  • The signature is over the data above, PREPENDED with the single byte containing the DatabaseStore type (7).

  • The signature may be verified using the signing public key of the destination, or the transient signing public key, if an offline signature is included in the leaseset2 header.

  • See note on the ‘published’ field in LeaseSet2Header

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/MetaLeaseSet.html

EncryptedLeaseSet

Description

Contained in a I2NP DatabaseStore message of type 5. Defined as of 0.9.38; working as of 0.9.39; see proposal 123 for more information.

Only the blinded key and expiration are visible in cleartext. The actual lease set is encrypted.

Contents

A two byte signature type, the blinded SigningPrivateKey , published time, expiration, and flags. Then, a two byte length followed by encrypted data. Finally, a Signature of the previous bytes signed by the blinded SigningPrivateKey or the transient key.

+----+----+----+----+----+----+----+----+
| sigtype |                             |
+----+----+                             +
|        blinded_public_key             |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
|     published     | expires |  flags  |
+----+----+----+----+----+----+----+----+
| offline_signature (optional)          |
+                                       +
|                                       |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
|  len    |                             |
+----+----+                             +
|         encrypted_data                |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
| signature                             |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+

sigtype :: A two byte signature type of the public key to follow
           length -> 2 bytes

blinded_public_key :: `SigningPublicKey`
                      length -> As inferred from the sigtype

published :: 4 byte date
             length -> 4 bytes
             Seconds since the epoch, rolls over in 2106.

expires :: 2 byte time
           length -> 2 bytes
           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.
  Bits 15-2: set to 0 for compatibility with future uses

offline_signature :: `OfflineSignature`
                     length -> varies
                     Optional, only present if bit 0 is set in the flags.

len :: `Integer`
        length -> 2 bytes
        length of encrypted_data to follow
        value: 1 <= num <= max TBD

encrypted_data :: Data encrypted
                  length -> len bytes

signature :: `Signature`
             length -> As specified by the sigtype of the blinded pubic key,
                       or by the sigtype of the transient public key,
                       if present in the header

Notes

  • The public key of the destination was used for the old I2CP-to-I2CP encryption which was disabled in version 0.6, it is currently unused.

  • The signature is over the data above, PREPENDED with the single byte containing the DatabaseStore type (5).

  • The signature may be verified using the signing public key of the destination, or the transient signing public key, if an offline signature is included in the leaseset2 header.

  • Blinding and encryption are specified in EncryptedLeaseSet

  • This structure does not use the LeaseSet2Header .

  • Maximum actual expires time is about 660 (11 minutes), unless it is an encrypted MetaLeaseSet .

  • See proposal 123 for notes on using offline signatures with encrypted leasesets.

  • See note on the ‘published’ field in LeaseSet2Header (same issue, even though we do not use the LeaseSet2Header format here)

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/EncryptedLeaseSet.html

RouterAddress

Description

This structure defines the means to contact a router through a transport protocol.

Contents

1 byte Integer defining the relative cost of using the address, where 0 is free and 255 is expensive, followed by the expiration Date after which the address should not be used, or if null, the address never expires. After that comes a String defining the transport protocol this router address uses. Finally there is a Mapping containing all of the transport specific options necessary to establish the connection, such as IP address, port number, email address, URL, etc.

+----+----+----+----+----+----+----+----+
|cost|           expiration
+----+----+----+----+----+----+----+----+
     |        transport_style           |
+----+----+----+----+-/-+----+----+----+
|                                       |
+                                       +
|               options                 |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+

cost :: `Integer`
        length -> 1 byte

        case 0 -> free
        case 255 -> expensive

expiration :: `Date` (must be all zeros, see notes below)
              length -> 8 bytes

              case null -> never expires

transport_style :: `String`
                   length -> 1-256 bytes

options :: `Mapping`

Notes

  • Cost is typically 5 or 6 for SSU, and 10 or 11 for NTCP.

  • Expiration is currently unused, always null (all zeroes). As of release 0.9.3, the expiration is assumed zero and not stored, so any non-zero expiration will fail in the RouterInfo signature verification. Implementing expiration (or another use for these bytes) will be a backwards-incompatible change. Routers MUST set this field to all zeros. As of release 0.9.12, a non-zero expiration field is again recognized, however we must wait several releases to use this field, until the vast majority of the network recognizes it.

  • The following options, while not required, are standard and expected to be present in most router addresses: “host” (an IPv4 or IPv6 address or host name) and “port”.

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/router/RouterAddress.html

RouterInfo

Description

Defines all of the data that a router wants to publish for the network to see. The RouterInfo is one of two structures stored in the network database (the other being LeaseSet ), and is keyed under the SHA256 of the contained RouterIdentity .

Contents

RouterIdentity followed by the Date , when the entry was published

+----+----+----+----+----+----+----+----+
| router_ident                          |
+                                       +
|                                       |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
| published                             |
+----+----+----+----+----+----+----+----+
|size| RouterAddress 0                  |
+----+                                  +
|                                       |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
| RouterAddress 1                       |
+                                       +
|                                       |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+----+----+----+----+
| RouterAddress ($size-1)               |
+                                       +
|                                       |
~                                       ~
~                                       ~
|                                       |
+----+----+----+----+-/-+----+----+----+
|psiz| options                          |
+----+----+----+----+-/-+----+----+----+
| signature                             |
+                                       +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+

router_ident :: `RouterIdentity`
                length -> >= 387+ bytes

published :: `Date`
             length -> 8 bytes

size :: `Integer`
        length -> 1 byte
        The number of `RouterAddress`es to follow, 0-255

addresses :: [`RouterAddress`]
             length -> varies

peer_size :: `Integer`
             length -> 1 byte
             The number of peer `Hash`es to follow, 0-255, unused, always zero
             value -> 0

options :: `Mapping`

signature :: `Signature`
             length -> 40 bytes or as specified in router_ident's key
                       certificate

Notes

  • The peer_size Integer may be followed by a list of that many router hashes. This is currently unused. It was intended for a form of restricted routes, which is unimplemented. Certain implementations may require the list to be sorted so the signature is invariant. To be researched before enabling this feature.

  • The signature may be verified using the signing public key of the router_ident.

  • See the network database page NETDB-ROUTERINFO for standard options that are expected to be present in all router infos.

  • Very old routers required the addresses to be sorted by the SHA256 of their data so the signature is invariant. This is no longer required, and not worth implementing for backward compatibility.

JavaDoc: http://docs.i2p-projekt.de/javadoc/net/i2p/data/router/RouterInfo.html

Delivery Instructions

Tunnel Message Delivery Instructions are defined in the Tunnel Message Specification TUNNEL-DELIVERY .

Garlic Message Delivery Instructions are defined in the I2NP Message Specification GARLIC-DELIVERY .

References

Was this page helpful?