Files
i2p.www/i2p2www/pages/site/docs/spec/common-structures.html
2014-08-24 19:50:20 +00:00

1018 lines
41 KiB
HTML

{% extends "global/layout.html" %}
{% block title %}{% trans %}Common structures Specification{% endtrans %}{% endblock %}
{% block lastupdated %}{% trans %}August 2014{% endtrans %}{% endblock %}
{% block accuratefor %}0.9.15{% endblock %}
{% block content %}
<p>{% 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
<a href="{{ i2np }}">I2NP</a>, <a href="{{ i2cp }}">I2CP</a>,
<a href="{{ ssu }}">SSU</a>, etc.
{%- endtrans %}</p>
<h2>Index</h2>
<table border=1>
<tr><th>{% trans %}Type{% endtrans %}</th></tr>
<tr><td><a href="#type_Boolean">Boolean</a></td></tr>
<tr><td><a href="#type_Certificate">Certificate</a></td></tr>
<tr><td><a href="#type_Date">Date</a></td></tr>
<tr><td><a href="#struct_DeliveryInstructions">Delivery Instructions</a></td></tr>
<tr><td><a href="#struct_Destination">Destination</a></td></tr>
<tr><td><a href="#type_Hash">Hash</a></td></tr>
<tr><td><a href="#type_Integer">Integer</a></td></tr>
<tr><td><a href="#struct_Lease">Lease</a></td></tr>
<tr><td><a href="#struct_LeaseSet">LeaseSet</a></td></tr>
<tr><td><a href="#type_Mapping">Mapping</a></td></tr>
<tr><td><a href="#type_PrivateKey">PrivateKey</a></td></tr>
<tr><td><a href="#type_PublicKey">PublicKey</a></td></tr>
<tr><td><a href="#struct_RouterAddress">RouterAddress</a></td></tr>
<tr><td><a href="#struct_RouterIdentity">RouterIdentity</a></td></tr>
<tr><td><a href="#struct_RouterInfo">RouterInfo</a></td></tr>
<tr><td><a href="#type_SessionTag">SessionTag</a></td></tr>
<tr><td><a href="#type_Signature">Signature</a></td></tr>
<tr><td><a href="#type_SigningPrivateKey">SigningPrivateKey</a></td></tr>
<tr><td><a href="#type_SigningPublicKey">SigningPublicKey</a></td></tr>
<tr><td><a href="#type_String">String</a></td></tr>
<tr><td><a href="#type_TunnelId">TunnelId</a></td></tr>
</table>
<h2 id="type_Integer">Integer</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
Represents a non-negative integer.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
1 to 8 bytes in network byte order representing an unsigned integer
{% endtrans %}</p>
<h2 id="type_Date">Date</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% 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 %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
8 byte <a href="#type_Integer">Integer</a>
{% endtrans %}</p>
<h2 id="type_String">String</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
Represents a UTF-8 encoded string.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% 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 %}</p>
<h2 id="type_Boolean">Boolean</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
A boolean value, supporting null/unknown representation
0=false, 1=true, 2=unknown/null
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
1 byte <a href="#type_Integer">Integer</a>
{% endtrans %}</p>
<h4>{% trans %}Notes{% endtrans %}</h4>
<p>{% trans -%}
Deprecated - unused
{% endtrans %}</p>
<h2 id="type_PublicKey">PublicKey</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% 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
<a href="{{ cryptography }}#elgamal">the cryptography specification</a>.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
256 bytes
{% endtrans %}</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/PublicKey.html">Javadoc</a></h4>
<h2 id="type_PrivateKey">PrivateKey</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% 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
<a href="{{ cryptography }}#elgamal">the cryptography specification</a>.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
256 bytes
{% endtrans %}</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/PrivateKey.html">Javadoc</a></h4>
<h2 id="type_SessionKey">SessionKey</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
This structure is used for AES256 encryption and decryption.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
32 bytes
{% endtrans %}</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/SessionKey.html">Javadoc</a></h4>
<h2 id="type_SigningPublicKey">SigningPublicKey</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans cryptography=site_url('docs/how/cryptography') -%}
This structure is used for verifying signatures.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% 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 %}</p>
<table border=1>
<tr><th>{% trans %}Type{% endtrans %}</th><th>{% trans %}Length (bytes){% endtrans %}</th><th>{% trans %}Since{% endtrans %}</th></tr>
<tr><td>DSA_SHA1</td><td align="center">128</td><td>&nbsp;</td></tr>
<tr><td>ECDSA_SHA256_P256</td><td align="center">64</td><td align="center">0.9.12</td></tr>
<tr><td>ECDSA_SHA384_P384</td><td align="center">96</td><td align="center">0.9.12</td></tr>
<tr><td>ECDSA_SHA512_P521</td><td align="center">132</td><td align="center">0.9.12</td></tr>
<tr><td>RSA_SHA256_2048</td><td align="center">256</td><td align="center">0.9.12</td></tr>
<tr><td>RSA_SHA384_3072</td><td align="center">384</td><td align="center">0.9.12</td></tr>
<tr><td>RSA_SHA512_4096</td><td align="center">512</td><td align="center">0.9.12</td></tr>
<tr><td>EdDSA_SHA512_Ed25519</td><td align="center">32</td><td align="center">0.9.15</td></tr>
</table>
<h4>{% trans %}Notes{% endtrans %}</h4>
<ul>
<li>{% trans -%}
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.
{%- endtrans %}</li>
</ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/SigningPublicKey.html">Javadoc</a></h4>
<h2 id="type_SigningPrivateKey">SigningPrivateKey</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans cryptography=site_url('docs/how/cryptography') -%}
This structure is used for creating signatures.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% 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 %}</p>
<table border=1>
<tr><th>{% trans %}Type{% endtrans %}</th><th>{% trans %}Length (bytes){% endtrans %}</th><th>{% trans %}Since{% endtrans %}</th></tr>
<tr><td>DSA_SHA1</td><td align="center">20</td><td>&nbsp;</td></tr>
<tr><td>ECDSA_SHA256_P256</td><td align="center">32</td><td align="center">0.9.12</td></tr>
<tr><td>ECDSA_SHA384_P384</td><td align="center">48</td><td align="center">0.9.12</td></tr>
<tr><td>ECDSA_SHA512_P521</td><td align="center">66</td><td align="center">0.9.12</td></tr>
<tr><td>RSA_SHA256_2048</td><td align="center">512</td><td align="center">0.9.12</td></tr>
<tr><td>RSA_SHA384_3072</td><td align="center">768</td><td align="center">0.9.12</td></tr>
<tr><td>RSA_SHA512_4096</td><td align="center">1024</td><td align="center">0.9.12</td></tr>
<tr><td>EdDSA_SHA512_Ed25519</td><td align="center">32</td><td align="center">0.9.15</td></tr>
</table>
<h4>{% trans %}Notes{% endtrans %}</h4>
<ul>
<li>{% trans -%}
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.
{%- endtrans %}</li>
</ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/SigningPrivateKey.html">Javadoc</a></h4>
<h2 id="type_Signature">Signature</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans cryptography=site_url('docs/how/cryptography') -%}
This structure represents the signature of some data.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% 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 %}</p>
<table border=1>
<tr><th>{% trans %}Type{% endtrans %}</th><th>{% trans %}Length (bytes){% endtrans %}</th><th>{% trans %}Since{% endtrans %}</th></tr>
<tr><td>DSA_SHA1</td><td align="center">40</td><td>&nbsp;</td></tr>
<tr><td>ECDSA_SHA256_P256</td><td align="center">64</td><td align="center">0.9.12</td></tr>
<tr><td>ECDSA_SHA384_P384</td><td align="center">96</td><td align="center">0.9.12</td></tr>
<tr><td>ECDSA_SHA512_P521</td><td align="center">132</td><td align="center">0.9.12</td></tr>
<tr><td>RSA_SHA256_2048</td><td align="center">256</td><td align="center">0.9.12</td></tr>
<tr><td>RSA_SHA384_3072</td><td align="center">384</td><td align="center">0.9.12</td></tr>
<tr><td>RSA_SHA512_4096</td><td align="center">512</td><td align="center">0.9.12</td></tr>
<tr><td>EdDSA_SHA512_Ed25519</td><td align="center">64</td><td align="center">0.9.15</td></tr>
</table>
<h4>{% trans %}Notes{% endtrans %}</h4>
<ul>
<li>{% trans -%}
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.
{%- endtrans %}</li>
</ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/Signature.html">Javadoc</a></h4>
<h2 id="type_Hash">Hash</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
Represents the SHA256 of some data.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
32 bytes
{% endtrans %}</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/Hash.html">Javadoc</a></h4>
<h2 id="type_SessionTag">Session Tag</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
A random number
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
32 bytes
{% endtrans %}</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/SessionTag.html">Javadoc</a></h4>
<h2 id="type_TunnelId">TunnelId</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
Defines an identifier that is unique to each router in a tunnel.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
4 byte <a href="#type_Integer">Integer</a>
{% endtrans %}</p>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/TunnelId.html">Javadoc</a></h4>
<h2 id="type_Certificate">Certificate</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
A certificate is a container for various receipts or proof of works used throughout the I2P network.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
1 byte <a href="#type_Integer">Integer</a> specifying certificate type, followed by a 2 byte <a href="#type_Integer">Integer</a> specifying the size of the certificate payload, then that many bytes.
{% endtrans %}</p>
{% 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 %}
<h4>{% trans %}Notes{% endtrans %}</h4>
<ul>
<li>{% trans -%}
For <a href="#struct_RouterIdentity">Router Identities</a>, the Certificate is always NULL through version 0.9.15.
As of 0.9.16, a Key Certificate may be used to specify the signing public key type. See below.
{%- endtrans %}</li>
<li>{% trans i2np=site_url('docs/spec/i2np') -%}
For <a href="{{ i2np }}#struct_GarlicClove">Garlic Cloves</a>, the Certificate is always NULL, no others are currently implemented.
{%- endtrans %}</li>
<li>{% trans i2np=site_url('docs/spec/i2np') -%}
For <a href="{{ i2np }}#msg_Garlic">Garlic Messages</a>, the Certificate is always NULL, no others are currently implemented.
{%- endtrans %}</li>
<li>{% trans -%}
For <a href="#struct_Destination">Destinations</a>, 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.
{%- endtrans %}</li>
</ul>
<h4>{% trans %}Certificate Types{% endtrans %}</h4>
<p>The following certificate types are defined:</p>
<table border=1>
<tr><th>Type</th><th>Type Code</th><th>Payload Length</th><th>Total Length</th><th>Notes</th></tr>
<tr><td>Null</td><td align="center">0</td><td align="center">0</td><td align="center">3</td><td></td></tr>
<tr><td>HashCash</td><td align="center">1</td><td align="center">varies</td><td align="center">varies</td><td>
Experimental, unused. Payload contains an ASCII colon-separated hashcash string.
</td></tr>
<tr><td>Hidden</td><td align="center">2</td><td align="center">0</td><td align="center">3</td><td>
Experimental, unused. Hidden routers generally do not announce that they are hidden.
</td></tr>
<tr><td>Signed</td><td align="center">3</td><td align="center">40 or 72</td><td align="center">43 or 75</td><td>
Experimental, unused. Payload contains a 40-byte DSA signature,
optionally followed by the 32-byte Hash of the signing Destination.
</td></tr>
<tr><td>Multiple</td><td align="center">4</td><td align="center">varies</td><td align="center">varies</td><td>
Experimental, unused. Payload contains multiple certificates.
</td></tr>
<tr><td>Key</td><td align="center">5</td><td align="center">4+</td><td align="center">7+</td><td>
Since 0.9.12. See below for details.
</td></tr>
</table>
<h4>{% trans %}Key Certificates{% endtrans %}</h4>
<p>
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.
</p><p>
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.
</p><p>
The key certificate payload contains:
</p><table border=1>
<tr><th>Data</th><th>Length</th></tr>
<tr><td>Signing Public Key Type
(<a href="#type_Integer">Integer</a>)
</td><td align="center">2</td></tr>
<tr><td>Crypto Public Key Type
(<a href="#type_Integer">Integer</a>)
</td><td align="center">2</td></tr>
<tr><td>Excess Signing Public Key Data</td><td align="center">0+</td></tr>
<tr><td>Excess Crypto Public Key Data</td><td align="center">0+</td></tr>
</table>
<p>
The defined Signing Key types are:
</p><table border=1>
<tr><th>Type</th><th>Type Code</th><th>Total Public Key Length</th><th>{% trans %}Since{% endtrans %}</th></tr>
<tr><td>DSA_SHA1</td><td align="center">0</td><td align="center">128</td><td align="center">0.9.12</td></tr>
<tr><td>ECDSA_SHA256_P256</td><td align="center">1</td><td align="center">64</td><td align="center">0.9.12</td></tr>
<tr><td>ECDSA_SHA384_P384</td><td align="center">2</td><td align="center">96</td><td align="center">0.9.12</td></tr>
<tr><td>ECDSA_SHA512_P521</td><td align="center">3</td><td align="center">132</td><td align="center">0.9.12</td></tr>
<tr><td>RSA_SHA256_2048</td><td align="center">4</td><td align="center">256</td><td align="center">0.9.12</td></tr>
<tr><td>RSA_SHA384_3072</td><td align="center">5</td><td align="center">384</td><td align="center">0.9.12</td></tr>
<tr><td>RSA_SHA512_4096</td><td align="center">6</td><td align="center">512</td><td align="center">0.9.12</td></tr>
<tr><td>EdDSA_SHA512_Ed25519</td><td align="center">7</td><td align="center">32</td><td align="center">0.9.15</td></tr>
</table>
<p>
The defined Crypto Public Key types are:
</p><table border=1>
<tr><th>Type</th><th>Type Code</th><th>Total Public Key Length</th></tr>
<tr><td>ElGamal</td><td align="center">0</td><td align="center">256</td></tr>
</table>
<p>
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:
<ul><li>
Complete or first portion of Crypto Public Key
</li><li>
Random padding if the total lengths of the two keys are less than 384 bytes
</li><li>
Complete or first portion of Signing Public Key
</li></ul>
</p><p>
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.
</p>
<p>
Example layouts using an ElGamal Crypto Public Key and the Signing Public Key type indicated:
</p><table border=1>
<tr><th>Signing Key Type</th><th>Padding Length</th><th>Excess Signing Key Data in Cert</th></tr>
<tr><td>DSA_SHA1</td><td align="center">0</td><td align="center">0</td></tr>
<tr><td>ECDSA_SHA256_P256</td><td align="center">64</td><td align="center">0</td></tr>
<tr><td>ECDSA_SHA384_P384</td><td align="center">32</td><td align="center">0</td></tr>
<tr><td>ECDSA_SHA512_P521</td><td align="center">0</td><td align="center">4</td></tr>
<tr><td>RSA_SHA256_2048</td><td align="center">0</td><td align="center">128</td></tr>
<tr><td>RSA_SHA384_3072</td><td align="center">0</td><td align="center">256</td></tr>
<tr><td>RSA_SHA512_4096</td><td align="center">0</td><td align="center">384</td></tr>
<tr><td>EdDSA_SHA512_Ed25519</td><td align="center">96</td><td align="center">0</td></tr>
</table>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/Certificate.html">Javadoc</a></h4>
<h2 id="type_Mapping">Mapping</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
A set of key/value mappings or properties
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
A 2-byte size Integer followed by a series of String=String; pairs
{% endtrans %}</p>
{% 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 %}
<h4>{% trans %}Notes{% endtrans %}</h4>
<ul>
<li>{% trans -%}
The encoding isn't optimal - we either need the '=' and ';' characters, or the string lengths, but not both
{%- endtrans %}</li>
<li>{% trans -%}
Some documentation says that the strings may not include '=' or ';' but this encoding supports them
{%- endtrans %}</li>
<li>{% trans -%}
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.
{%- endtrans %}</li>
<li>{% trans -%}
The encoding allows duplicate keys, however in any usage where the mapping is signed,
duplicates may cause a signature failure.
{%- endtrans %}</li>
<li>{% trans -%}
Mappings contained in I2NP messages (i.e. in a RouterAddress or RouterInfo)
must be sorted by key so that the signature will be invariant.
Duplicate keys are not allowed.
{%- endtrans %}</li>
<li>{% trans i2cp=site_url('docs/spec/i2cp') -%}
Mappings contained in an <a href="{{ i2cp }}#struct_SessionConfig">I2CP SessionConfig</a>
must be sorted by key so that the signature will be invariant.
Duplicate keys are not allowed.
{%- endtrans %}</li>
<li>{% trans -%}
The sort method is defined as in Java String.compareTo(),
using the Unicode value of the characters.
{%- endtrans %}</li>
<li>{% trans -%}
While it is application-dependent, keys and values are generally case-sensitive.
{%- endtrans %}</li>
<li>{% trans -%}
Key and value string length limits are 255 bytes (not characters) each, plus the length byte. Length byte may be 0.
{%- endtrans %}</li>
<li>{% trans -%}
Total length limit is 65535 bytes, plus the 2 byte size field, or 65537 total.
{%- endtrans %}</li>
</ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/DataHelper.html">Javadoc</a></h4>
<h1>{% trans %}Common structure specification{% endtrans %}</h1>
<h2 id="struct_RouterIdentity">RouterIdentity</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
Defines the way to uniquely identify a particular router
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
<a href="#type_PublicKey">PublicKey</a> followed by <a href="#type_SigningPublicKey">SigningPublicKey</a> and then a <a href="#type_Certificate">Certificate</a>
{% endtrans %}</p>
{% 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 %}
<h4>{% trans %}Notes{% endtrans %}</h4>
<ul><li>{% trans -%}
The certificate for a RouterIdentity is currently unused and is always NULL.
{%- endtrans %}</li><li>
Do not assume that RouterIdentities are always 387 bytes!
They are 387 bytes plus the certificate length specified at bytes 385-386, which may be non-zero in a future release.
</li><li>
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.
</li><li>
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.
</li></ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/RouterIdentity.html">Javadoc</a></h4>
<h2 id="struct_Destination">Destination</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
A Destination defines a particular endpoint to which messages can be directed for secure delivery.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
<a href="#type_PublicKey">PublicKey</a> followed by a <a href="#type_SigningPublicKey">SigningPublicKey</a> and then a <a href="#type_Certificate">Certificate</a>
{% endtrans %}</p>
{% highlight lang='dataspec' %}
+----+----+----+----+----+----+----+----+
| public_key |
+ +
| |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| padding (optional) |
~ ~
~ ~
| |
+----+----+----+----+----+----+----+----+
| signing_public_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_public_key length == 128 bytes
signing_public_key :: `SigningPublicKey` (partial or full)
length -> 128 bytes or as specified in key certificate
padding length + signing_public_key length == 128 bytes
certificate :: `Certificate`
length -> >= 3 bytes
total length: 387+ bytes
{% endhighlight %}
<h4>Notes</h4>
<ul><li>
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
except for the IV for LeaseSet encryption,
which is deprecated. The public key in the LeaseSet is used instead.
</li><li>
Do not assume that Destinations are always 387 bytes!
They are 387 bytes plus the certificate length specified at bytes 385-386, which may be non-zero.
</li><li>
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.
</li><li>
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.
</li></ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/Destination.html">Javadoc</a></h4>
<h2 id="struct_Lease">Lease</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
Defines the authorization for a particular tunnel to receive messages targeting a <a href="#struct_Destination">Destination</a>.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
SHA256 <a href="#type_Hash">Hash</a> of the
<a href="#struct_RouterIdentity">RouterIdentity</a> of the gateway router, then the <a href="#type_TunnelId">TunnelId</a>, and finally an end <a href="#type_Date">Date</a>
{% endtrans %}</p>
{% 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 %}
<h4>{% trans %}Notes{% endtrans %}</h4>
<ul>
<li>{% trans -%}
Total size: 44 bytes
{%- endtrans %}</li>
</ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/Lease.html">Javadoc</a></h4>
<h2 id="struct_LeaseSet">LeaseSet</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
Contains all of the currently authorized <a href="#struct_Lease">Lease</a>s for a particular <a href="#struct_Destination">Destination</a>, the <a href="#type_PublicKey">PublicKey</a> to which garlic messages can be encrypted,
and then the <a href="#type_SigningPublicKey">public key</a> that can be used to revoke this particular version of the structure. The <a href="#struct_LeaseSet">LeaseSet</a> is one of the two structures stored in the network database(
the other being <a href="#struct_RouterInfo">RouterInfo</a>), and is keyed under the SHA256 of the contained <a href="#struct_Destination">Destination</a>.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
<a href="#struct_Destination">Destination</a>, followed by a <a href="#type_PublicKey">PublicKey</a> for encryption, then a <a href="#type_SigningPublicKey">SigningPublicKey</a> which can be used to revoke this version of the <a href="#struct_LeaseSet">LeaseSet</a>,
then a 1 byte <a href="#type_Integer">Integer</a> specifying how many <a href="#struct_Lease">Lease</a> structures are in the set, followed by the actual <a href="#struct_Lease">Lease</a> structures and finally a <a href="#type_Signature">Signature</a> of the previous
bytes signed by the <a href="#struct_Destination">Destination's</a> <a href="#type_SigningPrivateKey">SigningPrivateKey</a>
{%- endtrans %}</p>
{% 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 %}
<h4>{% trans %}Notes{% endtrans %}</h4>
<ul>
<li>{% trans -%}
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.
{%- endtrans %}</li>
<li>{% trans elgamalaes=site_url('docs/how/elgamal-aes') -%}
The encryption key is used for end-to-end <a href="{{ elgamalaes }}">ElGamal/AES+SessionTag</a> encryption.
It is currently generated anew at every router startup, it is not persistent.
{%- endtrans %}</li>
<li>{% trans -%}
The signature may be verified using the signing public key of the destination.
{%- endtrans %}</li>
<li>{% trans -%}
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.
{%- endtrans %}</li>
<li>{% trans -%}
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.
{%- endtrans %}</li>
<li>{% trans -%}
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.
{%- endtrans %}</li>
</ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/LeaseSet.html">Javadoc</a></h4>
<h2 id="struct_RouterAddress">RouterAddress</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
This structure defines the means to contact a router through a transport protocol.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
1 byte <a href="#type_Integer">Integer</a> defining the relative cost of using the address, where 0 is free and 255 is expensive, followed by the expiration <a href="#type_Date">Date</a> after which the address should not be used, or if null, the address never expires.
After that comes a <a href="#type_String">String</a> defining the transport protocol this router address uses. Finally there is a <a href="#type_Mapping">Mapping</a> containing all of the transport specific options necessary to establish the connection, such as
IP address, port number, email address, URL, etc.
{% endtrans %}</p>
{% 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 %}
<h4>{% trans %}Notes{% endtrans %}</h4>
<ul>
<li>{% trans -%}
Cost is typically 5 or 6 for SSU, and 10 or 11 for NTCP.
{%- endtrans %}</li>
<li>{% trans -%}
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.
{%- endtrans %}</li>
<li>{% trans -%}
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".
{%- endtrans %}</li>
</ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/RouterAddress.html">Javadoc</a></h4>
<h2 id="struct_RouterInfo">RouterInfo</h2>
<h4>{% trans %}Description{% endtrans %}</h4>
<p>{% trans -%}
Defines all of the data that a router wants to publish for the network to see. The <a href="#struct_RouterInfo">RouterInfo</a> is one of two structures stored in the network database(the other being <a href="#struct_LeaseSet">LeaseSet</a>, and is keyed under the SHA256 of
the contained <a href="#struct_RouterIdentity">RouterIdentity</a>.
{% endtrans %}</p>
<h4>{% trans %}Contents{% endtrans %}</h4>
<p>{% trans -%}
<a href="#struct_RouterIdentity">RouterIdentity</a> followed by the <a href="#type_Date">Date</a>, when the entry was published
{% endtrans %}</p>
{% 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 %}
<h4>{% trans %}Notes{% endtrans %}</h4>
<ul>
<li>{% trans -%}
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.
{%- endtrans %}</li>
<li>{% trans -%}
The signature may be verified using the signing public key of the router_ident.
{%- endtrans %}</li>
<li>{% trans netdb=site_url('docs/how/network-database') -%}
See <a href="{{ netdb }}#routerInfo">the network database page</a>
for standard options that are expected to be present in all router infos.
{%- endtrans %}</li>
</ul>
<h4><a href="http://docs.i2p-projekt.de/javadoc/net/i2p/data/RouterInfo.html">Javadoc</a></h4>
<h2 id="struct_DeliveryInstructions">Delivery Instructions</h2>
<p>{% trans tunnelmessage=site_url('docs/spec/tunnel-message') -%}
Tunnel Message Delivery Instructions are defined in the <a href="{{ tunnelmessage }}#delivery">Tunnel Message Specification</a>.
{% endtrans %}</p>
<p>{% trans i2npmessage=site_url('docs/spec/i2np') -%}
Garlic Message Delivery Instructions are defined in the <a href="{{ i2npmessage }}#struct_DeliveryInstructions">I2NP Message Specification</a>.
{% endtrans %}</p>
{% endblock %}