{% extends "global/layout.html" %} {% block title %}{% trans %}Common structures Specification{% endtrans %}{% endblock %} {% block lastupdated %}{% trans %}April 2015{% endtrans %}{% endblock %} {% block accuratefor %}0.9.19{% endblock %} {% block content %}
{% trans i2np=site_url('docs/protocol/i2np'), i2cp=site_url('docs/protocol/i2cp'), ssu=site_url('docs/transport/ssu') -%} This document describes some data types common to all I2P protocols, like I2NP, I2CP, SSU, etc. {%- endtrans %}
{% trans -%} Represents a non-negative integer. {% endtrans %}
{% trans -%} 1 to 8 bytes in network byte order representing an unsigned integer {% endtrans %}
{% trans -%} 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. {% endtrans %}
{% trans -%} 8 byte Integer {% endtrans %}
{% trans -%} Represents a UTF-8 encoded string. {% endtrans %}
{% trans -%} 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. {% endtrans %}
{% trans -%} A boolean value, supporting null/unknown representation 0=false, 1=true, 2=unknown/null {% endtrans %}
{% trans -%} 1 byte Integer {% endtrans %}
{% trans -%} Deprecated - unused {% endtrans %}
{% trans cryptography=site_url('docs/how/cryptography') -%} This structure is used in ElGamal encryption, representing only the exponent, not the primes, which are constant and defined in the cryptography specification. {% endtrans %}
{% trans -%} 256 bytes {% endtrans %}
{% trans cryptography=site_url('docs/how/cryptography') -%} This structure is used in ElGamal decryption, representing only the exponent, not the primes which are constant and defined in the cryptography specification. {% endtrans %}
{% trans -%} 256 bytes {% endtrans %}
{% trans -%} This structure is used for AES256 encryption and decryption. {% endtrans %}
{% trans -%} 32 bytes {% endtrans %}
{% trans cryptography=site_url('docs/how/cryptography') -%} This structure is used for verifying signatures. {% endtrans %}
{% trans -%} Key type and length are inferred from context or are specified in the Key Certificate of a Destination. {% endtrans %} {% trans -%} The default type is DSA_SHA1. {% endtrans %} {% trans -%} As of release 0.9.12, other types may be supported, depending on context. {% endtrans %}
{% trans %}Type{% endtrans %} | {% trans %}Length (bytes){% endtrans %} | {% trans %}Since{% endtrans %} |
---|---|---|
DSA_SHA1 | 128 | |
ECDSA_SHA256_P256 | 64 | 0.9.12 |
ECDSA_SHA384_P384 | 96 | 0.9.12 |
ECDSA_SHA512_P521 | 132 | 0.9.12 |
RSA_SHA256_2048 | 256 | 0.9.12 |
RSA_SHA384_3072 | 384 | 0.9.12 |
RSA_SHA512_4096 | 512 | 0.9.12 |
EdDSA_SHA512_Ed25519 | 32 | 0.9.15 |
{% trans cryptography=site_url('docs/how/cryptography') -%} This structure is used for creating signatures. {% endtrans %}
{% trans -%} Key type and length are specified when created. {% endtrans %} {% trans -%} The default type is DSA_SHA1. {% endtrans %} {% trans -%} As of release 0.9.12, other types may be supported, depending on context. {% endtrans %}
{% trans %}Type{% endtrans %} | {% trans %}Length (bytes){% endtrans %} | {% trans %}Since{% endtrans %} |
---|---|---|
DSA_SHA1 | 20 | |
ECDSA_SHA256_P256 | 32 | 0.9.12 |
ECDSA_SHA384_P384 | 48 | 0.9.12 |
ECDSA_SHA512_P521 | 66 | 0.9.12 |
RSA_SHA256_2048 | 512 | 0.9.12 |
RSA_SHA384_3072 | 768 | 0.9.12 |
RSA_SHA512_4096 | 1024 | 0.9.12 |
EdDSA_SHA512_Ed25519 | 32 | 0.9.15 |
{% trans cryptography=site_url('docs/how/cryptography') -%} This structure represents the signature of some data. {% endtrans %}
{% trans -%} Signature type and length are inferred from the type of key used. {% endtrans %} {% trans -%} The default type is DSA_SHA1. {% endtrans %} {% trans -%} As of release 0.9.12, other types may be supported, depending on context. {% endtrans %}
{% trans %}Type{% endtrans %} | {% trans %}Length (bytes){% endtrans %} | {% trans %}Since{% endtrans %} |
---|---|---|
DSA_SHA1 | 40 | |
ECDSA_SHA256_P256 | 64 | 0.9.12 |
ECDSA_SHA384_P384 | 96 | 0.9.12 |
ECDSA_SHA512_P521 | 132 | 0.9.12 |
RSA_SHA256_2048 | 256 | 0.9.12 |
RSA_SHA384_3072 | 384 | 0.9.12 |
RSA_SHA512_4096 | 512 | 0.9.12 |
EdDSA_SHA512_Ed25519 | 64 | 0.9.15 |
{% trans -%} Represents the SHA256 of some data. {% endtrans %}
{% trans -%} 32 bytes {% endtrans %}
{% trans -%} A random number {% endtrans %}
{% trans -%} 32 bytes {% endtrans %}
{% trans -%} Defines an identifier that is unique to each router in a tunnel. {% endtrans %} {% trans -%} A Tunnel ID is generally greater than zero; do not use a value of zero except in special cases. {% endtrans %}
{% trans -%} 4 byte Integer {% endtrans %}
{% trans -%} A certificate is a container for various receipts or proof of works used throughout the I2P network. {% endtrans %}
{% trans -%} 1 byte Integer specifying certificate type, followed by a 2 byte Integer specifying the size of the certificate payload, then that many bytes. {% endtrans %}
{% highlight lang='dataspec' %} +----+----+----+----+----+-// |type| length | payload +----+----+----+----+----+-// type :: `Integer` length -> 1 byte case 0 -> NULL case 1 -> HASHCASH case 2 -> HIDDEN case 3 -> SIGNED case 4 -> MULTIPLE case 5 -> KEY length :: `Integer` length -> 2 bytes payload :: data length -> $length bytes {% endhighlight %}The following certificate types are defined:
Type | Type Code | Payload Length | Total Length | Notes |
---|---|---|---|---|
Null | 0 | 0 | 3 | |
HashCash | 1 | varies | varies | Experimental, unused. Payload contains an ASCII colon-separated hashcash string. |
Hidden | 2 | 0 | 3 | Experimental, unused. Hidden routers generally do not announce that they are hidden. |
Signed | 3 | 40 or 72 | 43 or 75 | Experimental, unused. Payload contains a 40-byte DSA signature, optionally followed by the 32-byte Hash of the signing Destination. |
Multiple | 4 | varies | varies | Experimental, unused. Payload contains multiple certificates. |
Key | 5 | 4+ | 7+ | Since 0.9.12. See below for details. |
Key certificates are preliminary, and are scheduled to be 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 RouterIdentities.
The key certificate payload contains:
Data | Length |
---|---|
Signing Public Key Type (Integer) | 2 |
Crypto Public Key Type (Integer) | 2 |
Excess Signing Public Key Data | 0+ |
Excess Crypto Public Key Data | 0+ |
The defined Signing Key types are:
Type | Type Code | Total Public Key Length | {% trans %}Since{% endtrans %} |
---|---|---|---|
DSA_SHA1 | 0 | 128 | 0.9.12 |
ECDSA_SHA256_P256 | 1 | 64 | 0.9.12 |
ECDSA_SHA384_P384 | 2 | 96 | 0.9.12 |
ECDSA_SHA512_P521 | 3 | 132 | 0.9.12 |
RSA_SHA256_2048 | 4 | 256 | 0.9.12 |
RSA_SHA384_3072 | 5 | 384 | 0.9.12 |
RSA_SHA512_4096 | 6 | 512 | 0.9.12 |
EdDSA_SHA512_Ed25519 | 7 | 32 | 0.9.15 |
The defined Crypto Public Key types are:
Type | Type Code | Total Public Key Length |
---|---|---|
ElGamal | 0 | 256 |
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:
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 Type | Padding Length | Excess Signing Key Data in Cert |
---|---|---|
DSA_SHA1 | 0 | 0 |
ECDSA_SHA256_P256 | 64 | 0 |
ECDSA_SHA384_P384 | 32 | 0 |
ECDSA_SHA512_P521 | 0 | 4 |
RSA_SHA256_2048 | 0 | 128 |
RSA_SHA384_3072 | 0 | 256 |
RSA_SHA512_4096 | 0 | 384 |
EdDSA_SHA512_Ed25519 | 96 | 0 |
{% trans -%} A set of key/value mappings or properties {% endtrans %}
{% trans -%} A 2-byte size Integer followed by a series of String=String; pairs {% endtrans %}
{% highlight lang='dataspec' %} +----+----+----+----+----+----+----+----+ | size |key_string (len + data) | = | +----+----+----+----+----+----+----+----+ | val_string (len + data) | ; | ... +----+----+----+----+----+----+----+ size :: `Integer` length -> 2 bytes Total number of bytes that follow key_string :: `String` A string (one byte length followed by UTF-8 encoded characters) = :: A single byte containing '=' val_string :: `String` A string (one byte length followed by UTF-8 encoded characters) ; :: A single byte containing ';' {% endhighlight %}{% trans -%} An encryption public key, a signing public key, and a certificate, used as either a RouterIdentity or a Destination. {% endtrans %}
{% trans -%} PublicKey followed by SigningPublicKey and then a Certificate {% endtrans %}
{% highlight lang='dataspec' %} +----+----+----+----+----+----+----+----+ | public_key | + + | | ~ ~ ~ ~ | | +----+----+----+----+----+----+----+----+ | padding (optional) | ~ ~ ~ ~ | | +----+----+----+----+----+----+----+----+ | signing_key | + + | | ~ ~ ~ ~ | | +----+----+----+----+----+----+----+----+ | certificate | +----+----+----+-// public_key :: `PublicKey` (partial or full) length -> 256 bytes or as specified in key certificate padding :: random data length -> 0 bytes or as specified in key certificate padding length + signing_key length == 128 bytes signing__key :: `SigningPublicKey` (partial or full) length -> 128 bytes or as specified in key certificate padding length + signing_key length == 128 bytes certificate :: `Certificate` length -> >= 3 bytes total length: 387+ bytes {% endhighlight %}{% trans -%} Defines the way to uniquely identify a particular router {% endtrans %}
{% trans -%} Identical to KeysAndCert. {% endtrans %}
{% trans -%} A Destination defines a particular endpoint to which messages can be directed for secure delivery. {% endtrans %}
{% trans -%} Identical to KeysAndCert. {% endtrans %}
{% trans -%} Defines the authorization for a particular tunnel to receive messages targeting a Destination. {% endtrans %}
{% trans -%} SHA256 Hash of the RouterIdentity of the gateway router, then the TunnelId, and finally an end Date {% endtrans %}
{% highlight lang='dataspec' %} +----+----+----+----+----+----+----+----+ | 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 :: `Date` length -> 8 bytes {% endhighlight %}{% trans -%} Contains all of the currently authorized Leases for a particular Destination, the PublicKey to which garlic messages can be encrypted, and then the public key 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. {% endtrans %}
{% trans -%} 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 {%- endtrans %}
{% highlight lang='dataspec' %} +----+----+----+----+----+----+----+----+ | destination | + + | | ~ ~ ~ ~ | | +----+----+----+----+----+----+----+----+ | encryption_key | + + | | ~ ~ ~ ~ | | +----+----+----+----+----+----+----+----+ | signing_key | + + | | ~ ~ ~ ~ | | +----+----+----+----+----+----+----+----+ |num | Lease 0 | +----+ + | | ~ ~ ~ ~ | | +----+----+----+----+----+----+----+----+ | Lease 1 | + + | | ~ ~ ~ ~ | | +----+----+----+----+----+----+----+----+ | Lease ($num-1) | + + | | ~ ~ ~ ~ | | +----+----+----+----+----+----+----+----+ | signature | + + | | + + | | + + | | + + | | +----+----+----+----+----+----+----+----+ destination :: `Destination` length -> >= 387 bytes encryption_key :: `PublicKey` length -> 256 bytes signing_key :: `SigningPublicKey` length -> 128 bytes or as specified in destination's key certificate num :: `Integer` length -> 1 byte Number of leases to follow value: 0 <= num <= 16 leases :: [`Lease`] length -> $num*44 bytes signature :: `Signature` length -> 40 bytes or as specified in destination's key certificate {% endhighlight %}{% trans -%} This structure defines the means to contact a router through a transport protocol. {% endtrans %}
{% trans -%} 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. {% endtrans %}
{% highlight lang='dataspec' %} +----+----+----+----+----+----+----+----+ |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` {% endhighlight %}{% trans -%} 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. {% endtrans %}
{% trans -%} RouterIdentity followed by the Date, when the entry was published {% endtrans %}
{% highlight lang='dataspec' %} +----+----+----+----+----+----+----+----+ | 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 RouterAddresses to follow, 0-255 addresses :: [`RouterAddress`] length -> varies peer_size :: `Integer` length -> 1 byte The number of peer Hashes to follow, 0-255, unused, always zero value -> 0 options :: `Mapping` signature :: `Signature` length -> 40 bytes {% endhighlight %}{% trans tunnelmessage=site_url('docs/spec/tunnel-message') -%} Tunnel Message Delivery Instructions are defined in the Tunnel Message Specification. {% endtrans %}
{% trans i2npmessage=site_url('docs/spec/i2np') -%} Garlic Message Delivery Instructions are defined in the I2NP Message Specification. {% endtrans %}
{% endblock %}