Compare commits
48 Commits
35f6465301
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0206eb63cb | ||
![]() |
ee7ed83062 | ||
![]() |
dd14d5ccf8 | ||
![]() |
c497a9a840 | ||
![]() |
4c4cffbc6d | ||
![]() |
dbfa21d523 | ||
![]() |
836cdb9cd0 | ||
![]() |
80972af6b3 | ||
![]() |
b6ac602c8d | ||
![]() |
d9d2fcac82 | ||
![]() |
6b4634fb21 | ||
![]() |
dabf40a185 | ||
![]() |
d3df17be81 | ||
![]() |
0d70474034 | ||
![]() |
3952d48b3c | ||
![]() |
287e7149de | ||
![]() |
422ec5aa3a | ||
![]() |
5cb8e81a09 | ||
![]() |
2515a42427 | ||
![]() |
0dfc92de5e | ||
![]() |
68d3546fb0 | ||
![]() |
de5aba25b8 | ||
![]() |
787817bc6b | ||
![]() |
b6c4aa2839 | ||
![]() |
3185eb3e89 | ||
![]() |
d9178a8026 | ||
![]() |
34aaef0cbb | ||
![]() |
a2b9e4c8a7 | ||
![]() |
1e70151059 | ||
![]() |
976424985a | ||
![]() |
64d742b648 | ||
![]() |
955eb09014 | ||
![]() |
419c504683 | ||
![]() |
80915e7d35 | ||
![]() |
e332c00622 | ||
![]() |
cee7fd0693 | ||
![]() |
e88928ee4f | ||
![]() |
3d11c3d88e | ||
![]() |
835d94407f | ||
![]() |
ab4b805645 | ||
![]() |
e136562d9b | ||
![]() |
4f806a3047 | ||
![]() |
138ad3147e | ||
![]() |
4bc9e8ac42 | ||
![]() |
41d5bccd80 | ||
![]() |
98359fa710 | ||
![]() |
5a48e08908 | ||
![]() |
4ced867eea |
23
.github/workflows/github-sync.yml
vendored
23
.github/workflows/github-sync.yml
vendored
@@ -1,23 +0,0 @@
|
||||
# File: .github/workflows/repo-sync.yml
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "*/5 * * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
repo-sync:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: repo-sync
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: repo-sync/github-sync@v2
|
||||
with:
|
||||
source_repo: "https://i2pgit.org/i2p-hackers/i2p.www"
|
||||
source_branch: "master"
|
||||
destination_branch: "master"
|
||||
github_token: ${{ secrets.SYNC_PAT }}
|
66
.github/workflows/sync.yaml
vendored
Normal file
66
.github/workflows/sync.yaml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
# GitHub Actions workflow file to sync an external repository to this GitHub mirror.
|
||||
# This file was automatically generated by go-github-sync.
|
||||
#
|
||||
# The workflow does the following:
|
||||
# - Runs on a scheduled basis (and can also be triggered manually)
|
||||
# - Clones the GitHub mirror repository
|
||||
# - Fetches changes from the primary external repository
|
||||
# - Applies those changes to the mirror repository
|
||||
# - Pushes the updated content back to the GitHub mirror
|
||||
#
|
||||
# Authentication is handled by the GITHUB_TOKEN secret provided by GitHub Actions.
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Validate Github Actions Environment
|
||||
run: if [ "$GITHUB_ACTIONS" != "true" ]; then echo 'This script must be run in a GitHub Actions environment.'; exit 1; fi
|
||||
- name: Checkout GitHub Mirror
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Configure Git
|
||||
run: |-
|
||||
git config user.name 'GitHub Actions'
|
||||
git config user.email 'actions@github.com'
|
||||
- env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: Sync Primary Repository
|
||||
run: |-
|
||||
# Add the primary repository as a remote
|
||||
git remote add primary https://i2pgit.org/I2P_Developers/i2p.www.git
|
||||
|
||||
# Fetch the latest changes from the primary repository
|
||||
git fetch primary
|
||||
|
||||
# Check if the primary branch exists in the primary repository
|
||||
if git ls-remote --heads primary master | grep -q master; then
|
||||
echo "Primary branch master found in primary repository"
|
||||
else
|
||||
echo "Error: Primary branch master not found in primary repository"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if we're already on the mirror branch
|
||||
if git rev-parse --verify --quiet master; then
|
||||
git checkout master
|
||||
else
|
||||
# Create the mirror branch if it doesn't exist
|
||||
git checkout -b master
|
||||
fi
|
||||
|
||||
|
||||
# Force-apply all changes from primary, overriding any conflicts
|
||||
echo "Performing force sync from primary/master to master"
|
||||
git reset --hard primary/master
|
||||
|
||||
|
||||
# Push changes back to the mirror repository
|
||||
git push origin master
|
||||
name: Sync Primary Repository to GitHub Mirror
|
||||
"on":
|
||||
push: {}
|
||||
schedule:
|
||||
- cron: 0 0 * * *
|
||||
workflow_dispatch: {}
|
@@ -22,8 +22,8 @@ except ImportError:
|
||||
###########
|
||||
# Constants
|
||||
|
||||
CURRENT_I2P_VERSION = '2.8.2'
|
||||
CURRENT_I2P_FIREFOX_PROFILE_VERSION = '2.8.2'
|
||||
CURRENT_I2P_VERSION = '2.9.0'
|
||||
CURRENT_I2P_FIREFOX_PROFILE_VERSION = '2.9.0'
|
||||
CURRENT_I2P_OSX_VERSION = '1.9.0'
|
||||
|
||||
CANONICAL_DOMAIN = 'geti2p.net'
|
||||
|
48
i2p2www/blog/2025/06/02/2.9.0_release.rst
Normal file
48
i2p2www/blog/2025/06/02/2.9.0_release.rst
Normal file
@@ -0,0 +1,48 @@
|
||||
{% trans -%}
|
||||
=============
|
||||
2.9.0 Release
|
||||
=============
|
||||
{%- endtrans %}
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2025-06-02
|
||||
:category: release
|
||||
:excerpt: {% trans %}I2P 2.9.0 Release{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
I2P 2.9.0 is a maintenance release that includes bug fixes and work on new features.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Thread usage has been improved to improve the performance of the i2ptunnel system.
|
||||
NTCP2 has been improved to resist probing attacks.
|
||||
The notification system has been integrated into more applications to provide better feedback to users from I2PSnark and the other applications.
|
||||
Automatic floodfill enrollment has been fixed.
|
||||
Users may observe increased resource usage when acting as floodfill.
|
||||
If this is not desired, floodfill mode can be disabled on the /config page.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
A new global map feature is available in the console which shows the locations of routers in your view of the netDb.
|
||||
These are the peers that help your router build tunnels and provide services anonymously.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Work continues on implementing automatic bandwidth management for tunnels, the Datagram2 protocol, and Post-Quantum cryptography.
|
||||
In two releases, at 2.11.0, I2P will require Java 17.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
As usual, we recommend that you update to this release.
|
||||
The best way to maintain security and help the network is to run the latest release.
|
||||
{%- endtrans %}
|
||||
|
||||
**{% trans %}SHA256 Checksums:{% endtrans %}**
|
||||
|
||||
::
|
||||
|
||||
681884cf79f001a360dd3635f7b31e889d407af8c3edb6fe89d841a5421ba563 i2pinstall_2.9.0_windows.exe
|
||||
f4474ca98914f18fce1a4ce37a6b3cd080499919e4202a29b8eae51798f0c7c1 i2pinstall_2.9.0.jar
|
||||
03989319e186d9b06ed96ea0efa6ac95af1bc57af956d7f5f06f52f8da64fcd7 i2psource_2.9.0.tar.bz2
|
||||
1b79b2593bbe60e08da3f84411d48a5f1fe0c8cfd934f1c90d2fece436c1f2b5 i2pupdate_2.9.0.zip
|
||||
2df2d63a65d9d8743098203919693185c910ddd8a53f13e91d5be7d95d1d0e82 i2pupdate.su3
|
@@ -12,7 +12,7 @@
|
||||
<li><a href="#debian">Knoppix</a></li>
|
||||
</ul>
|
||||
|
||||
{% trans gtitlab='https://i2pgit.org/i2p-hackers/i2p.i2p/' -%}
|
||||
{% trans gtitlab='https://i2pgit.org/I2P_Developers/i2p.i2p/' -%}
|
||||
The I2P packages <em>may</em> work on systems not listed above. Please report any issues
|
||||
with these packages on <a href="{{ gtitlab }}">Gitlab</a> at
|
||||
<a href="{{ gtitlab }}">i2p.i2p</a>.
|
||||
|
@@ -20,7 +20,7 @@ Please verify that the hashes match the downloads when installing the bundle.
|
||||
<h2>{{ _('What do I need to use it?') }}</h2>
|
||||
<p><strong>{% trans -%}
|
||||
Just Firefox (Or Tor Browser).{%- endtrans %}</strong>
|
||||
{% trans issueurl="https://i2pgit.org/i2p-hackers/i2p.firefox/-/issues/2" -%}
|
||||
{% trans issueurl="https://i2pgit.org/I2P_Developers/i2p.firefox/-/issues/2" -%}
|
||||
This installer still requires Firefox to be installed on the system, it does not
|
||||
bundle a Firefox installer of its own. Please obtain Firefox from Mozilla, or
|
||||
Tor Browser from the Tor Project or one of their mirrors. If you would like to
|
||||
@@ -110,7 +110,7 @@ If you would like to examine the source code for individual components, you may
|
||||
find it on i2pgit.org or github.com. The license for each respective component
|
||||
can be found in the license directory of the <code>i2p.firefox</code> project.
|
||||
{%- endtrans %}</div>
|
||||
<div><a href="https://i2pgit.org/i2p-hackers/i2p.firefox">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/I2P_Developers/i2p.firefox">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://github.com/i2p/i2p.firefox">{% trans -%}Github Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/idk/i2p.plugins.firefox">{% trans -%}Gitlab Repository for Profile Manager{%- endtrans %}</a></div>
|
||||
<div><a href="https://github.com/eyedeekay/i2p.plugins.firefox">{% trans -%}Github Repository Profile Manager{%- endtrans %}</a></div>
|
||||
@@ -120,7 +120,7 @@ contact us. For security-sensitive issues, please remember to check the
|
||||
"This issue is confidential and should only be visible to team members with at least Reporter access"
|
||||
option when filing the issue.
|
||||
{%- endtrans %}</div>
|
||||
<div><a href="https://i2pgit.org/i2p-hackers/i2p.firefox/issues">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/I2P_Developers/i2p.firefox/issues">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<h2>{{ _('How is it different from Tor Browser?') }}</h2>
|
||||
<p>{% trans -%}
|
||||
This is not a fork of Firefox. Instead, it is a browser profile with pre-configured
|
||||
|
@@ -87,7 +87,7 @@ If you would like to examine the source code for individual components, you may
|
||||
find it on i2pgit.org or github.com. The license for each respective component
|
||||
can be found in the license directory of the <code>i2p.firefox</code> project.
|
||||
{%- endtrans %}</div>
|
||||
<div><a href="https://i2pgit.org/i2p-hackers/i2p.firefox">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/I2P_Developers/i2p.firefox">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://github.com/i2p/i2p.firefox">{% trans -%}Github Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/idk/i2p.plugins.firefox">{% trans -%}Gitlab Repository for Profile Manager{%- endtrans %}</a></div>
|
||||
<div><a href="https://github.com/eyedeekay/i2p.plugins.firefox">{% trans -%}Github Repository Profile Manager{%- endtrans %}</a></div>
|
||||
@@ -97,7 +97,7 @@ contact us. For security-sensitive issues, please remember to check the
|
||||
"This issue is confidential and should only be visible to team members with at least Reporter access"
|
||||
option when filing the issue.
|
||||
{%- endtrans %}</div>
|
||||
<div><a href="https://i2pgit.org/i2p-hackers/i2p.firefox/issues">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/I2P_Developers/i2p.firefox/issues">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<h2>{{ _('How is it different from Tor Browser?') }}</h2>
|
||||
<p>{% trans -%}
|
||||
This is not a fork of Firefox. Instead, it is a browser profile with pre-configured
|
||||
|
@@ -113,13 +113,13 @@ I2P to launch when your user logs in by right-clicking on the I2P Dock icon.
|
||||
If you would like to examine the source code for individual components, you may
|
||||
find it on i2pgit.org.
|
||||
{%- endtrans %}</div>
|
||||
<div><a href="https://i2pgit.org/i2p-hackers/i2p-jpackage-mac">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/I2P_Developers/i2p-jpackage-mac">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div>{% trans -%}
|
||||
If you wish to file an issue about the DMG Bundle, please use Gitlab to
|
||||
contact us. For security-sensitive issues, please remember to check the
|
||||
"This issue is confidential and should only be visible to team members with at
|
||||
least Reporter access" option when filing the issue.
|
||||
{%- endtrans %}</div>
|
||||
<div><a href="https://i2pgit.org/i2p-hackers/i2p-jpackage-mac/issues">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
<div><a href="https://i2pgit.org/I2P_Developers/i2p-jpackage-mac/issues">{% trans -%}Gitlab Repository{%- endtrans %}</a></div>
|
||||
|
||||
{% endblock %}
|
||||
|
@@ -1,14 +1,14 @@
|
||||
{% set i2pinstall_windows_hash = '7658f9ba7e28ab29ffeb3ec1909bf04f5ae391ee159980145ea01bd793c46f80' %}
|
||||
{% set i2pinstall_jar_hash = 'cd606827a9bca363bd6b3c89664772ec211d276cce3148f207643cc5e5949b8a' %}
|
||||
{% set i2psource_hash = '039b59fedd4a64aaeb6b74ab974310abdc9c08cb47ef1b8568c718965b50a485' %}
|
||||
{% set i2pupdate_hash = '15d886a9015dcf27ccc25e31b703ef6538b8b777176adf643dfe8ee0ba4984e0' %}
|
||||
{% set i2p_android_hash = '9378b9b50baae300f91f3fcf87ed8579ece2e650f4a83f3f23f7868c443479b8' %}
|
||||
{% set i2pinstall_windows_hash = 'fe106319dcf5972b7c833150292cb72ae6a764cf18929f043dfb9f10340ee782' %}
|
||||
{% set i2pinstall_jar_hash = 'fee438e9f42345eeef3f5255842bbcf725eb01f1f84589791a525cd45143555b' %}
|
||||
{% set i2psource_hash = '03989319e186d9b06ed96ea0efa6ac95af1bc57af956d7f5f06f52f8da64fcd7' %}
|
||||
{% set i2pupdate_hash = '1b79b2593bbe60e08da3f84411d48a5f1fe0c8cfd934f1c90d2fece436c1f2b5' %}
|
||||
{% set i2p_android_hash = '13b6e3c35756605e8e65804ab91cb34521c819fcfaebafb348eba5d40bed6699' %}
|
||||
{% set i2p_macnative_hash = '18cb22cfcc3cbe0cec150e89a394d1a35703cb508ed627ef48084b7ba7c90dde' %}
|
||||
|
||||
{% set i2p_windows_subver = '' %}
|
||||
{% set i2p_macosx_launcher_version = '1.9.0' %}
|
||||
|
||||
{% set i2p_android_version = '2.7.0' %}
|
||||
{% set i2p_android_version = '2.9.0' %}
|
||||
{% set i2p_android_version_kytv = '0.9.22' %}
|
||||
{% set i2p_android_version_fdroid = '2.6.0' %}
|
||||
|
||||
|
@@ -31,6 +31,17 @@
|
||||
#
|
||||
# Proposed new sections: application privacy, data anonymization, ...
|
||||
#
|
||||
@inproceedings {wangchuk,
|
||||
author = {Tashi Wangchuk and Ngaira Mandela and Tumaini Mbinda and Kamboisssoi Damedjate and Felix Etyang and Joel Makopa},
|
||||
title = {Forensic Analysis of I2P Communication Network in Android and macOS Environments},
|
||||
booktitle = {2024 11th International Conference on Computing for Sustainable Global Development (INDIACom)},
|
||||
year = {2024},
|
||||
url = {https://ieeexplore.ieee.org/document/10498888},
|
||||
publisher = {IEEE},
|
||||
month = {April},
|
||||
www_section = traffic,
|
||||
}
|
||||
|
||||
@inproceedings {abdo,
|
||||
author = {Jacques Bou Abdo and Liaquat Hossain},
|
||||
title = {Modeling the Invisible Internet},
|
||||
|
@@ -30,7 +30,7 @@ The following are discussed on the <a href="{{ othernetworks }}">other networks
|
||||
<li>Haystack</li>
|
||||
</ul>
|
||||
|
||||
<p>{% trans trac='https://i2pgit.org/i2p-hackers/i2p.www/issues' -%}
|
||||
<p>{% trans trac='https://i2pgit.org/I2P_Developers/i2p.www/issues' -%}
|
||||
The content of this page is subject to update, discussion and dispute, and we welcome comments and additions.
|
||||
You may contribute an analysis by entering a <a href="{{ trac }}">new issue on Github</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
@@ -14,7 +14,7 @@ The following networks are discussed on this page.
|
||||
<li>Haystack</li>
|
||||
</ul>
|
||||
|
||||
<p>{% trans comparison=site_url('comparison'), trac='https://i2pgit.org/i2p-hackers/i2p.www/issues' -%}
|
||||
<p>{% trans comparison=site_url('comparison'), trac='https://i2pgit.org/I2P_Developers/i2p.www/issues' -%}
|
||||
Most of the following sections are fairly old, and may not be accurate.
|
||||
For an overview of available comparisons, see the
|
||||
<a href="{{ comparison }}">main network comparisons page</a>.
|
||||
@@ -246,13 +246,13 @@ I2P is, of course, open source. However, that source, and our
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2>{{ _('Paid VPN Services') }}</h2>
|
||||
<p>{% trans trac='https://i2pgit.org/i2p-hackers/i2p.www/issues' -%}
|
||||
<p>{% trans trac='https://i2pgit.org/I2P_Developers/i2p.www/issues' -%}
|
||||
You may contribute an analysis by entering a
|
||||
<a href="{{ trac }}">new issue on Github</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2>{{ _('Others') }}</h2>
|
||||
<p>{% trans trac='https://i2pgit.org/i2p-hackers/i2p.www/issues' -%}
|
||||
<p>{% trans trac='https://i2pgit.org/I2P_Developers/i2p.www/issues' -%}
|
||||
You may contribute an analysis by entering a
|
||||
<a href="{{ trac }}">new issue on Github</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
@@ -1,18 +1,20 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{{ _('BOB - Basic Open Bridge') }}{% endblock %}
|
||||
{% block lastupdated %}2022-06{% endblock %}
|
||||
{% block lastupdated %}2025-05{% endblock %}
|
||||
{% block content %}
|
||||
<h2>Warning - Deprecated</h2>
|
||||
<p>Not for use by new applications.
|
||||
BOB supports the DSA-SHA1 signature type only.
|
||||
BOB, as specified here, supports the DSA-SHA1 signature type only.
|
||||
BOB will not be extended to support new signature types or other advanced features.
|
||||
New applications should use <a href="{{ site_url('docs/api/samv3') }}">SAM V3</a>.
|
||||
</p><p>
|
||||
BOB is not supported in Java I2P new installs as of release 1.7.0 (2022-02).
|
||||
BOB support was removed from Java I2P new installs as of release 1.7.0 (2022-02).
|
||||
It will still work in Java I2P originally installed as version 1.6.1 or earlier,
|
||||
even after updates, but it is unsupported and may break at any time.
|
||||
BOB is still supported by i2pd as of 2022-06, but applications
|
||||
BOB is still supported by i2pd as of 2025-05, but applications
|
||||
should still migrate to SAMv3 for the reasons above.
|
||||
See <a href="https://i2pd.readthedocs.io/en/latest/devs/i2pd-specifics/">the i2pd documentation</a>
|
||||
for any extensions to the API documented here that are supported by i2pd.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@@ -677,7 +677,8 @@ received through other forms are answered with an error message) :
|
||||
[HOST=$host] # Optional for DATAGRAM* and RAW, invalid for STREAM
|
||||
[FROM_PORT=nnn] # SAM 3.2 or higher only, default 0
|
||||
[TO_PORT=nnn] # SAM 3.2 or higher only, default 0
|
||||
[PROTOCOL=nnn] # SAM 3.2 or higher only, for STYLE=RAW only, default 18
|
||||
[PROTOCOL=nnn] # SAM 3.2 or higher only, for STYLE=RAW only, default 18.
|
||||
# 6, 17, 19, 20 not allowed.
|
||||
[HEADER={true,false}] # SAM 3.2 or higher only, for STYLE=RAW only, default false
|
||||
[sam.udp.host=hostname] # Datagram bind host, Java I2P only, DATAGRAM*/RAW only, default 127.0.0.1
|
||||
[sam.udp.port=nnn] # Datagram bind port, Java I2P only, DATAGRAM*/RAW only, default 7655
|
||||
@@ -870,7 +871,7 @@ depending on signature type.
|
||||
<b>NOTE:</b>
|
||||
Since about 2014 (SAM v3.1), Java I2P has also supported hostnames and b32 addresses for the $destination, but this was previously undocumented.
|
||||
Hostnames and b32 addresses are now officially supported by Java I2P as of release 0.9.48.
|
||||
The i2pd router will support hostnames and b32 addresses as of release 2.38.0 (0.9.50).
|
||||
The i2pd router supports hostnames and b32 addresses as of release 2.38.0 (0.9.50).
|
||||
For both routers, "b32" support includes support extended "b33" addresses for blinded destinations.
|
||||
</p>
|
||||
|
||||
@@ -1195,9 +1196,9 @@ This is all on one line (space separated), shown on multiple lines for clarity:
|
||||
3.0 # As of SAM 3.2, any "3.x" is allowed. Prior to that, "3.0" is required.
|
||||
$nickname
|
||||
$destination
|
||||
[FROM_PORT=nnn] # SAM 3.2 or higher only, default 0
|
||||
[TO_PORT=nnn] # SAM 3.2 or higher only, default 0
|
||||
[PROTOCOL=nnn] # SAM 3.2 or higher only, only for RAW sessions, default 18
|
||||
[FROM_PORT=nnn] # SAM 3.2 or higher only, default from session options
|
||||
[TO_PORT=nnn] # SAM 3.2 or higher only, default from session options
|
||||
[PROTOCOL=nnn] # SAM 3.2 or higher only, only for RAW sessions, default from session options
|
||||
[SEND_TAGS=nnn] # SAM 3.3 or higher only, number of session tags to send
|
||||
# Overrides crypto.tagsToSend I2CP session option
|
||||
# Default is router-dependent (40 for Java router)
|
||||
@@ -1290,7 +1291,8 @@ CREATE command with PORT and HOST options:
|
||||
[HOST=$host]
|
||||
[FROM_PORT=nnn] # SAM 3.2 or higher only, default 0
|
||||
[TO_PORT=nnn] # SAM 3.2 or higher only, default 0
|
||||
[PROTOCOL=nnn] # SAM 3.2 or higher only, for STYLE=RAW only, default 18
|
||||
[PROTOCOL=nnn] # SAM 3.2 or higher only, for STYLE=RAW only, default 18.
|
||||
# 6, 17, 19, 20 not allowed.
|
||||
[sam.udp.host=hostname] # Datagram bind host, Java I2P only, default 127.0.0.1
|
||||
[sam.udp.port=nnn] # Datagram bind port, Java I2P only, default 7655
|
||||
[option=value]* # I2CP options
|
||||
@@ -1609,7 +1611,8 @@ Using the same control socket on which the PRIMARY session was created:
|
||||
[HOST=$host] # Optional for DATAGRAM* and RAW, invalid for STREAM
|
||||
[FROM_PORT=nnn] # For outbound traffic, default 0
|
||||
[TO_PORT=nnn] # For outbound traffic, default 0
|
||||
[PROTOCOL=nnn] # For outbound traffic for STYLE=RAW only, default 18
|
||||
[PROTOCOL=nnn] # For outbound traffic for STYLE=RAW only, default 18.
|
||||
# 6, 17, 19, 20 not allowed.
|
||||
[LISTEN_PORT=nnn] # For inbound traffic, default is the FROM_PORT value.
|
||||
# For STYLE=STREAM, only the FROM_PORT value or 0 is allowed.
|
||||
[LISTEN_PROTOCOL=nnn] # For inbound traffic for STYLE=RAW only.
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Streaming Protocol{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2024-09{% endblock %}
|
||||
{% block accuratefor %}0.9.64{% endblock %}
|
||||
{% block lastupdated %}2025-07{% endblock %}
|
||||
{% block accuratefor %}0.9.67{% endblock %}
|
||||
{% block content %}
|
||||
<h2>{% trans %}Overview{% endtrans %}</h2>
|
||||
|
||||
@@ -457,16 +457,34 @@ Optional delay values greater than 60000 indicate choking, see below.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
<h3>{% trans %}Receive Window and Choking{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
TCP headers include the receive window in bytes.
|
||||
The streaming protocol does not contain a receive window, it uses only a simple choke/unchoke indication.
|
||||
<h3>Transmit/Receive Windows and Choking</h3>
|
||||
<p>
|
||||
TCP headers include the receive window in bytes; however,
|
||||
the streaming protocol does not provide a way to exchange max receive window size either in bytes or packets.
|
||||
There is only a simple choke/unchoke indication indicating that the receive buffer is full.
|
||||
Each endpoint must maintain its own estimate of the far-end receive window, in either bytes or packets.
|
||||
The recommended minimum buffer size for receiver implementations is 128 packets or 217 KB (approximately 128x1730).
|
||||
Note that a receive buffer may overflow at any window size if the
|
||||
client application is slow to empty the buffer.
|
||||
</p><p>
|
||||
The default maximum transmit and receive window size in the Java implementation is 128 packets.
|
||||
Implementations setting a maximum transmit window size higher than 128
|
||||
must consider the following issues:
|
||||
</p>
|
||||
<ul>
|
||||
<li>CHOKE responses from Java routers due to receive buffer overflow are much more likely.
|
||||
<li>Far-end receiver buffer size estimation must be implemented to mitigate repeated overflows (see above)
|
||||
<li>CHOKE must be handled correctly (see below)
|
||||
<li>Max window sizes over 256 are even more error-prone, because the nack count option field length
|
||||
is one byte, limiting the maximum NACKs to 255.
|
||||
This specification does not address what to do if there are more than 255 NACKs.
|
||||
Max window sizes over 256 are not recommended.
|
||||
</ul>
|
||||
<p>
|
||||
The recommended minimum buffer size for receiver implementations is 128 packets or 232 KB (approximately 128 * 1812).
|
||||
Because of I2P netowrk latency, packet drops, and the resulting congestion control,
|
||||
a buffer of this size is rarely filled.
|
||||
Overflow is, however, likely to occur on high-bandwidth "local loopback" (same-router) connections.
|
||||
{%- endtrans %}</p>
|
||||
Overflow is, however, much more likely to occur on high-bandwidth "local loopback" (same-router) connections or in local testing.
|
||||
</p>
|
||||
<p>{% trans -%}
|
||||
To quickly indicate and smoothly recover from overflow conditions,
|
||||
there is a simple mechanism for pushback in the streaming protocol.
|
||||
@@ -579,13 +597,14 @@ The following Control Block Sharing parameters can be set per router:
|
||||
</p>
|
||||
|
||||
<h3 id="other">{% trans %}Other Parameters{% endtrans %}</h3>
|
||||
<p>{% trans -%}
|
||||
The following parameters are hardcoded, but may be of interest for analysis:
|
||||
{%- endtrans %}</p>
|
||||
<p>
|
||||
The following parameters are recommended defaults. Defaults may vary, implementation dependent:
|
||||
</p>
|
||||
<ul>
|
||||
<li>MIN_RESEND_DELAY = 100 ms (minimum RTO)
|
||||
<li>MAX_RESEND_DELAY = 45 sec (maximum RTO)
|
||||
<li>MIN_WINDOW_SIZE = 1
|
||||
<li>MAX_WINDOW_SIZE = 128
|
||||
<li>TREND_COUNT = 3
|
||||
<li>MIN_MESSAGE_SIZE = 512 (minimum MTU)
|
||||
<li>INBOUND_BUFFER_SIZE = maxMessageSize * (maxWindowSize + 2)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Bittorrent over I2P{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2024-11{% endblock %}
|
||||
{% block accuratefor %}0.9.64{% endblock %}
|
||||
{% block lastupdated %}2025-06{% endblock %}
|
||||
{% block accuratefor %}0.9.67{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<p>{% trans -%}
|
||||
@@ -133,12 +133,16 @@ the HTTP client proxy at port 4444. Doing so is both more efficient and it allow
|
||||
destination enforcement by the tracker (see below).
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans -%}
|
||||
There are no known I2P clients or trackers that currently support UDP announce/responses.
|
||||
{%- endtrans %}</p>
|
||||
<p>
|
||||
The specification for UDP announces was finalized 2025-06.
|
||||
Support in various I2P clients and trackers will be rolling out later in 2025.
|
||||
See below for additional information.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>{% trans %}Non-Compact Tracker Responses{% endtrans %}</h2>
|
||||
Note: Deprecated. All popular trackers now support compact responses and at least one requires compact=1 in the announce.
|
||||
All clients should request and support compact responses.
|
||||
<p>{% trans -%}
|
||||
The non-compact response is just as in standard bittorrent, with an I2P "ip".
|
||||
{%- endtrans %}
|
||||
@@ -357,22 +361,19 @@ Alternatives: A single byte string with concatenated hashes,
|
||||
or a list of strings alone.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
{% set udp_spec = spec_url('udp-announces') %}
|
||||
{% set dg2_spec = spec_url('datagrams') %}
|
||||
|
||||
<h2>{% trans %}Datagram (UDP) Trackers{% endtrans %}</h2>
|
||||
<p>{% trans -%}
|
||||
UDP tracker support in clients and trackers is not yet available.
|
||||
Preliminary differences from
|
||||
<p>
|
||||
The specification for UDP announces in I2P was finalized 2025-06.
|
||||
Support in various I2P clients and trackers will be rolling out later in 2025.
|
||||
Differences from
|
||||
<a href="http://www.bittorrent.org/beps/bep_0015.html">BEP 15</a>
|
||||
are described below, and are subject to change.
|
||||
Contact the I2P developers if you wish to develop a client or tracker supporting datagram announces.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<p>{% trans prop160=site_url('docs/spec/proposals/160') -%}
|
||||
See <a href="{{ prop160 }}">Proposal 160</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
|
||||
are documented in <a href="{{ udp_spec }}">the UDP announce specification</a>.
|
||||
The specification also requires support for
|
||||
<a href="{{ dg2_spec }}">the new Datagram 2/3 formats</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>{% trans %}Additional Information{% endtrans %}</h2>
|
||||
|
@@ -24,7 +24,7 @@
|
||||
<pre><code>git fetch $HOME/.i2p/i2psnark/i2p.i2p.bundle</code></pre>
|
||||
<h3 id="replace-the-bundle-remote-with-the-upstream-remote">{% trans -%}Replace the bundle remote with the upstream remote{%- endtrans %}</h3>
|
||||
<p>{% trans -%} Now that you have a bundle, you can keep up with changes by setting the remote to the upstream repository source. {%- endtrans %}</p>
|
||||
<pre><code>git remote set-url origin git@127.0.0.1:i2p-hackers/i2p.i2p</code></pre>
|
||||
<pre><code>git remote set-url origin git@127.0.0.1:I2P_Developers/i2p.i2p</code></pre>
|
||||
<h2 id="generating-a-bundle">{% trans -%}Generating a Bundle{%- endtrans %}</h2>
|
||||
<p>{% trans -%} First, follow the <a href="GIT.md">Git guide for Users</a> until you have a successfully <code>--unshallow</code>ed clone of clone of the i2p.i2p repository. If you already have a clone, make sure you run <code>git fetch --unshallow</code> before you generate a torrent bundle. {%- endtrans %}</p>
|
||||
<p>{% trans -%}Once you have that, simply run the corresponding ant target:{%- endtrans %}</p>
|
||||
|
@@ -24,7 +24,7 @@ using the instructions on the home page.{%- endtrans %}</p>
|
||||
<img src="/_static/images/git/register.png" alt="" /><figcaption>Registration is easy!</figcaption>
|
||||
</figure>
|
||||
<h2 id="second-create-a-project-to-test-with">Second: Create a project to test with</h2>
|
||||
<p>{% trans -%} To make sure the setup process works, it helps to make a repository to test with from the server, and for the sake of this tutorial, we’re going to use a fork of the I2P router. First, browse to the i2p-hackers/i2p.i2p repository: {%- endtrans %}</p>
|
||||
<p>{% trans -%} To make sure the setup process works, it helps to make a repository to test with from the server, and for the sake of this tutorial, we’re going to use a fork of the I2P router. First, browse to the I2P_Developers/i2p.i2p repository: {%- endtrans %}</p>
|
||||
<figure>
|
||||
<img src="/_static/images/git/explore.png" alt="" /><figcaption>Browse to i2p.i2p</figcaption>
|
||||
</figure>
|
||||
@@ -99,7 +99,7 @@ git fetch origin</code></pre>
|
||||
</ul>
|
||||
<ol type="1">
|
||||
<li><p>{% trans -%}Set up a second remote in your local repository using the upstream source code.{%- endtrans %}</p>
|
||||
<pre><code>git remote add upstream git@127.0.0.1:i2p-hackers/i2p.i2p</code></pre></li>
|
||||
<pre><code>git remote add upstream git@127.0.0.1:I2P_Developers/i2p.i2p</code></pre></li>
|
||||
<li><p>{% trans -%}Pull in any upstream changes on your current master:{%- endtrans %}</p>
|
||||
<pre><code>git pull upstream master</code></pre></li>
|
||||
<li><p>{% trans -%}Before making any changes to the source code, check out a new feature branch to develop on:{%- endtrans %}</p>
|
||||
@@ -110,7 +110,7 @@ git push origin feature-branch-name</code></pre></li>
|
||||
<li><p>{% trans -%}Submit a merge request. When the merge request is approved and brought into the upstream master, check out the master locally and pull in the changes:{%- endtrans %}</p>
|
||||
<pre><code>git checkout master
|
||||
git pull upstream master</code></pre></li>
|
||||
<li><p>{% trans -%}Whenever a change to the upstream master(i2p-hackers/i2p.i2p) is made, you can update your master code using this procedure as well.{%- endtrans %}</p>
|
||||
<li><p>{% trans -%}Whenever a change to the upstream master(I2P_Developers/i2p.i2p) is made, you can update your master code using this procedure as well.{%- endtrans %}</p>
|
||||
<pre><code>git checkout master
|
||||
git pull upstream master</code></pre></li>
|
||||
</ol>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %}{% trans %}Index to Technical Documentation{% endtrans %}{% endblock %}
|
||||
{% block lastupdated %}2022-08{% endblock %}
|
||||
{% block accuratefor %}0.9.55{% endblock %}
|
||||
{% block lastupdated %}2025-06{% endblock %}
|
||||
{% block accuratefor %}0.9.67{% endblock %}
|
||||
{% block content %}
|
||||
<p>{% trans -%}
|
||||
Following is an index to the technical documentation for I2P.
|
||||
@@ -19,7 +19,7 @@ The specifications linked below are currently supported in the network.
|
||||
See the <a href="{{ site_url('spec/proposals') }}">{{ _('Proposals') }}</a> page for
|
||||
specifications in discussion or development.
|
||||
|
||||
<p>{% trans trac='https://i2pgit.org/i2p-hackers/i2p.www/issues' -%}
|
||||
<p>{% trans trac='https://i2pgit.org/I2P_Developers/i2p.www/issues' -%}
|
||||
The I2P Project is committed to maintaining accurate, current documentation.
|
||||
If you find any inaccuracies in the documents linked below, please
|
||||
<a href="{{ trac }}">enter a ticket identifying the problem</a>.
|
||||
@@ -50,6 +50,7 @@ If you find any inaccuracies in the documents linked below, please
|
||||
<li><a href="{{ site_url('docs/applications/managed-clients') }}">{{ _('Managed Clients') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/applications/embedding') }}">{{ _('Embedding the router in your application') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/applications/bittorrent') }}">{{ _('Bittorrent over I2P') }}</a></li>
|
||||
<li><a href="{{ spec_url('udp-announces') }}">{{ _('Bittorrent UDP Announces') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/api/i2pcontrol') }}">{{ _('I2PControl Plugin API') }}</a></li>
|
||||
<li><a href="{{ spec_url('blockfile') }}">{{ _('hostsdb.blockfile Format') }}</a></li>
|
||||
<li><a href="{{ spec_url('configuration') }}">{{ _('Configuration File Format') }}</a></li>
|
||||
@@ -122,6 +123,7 @@ Traditionally used only by Java applications and higher-level APIs.
|
||||
{% trans %}How client messages are end-to-end encrypted by the router.{% endtrans %}
|
||||
<ul>
|
||||
<li><a href="{{ spec_url('ecies') }}">{{ _('ECIES-X25519-AEAD-Ratchet encryption for destinations') }}</a></li>
|
||||
<li><a href="{{ spec_url('ecies-hybrid') }}">PQ Hybrid {{ _('ECIES-X25519-AEAD-Ratchet encryption for destinations') }}</a></li>
|
||||
<li><a href="{{ spec_url('ecies-routers') }}">{{ _('ECIES-X25519 encryption for routers') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/how/elgamal-aes') }}">{{ _('ElGamal/AES+SessionTag encryption') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/how/cryptography') }}">{{ _('ElGamal and AES cryptography details') }}</a></li>
|
||||
@@ -256,7 +258,7 @@ ancient (str4d)
|
||||
</li><li>
|
||||
<a href="http://{{ i2pconv('zzz.i2p') }}/">{{ _('Developer forum inside I2P') }}</a>
|
||||
</li><li>
|
||||
<a href="https://i2pgit.org/i2p-hackers/i2p.i2p/issues">{{ _('Bug tracker') }}</a>
|
||||
<a href="https://i2pgit.org/I2P_Developers/i2p.i2p/issues">{{ _('Bug tracker') }}</a>
|
||||
</li><li>
|
||||
<a href="https://github.com/i2p/i2p.i2p">{{ _('I2P Source exported to GitHub') }}</a>
|
||||
</li><li>
|
||||
|
@@ -1036,8 +1036,8 @@ either through our IRC network, IRC2P, or on Freenode.{%- endtrans %}</p>
|
||||
<ul>
|
||||
<li>{% trans -%}Our Bugtracker:{%- endtrans %}
|
||||
<ul>
|
||||
<li>{% trans -%}Non-private internet:{%- endtrans %} <a href="https://i2pgit.org/i2p-hackers/i2p.i2p/issues">https://i2pgit.org/i2p-hackers/i2p.i2p/issues</a></li>
|
||||
<li>{% trans -%}On I2P:{%- endtrans %} <a href="http://git.idk.i2p/i2p-hackers/i2p.i2p/issues">http://git.idk.i2p/i2p-hackers/i2p.i2p/issues</a></li>
|
||||
<li>{% trans -%}Non-private internet:{%- endtrans %} <a href="https://i2pgit.org/I2P_Developers/i2p.i2p/issues">https://i2pgit.org/I2P_Developers/i2p.i2p/issues</a></li>
|
||||
<li>{% trans -%}On I2P:{%- endtrans %} <a href="http://git.idk.i2p/I2P_Developers/i2p.i2p/issues">http://git.idk.i2p/I2P_Developers/i2p.i2p/issues</a></li>
|
||||
</ul>
|
||||
<li>{% trans -%}Our forums:{%- endtrans %} <a href="http://{{ i2pconv('i2pforum.i2p') }}/">{{ i2pconv('i2pforum.i2p') }}</a></li>
|
||||
<li>{% trans -%}You may paste any interesting logs to a paste service such as the non-private internet services listed on the
|
||||
|
@@ -109,7 +109,7 @@ check it into a new branch on your own gitlab account, create an MR, and assign
|
||||
Assign the MR to yourself. Merge the MR yourself once the reviewer approves it.
|
||||
</li>
|
||||
<li>
|
||||
Do not create WIP branches in the main i2p-hackers account (except for i2p.www).
|
||||
Do not create WIP branches in the main I2P_Developers account (except for i2p.www).
|
||||
WIP belongs in your own account. When the work is done, create an MR.
|
||||
The only branches in the main account should be for true forks, like a point release.
|
||||
</li>
|
||||
|
@@ -65,7 +65,7 @@ Install <a href="{{ git_url }}">Git</a>.
|
||||
</li>
|
||||
<li><strong><a href="https://i2pgit.org">{% trans %}Outside I2P - (https://i2pgit.org){% endtrans %}</a></strong>
|
||||
</li>
|
||||
<code>git clone https://i2pgit.org/i2p-hackers/i2p.i2p.git</code>
|
||||
<code>git clone https://i2pgit.org/I2P_Developers/i2p.i2p.git</code>
|
||||
</ul>
|
||||
|
||||
<p>The read-only mirror is also still available at github.</p>
|
||||
@@ -100,7 +100,7 @@ see the <a href="{{ apps }}">application development guide</a>.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
<h2 id="development-ideas">{% trans %}Development ideas{% endtrans %}</h2>
|
||||
<p>{% trans todo=site_url('get-involved/todo'), trac='https://i2pgit.org/i2p-hackers/i2p.i2p/issues' -%}
|
||||
<p>{% trans todo=site_url('get-involved/todo'), trac='https://i2pgit.org/I2P_Developers/i2p.i2p/issues' -%}
|
||||
See <a href="{{ todo }}">the project TODO list</a> or
|
||||
<a href="{{ trac }}">the issue list on GitLab</a>
|
||||
for ideas.
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{% block title %} {{ _('Roadmap') }}{% endblock %}
|
||||
{% block lastupdated %}2025-04{% endblock %} {% block content %}
|
||||
{% block lastupdated %}2025-08{% endblock %} {% block content %}
|
||||
|
||||
<p>
|
||||
This is the official project roadmap for the desktop and Android Java I2P releases only. Some related tasks for resources such as the website and plugins may be included.
|
||||
@@ -16,21 +16,51 @@
|
||||
</p>
|
||||
|
||||
|
||||
<h2 id="2.10.0">2.10.0 (API 0.9.67)</h2>
|
||||
<p><b>Target release: Late August 2025</b></p>
|
||||
<h2 id="2.11.0">2.11.0 (API 0.9.68)</h2>
|
||||
<p><b>Target release: Early Dec. 2025</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
Restart work on UDP trackers (prop. 160)
|
||||
Hybrid PQ MLKEM Ratchet final, enable by default (prop. 169)
|
||||
</li>
|
||||
<li>
|
||||
Implement Datagram2, Datagram3 (prop. 163)
|
||||
Jetty 12, require Java 17+
|
||||
</li>
|
||||
<li>
|
||||
Implement LS service record parameter (prop. 167)
|
||||
Continue work on PQ (transports) (prop. 169)
|
||||
</li>
|
||||
<li>
|
||||
Continue work on PQ (prop. 169);
|
||||
Start checking in MLKEM parts of PQ (prop. 169)
|
||||
I2CP lookup support for LS service record parameters (prop. 167)
|
||||
</li>
|
||||
<li>
|
||||
Per-tunnel throttling
|
||||
</li>
|
||||
<li>
|
||||
Prometheus-friendly stat subsystem
|
||||
</li>
|
||||
<li>
|
||||
SAM support for Datagram 2/3
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2 id="2.10.0">2.10.0 (API 0.9.67)</h2>
|
||||
<p><b>Target release: Early Sept. 2025</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
i2psnark UDP tracker support (prop. 160)
|
||||
</li>
|
||||
<li>
|
||||
I2CP LS service record parameters (partial) (prop. 167)
|
||||
</li>
|
||||
<li>
|
||||
I2CP async lookup API
|
||||
</li>
|
||||
<li>
|
||||
Hybrid PQ MLKEM Ratchet Beta (prop. 169)
|
||||
</li>
|
||||
<li>
|
||||
Continue work on PQ (transports) (prop. 169)
|
||||
</li>
|
||||
<li>
|
||||
Tunnel build bandwidth parameters (prop. 168)
|
||||
@@ -40,23 +70,32 @@
|
||||
Continue work on per-tunnel throttling
|
||||
</li>
|
||||
<li>
|
||||
Stat/graph subsystem cleanup and make prometheus-friendly
|
||||
Remove unused transport ElGamal code
|
||||
</li>
|
||||
<li>
|
||||
Tomcat update
|
||||
Remove ancient SSU2 "active throttle" code
|
||||
</li>
|
||||
<li>
|
||||
Remove ancient stat logging support
|
||||
</li>
|
||||
<li>
|
||||
Stat/graph subsystem cleanup
|
||||
</li>
|
||||
<li>
|
||||
Hidden mode improvements and fixes
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<h2 id="2.9.0">2.9.0 (API 0.9.66)</h2>
|
||||
<p><b>Target release: June 3, 2025</b></p>
|
||||
<p><b>Released: June 2, 2025</b></p>
|
||||
<ul>
|
||||
<li>
|
||||
Netdb map
|
||||
</li>
|
||||
<li>
|
||||
Start work on Datagram2 (prop. 163)
|
||||
Implement Datagram2, Datagram3 (prop. 163)
|
||||
</li>
|
||||
<li>
|
||||
Start work on LS service record parameter (prop. 167)
|
||||
|
@@ -22,7 +22,7 @@ in during the course of development. Periodic reviews are conducted to update
|
||||
the "accurate for" information.
|
||||
</li></ul>
|
||||
|
||||
<p>{% trans trac='https://i2pgit.org/i2p-hackers/i2p.www/issues' -%}
|
||||
<p>{% trans trac='https://i2pgit.org/I2P_Developers/i2p.www/issues' -%}
|
||||
The I2P Project is committed to maintaining accurate, current documentation.
|
||||
If you find any inaccuracies in the documents linked below, please
|
||||
<a href="{{ trac }}">enter a ticket identifying the problem</a>.
|
||||
@@ -55,7 +55,6 @@ If you find any inaccuracies in the documents linked below, please
|
||||
Current specifications: These may eventually be migrated to the new format.
|
||||
|
||||
<ul>
|
||||
<li><a href="{{ site_url('docs/how/elgamal-aes') }}">{{ _('ElGamal/AES+SessionTags') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/api/i2pcontrol') }}">I2PControl</a></li>
|
||||
<li><a href="{{ site_url('docs/api/samv3') }}">SAM v3</a></li>
|
||||
<li><a href="{{ site_url('docs/applications/bittorrent') }}">{{ _('Bittorrent') }}</a></li>
|
||||
@@ -65,8 +64,14 @@ Current specifications: These may eventually be migrated to the new format.
|
||||
Obsolete specifications:
|
||||
|
||||
<ul>
|
||||
<li><a href="{{ site_url('docs/transport/ntcp') }}">NTCP</a></li>
|
||||
<li><a href="{{ site_url('docs/api/bob') }}">BOB</a></li>
|
||||
<li><a href="{{ site_url('docs/how/elgamal-aes') }}">{{ _('ElGamal/AES+SessionTags') }}</a></li>
|
||||
<li><a href="{{ site_url('docs/transport/ntcp') }}">NTCP 1</a></li>
|
||||
<li><a href="{{ site_url('docs/api/sam') }}">SAM v1</a></li>
|
||||
<li><a href="{{ site_url('docs/api/samv2') }}">SAM v2</a></li>
|
||||
<li><a href="{{ site_url('docs/transport/ssu') }}">SSU 1 (overview)</a></li>
|
||||
<li><a href="{{ spec_url('ssu') }}">SSU 1 (spec)</a></li>
|
||||
<li><a href="{{ spec_url('tunnel-creation') }}">Tunnel Creation (ElGamal)</a></li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
|
@@ -3,8 +3,8 @@ Common structures Specification
|
||||
===============================
|
||||
.. meta::
|
||||
:category: Design
|
||||
:lastupdated: 2025-04
|
||||
:accuratefor: 0.9.66
|
||||
:lastupdated: 2025-06
|
||||
:accuratefor: 0.9.67
|
||||
|
||||
.. contents::
|
||||
|
||||
@@ -84,15 +84,24 @@ X25519 keys are supported in RouterIdentities as of release 0.9.48.
|
||||
|
||||
|
||||
|
||||
======= ============== ====== =====
|
||||
Type Length (bytes) Since Usage
|
||||
======= ============== ====== =====
|
||||
ElGamal 256 Deprecated for Router Identities as of 0.9.58; use for Destinations, as the public key field is unused there; discouraged for leasesets
|
||||
P256 64 TBD Reserved, see proposal 145
|
||||
P384 96 TBD Reserved, see proposal 145
|
||||
P521 132 TBD Reserved, see proposal 145
|
||||
X25519 32 0.9.38 Little-endian. See [ECIES]_ and [ECIES-ROUTERS]_
|
||||
======= ============== ====== =====
|
||||
================ ================= ====== =====
|
||||
Type Length (bytes) Since Usage
|
||||
================ ================= ====== =====
|
||||
ElGamal 256 Deprecated for Router Identities as of 0.9.58; use for Destinations, as the public key field is unused there; discouraged for leasesets
|
||||
P256 64 TBD Reserved, see proposal 145
|
||||
P384 96 TBD Reserved, see proposal 145
|
||||
P521 132 TBD Reserved, see proposal 145
|
||||
X25519 32 0.9.38 Little-endian. See [ECIES]_ and [ECIES-ROUTERS]_
|
||||
MLKEM512_X25519 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM768_X25519 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM1024_X25519 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM512 800 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM768 1184 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM1024 1568 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM512_CT 768 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM768_CT 1088 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM1024_CT 1568 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
================ ================= ====== =====
|
||||
|
||||
JavaDoc: http://{{ i2pconv('idk.i2p/javadoc-i2p') }}/net/i2p/data/PublicKey.html
|
||||
|
||||
@@ -116,15 +125,21 @@ 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.
|
||||
|
||||
======= ============== ====== =====
|
||||
Type Length (bytes) Since Usage
|
||||
======= ============== ====== =====
|
||||
ElGamal 256 Deprecated for Router Identities as of 0.9.58; use for Destinations, as the public key field is unused there; discouraged for leasesets
|
||||
P256 32 TBD Reserved, see proposal 145
|
||||
P384 48 TBD Reserved, see proposal 145
|
||||
P521 66 TBD Reserved, see proposal 145
|
||||
X25519 32 0.9.38 Little-endian. See [ECIES]_ and [ECIES-ROUTERS]_
|
||||
======= ============== ====== =====
|
||||
================ ================== ====== =====
|
||||
Type Length (bytes) Since Usage
|
||||
================ ================== ====== =====
|
||||
ElGamal 256 Deprecated for Router Identities as of 0.9.58; use for Destinations, as the public key field is unused there; discouraged for leasesets
|
||||
P256 32 TBD Reserved, see proposal 145
|
||||
P384 48 TBD Reserved, see proposal 145
|
||||
P521 66 TBD Reserved, see proposal 145
|
||||
X25519 32 0.9.38 Little-endian. See [ECIES]_ and [ECIES-ROUTERS]_
|
||||
MLKEM512_X25519 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM768_X25519 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM1024_X25519 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM512 1632 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM768 2400 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
MLKEM1024 3168 0.9.67 See [ECIES-HYBRID]_, for handshakes only, not for Leasesets, RIs or Destinations
|
||||
================ ================== ====== =====
|
||||
|
||||
JavaDoc: http://{{ i2pconv('idk.i2p/javadoc-i2p') }}/net/i2p/data/PrivateKey.html
|
||||
|
||||
@@ -436,26 +451,39 @@ RSA_SHA384_3072 5 384 0.9.12 Deprecated
|
||||
RSA_SHA512_4096 6 512 0.9.12 Offline only; never used in Key Certificates for Router Identities or Destinations
|
||||
EdDSA_SHA512_Ed25519 7 32 0.9.15 Recent Router Identities and Destinations
|
||||
EdDSA_SHA512_Ed25519ph 8 32 0.9.25 Offline only; never used in Key Certificates for Router Identities or Destinations
|
||||
reserved (GOST) 9 64 Reserved, see proposal 134
|
||||
reserved (GOST) 10 128 Reserved, see proposal 134
|
||||
reserved (GOST) 9 64 Reserved, see [Prop134]_
|
||||
reserved (GOST) 10 128 Reserved, see [Prop134]_
|
||||
RedDSA_SHA512_Ed25519 11 32 0.9.39 For Destinations and encrypted leasesets only; never used for Router Identities
|
||||
reserved (MLDSA) 12 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 13 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 14 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 15 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 16 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 17 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 18 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 19 Reserved, see [Prop169]_
|
||||
reserved (MLDSA) 20 Reserved, see [Prop169]_
|
||||
reserved 65280-65534 Reserved for experimental use
|
||||
reserved 65535 Reserved for future expansion
|
||||
====================== =========== ======================= ====== =====
|
||||
|
||||
The defined Crypto Public Key types are:
|
||||
|
||||
======== =========== ======================= =====
|
||||
Type Type Code Total Public Key Length Usage
|
||||
======== =========== ======================= =====
|
||||
ElGamal 0 256 Deprecated for Router Identities as of 0.9.58; use for Destinations, as the public key field is unused there
|
||||
P256 1 64 Reserved, see proposal 145
|
||||
P384 2 96 Reserved, see proposal 145
|
||||
P521 3 132 Reserved, see proposal 145
|
||||
X25519 4 32 See [ECIES]_ and proposal 156
|
||||
reserved 65280-65534 Reserved for experimental use
|
||||
reserved 65535 Reserved for future expansion
|
||||
======== =========== ======================= =====
|
||||
================ =========== ======================= ====== =====
|
||||
Type Type Code Total Public Key Length Since Usage
|
||||
================ =========== ======================= ====== =====
|
||||
ElGamal 0 256 Deprecated for Router Identities as of 0.9.58; use for Destinations, as the public key field is unused there
|
||||
P256 1 64 Reserved, see proposal 145
|
||||
P384 2 96 Reserved, see proposal 145
|
||||
P521 3 132 Reserved, see proposal 145
|
||||
X25519 4 32 0.9.38 See [ECIES]_ and proposal 156
|
||||
MLKEM512_X25519 5 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM768_X25519 6 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
MLKEM1024_X25519 7 32 0.9.67 See [ECIES-HYBRID]_, for Leasesets only, not for RIs or Destinations
|
||||
reserved (NONE) 255 Reserved, see [Prop169]_
|
||||
reserved 65280-65534 Reserved for experimental use
|
||||
reserved 65535 Reserved 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
|
||||
@@ -1881,6 +1909,9 @@ References
|
||||
.. [ECIES]
|
||||
{{ spec_url('ecies') }}
|
||||
|
||||
.. [ECIES-HYBRID]
|
||||
{{ spec_url('ecies-hybrid') }}
|
||||
|
||||
.. [ECIES-ROUTERS]
|
||||
{{ spec_url('ecies-routers') }}
|
||||
|
||||
@@ -1905,6 +1936,12 @@ References
|
||||
.. [NETDB-ROUTERINFO]
|
||||
{{ site_url('docs/how/network-database', True) }}#routerInfo
|
||||
|
||||
.. [Prop134]
|
||||
{{ proposal_url('134') }}
|
||||
|
||||
.. [Prop169]
|
||||
{{ proposal_url('169') }}
|
||||
|
||||
.. [REGISTRY]
|
||||
http://www.dns-sd.org/ServiceTypes.html
|
||||
|
||||
|
@@ -3,8 +3,8 @@ Low-level Cryptography Specification
|
||||
====================================
|
||||
.. meta::
|
||||
:category: Design
|
||||
:lastupdated: 2020-09
|
||||
:accuratefor: 0.9.47
|
||||
:lastupdated: 2025-05
|
||||
:accuratefor: 0.9.66
|
||||
|
||||
.. contents::
|
||||
|
||||
@@ -12,6 +12,18 @@ Low-level Cryptography Specification
|
||||
Overview
|
||||
========
|
||||
|
||||
NOTE: MOSTLY OBSOLETE -
|
||||
See the following documents for current specifications:
|
||||
|
||||
- {{ spec_url('ecies') }}
|
||||
- {{ spec_url('encryptedleaseset') }}
|
||||
- {{ spec_url('ntcp2') }}
|
||||
- {{ spec_url('red25519') }}
|
||||
- {{ spec_url('ssu2') }}
|
||||
- {{ spec_url('tunnel-creation-ecies') }}
|
||||
|
||||
|
||||
|
||||
This page specifies the low-level details of the cryptography in I2P.
|
||||
|
||||
There are several cryptographic algorithms in use within I2P.
|
||||
@@ -39,11 +51,10 @@ of ElGamal asymmetric encryption and AES symmetric encryption.
|
||||
Newer protocols NTCP2 and ECIES-X25519-AEAD-Ratchet
|
||||
use a combination of X25519 key exchange and ChaCha20/Poly1305 symmetric encryption.
|
||||
|
||||
- ECIES-X25519-AEAD-Ratchet has replaced ElGamal/AES+SessionTags.
|
||||
- NTCP2 has replaced NTCP.
|
||||
- ECIES-X25519-AEAD-Ratchet design and implementation are complete,
|
||||
and will replace ElGamal/AES+SessionTags in late 2020.
|
||||
- SSU2, using X25519 and ChaCha20/Poly1305, is scheduled for design in late 2020
|
||||
to replace SSU in 2021.
|
||||
- SSU2 has replaced SSU.
|
||||
- X25519 tunnel creation has replaced ElGamal tunnel creation.
|
||||
|
||||
|
||||
Asymmetric Encryption
|
||||
|
833
i2p2www/spec/ecies-hybrid.rst
Normal file
833
i2p2www/spec/ecies-hybrid.rst
Normal file
@@ -0,0 +1,833 @@
|
||||
===================================
|
||||
PQ Hybrid ECIES-X25519-AEAD-Ratchet
|
||||
===================================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-06
|
||||
:accuratefor: 0.9.67
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
Note
|
||||
====
|
||||
|
||||
Implementation, testing, and rollout in progress in the various
|
||||
router implementations. Check the documentation of those implementations for status.
|
||||
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
This is the PQ Hybrid variant of the ECIES-X25519-AEAD-Ratchet protocol [ECIES]_.
|
||||
It is the first phase of the overall PQ proposal [Prop169]_
|
||||
to be approved. See that proposal for overall goals, threat models,
|
||||
analysis, alternatives, and additional information.
|
||||
|
||||
This specification contains only the differences from standard [ECIES]_
|
||||
and must be read in conjunction with that specification.
|
||||
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
We use the NIST FIPS 203 standard [FIPS203]_
|
||||
which is based on, but not compatible with,
|
||||
CRYSTALS-Kyber (versions 3.1, 3, and older).
|
||||
|
||||
Hybrid handshakes are as specified in [Noise-Hybrid]_.
|
||||
|
||||
|
||||
Key Exchange
|
||||
-------------
|
||||
|
||||
We define a hybrid key exchange for Ratchet.
|
||||
PQ KEM provides ephemeral keys only, and does not directly support
|
||||
static-key handshakes such as Noise IK.
|
||||
|
||||
We define the three ML-KEM variants as in [FIPS203]_,
|
||||
for 3 new encryption types total.
|
||||
Hybrid types are only defined in combination with X25519.
|
||||
|
||||
The new encryption types are:
|
||||
|
||||
================ ====
|
||||
Type Code
|
||||
================ ====
|
||||
MLKEM512_X25519 5
|
||||
MLKEM768_X25519 6
|
||||
MLKEM1024_X25519 7
|
||||
================ ====
|
||||
|
||||
Overhead will be substantial. Typical message 1 and 2 sizes (for IK)
|
||||
are currently around 100 bytes (before any additional payload).
|
||||
This will increase by 8x to 15x depending on algorithm.
|
||||
|
||||
|
||||
New Crypto Required
|
||||
-------------------
|
||||
|
||||
- ML-KEM (formerly CRYSTALS-Kyber) [FIPS203]_
|
||||
- SHA3-128 (formerly Keccak-256) [FIPS202]_ Used only for SHAKE128
|
||||
- SHA3-256 (formerly Keccak-512) [FIPS202]_
|
||||
- SHAKE128 and SHAKE256 (XOF extensions to SHA3-128 and SHA3-256) [FIPS202]_
|
||||
|
||||
Test vectors for SHA3-256, SHAKE128, and SHAKE256 are at [NIST-VECTORS]_.
|
||||
|
||||
Note that the Java bouncycastle library supports all the above.
|
||||
C++ library support is in OpenSSL 3.5 [OPENSSL]_.
|
||||
|
||||
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
Common Structures
|
||||
-----------------
|
||||
|
||||
See the common structures specification [COMMON]_ for key lengths and identifiers.
|
||||
|
||||
|
||||
|
||||
Handshake Patterns
|
||||
------------------
|
||||
|
||||
Handshakes use [Noise]_ handshake patterns.
|
||||
|
||||
The following letter mapping is used:
|
||||
|
||||
- e = one-time ephemeral key
|
||||
- s = static key
|
||||
- p = message payload
|
||||
- e1 = one-time ephemeral PQ key, sent from Alice to Bob
|
||||
- ekem1 = the KEM ciphertext, sent from Bob to Alice
|
||||
|
||||
The following modifications to XK and IK for hybrid forward secrecy (hfs) are
|
||||
as specified in [Noise-Hybrid]_ section 5:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
|
||||
IK: IKhfs:
|
||||
<- s <- s
|
||||
... ...
|
||||
-> e, es, s, ss, p -> e, es, e1, s, ss, p
|
||||
<- tag, e, ee, se, p <- tag, e, ee, ekem1, se, p
|
||||
<- p <- p
|
||||
p -> p ->
|
||||
|
||||
e1 and ekem1 are encrypted. See pattern definitions below.
|
||||
NOTE: e1 and ekem1 are different sizes (unlike X25519)
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
The e1 pattern is defined as follows, as specified in [Noise-Hybrid]_ section 4:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
|
||||
For Alice:
|
||||
(encap_key, decap_key) = PQ_KEYGEN()
|
||||
|
||||
// EncryptAndHash(encap_key)
|
||||
ciphertext = ENCRYPT(k, n, encap_key, ad)
|
||||
n++
|
||||
MixHash(ciphertext)
|
||||
|
||||
For Bob:
|
||||
|
||||
// DecryptAndHash(ciphertext)
|
||||
encap_key = DECRYPT(k, n, ciphertext, ad)
|
||||
n++
|
||||
MixHash(ciphertext)
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
The ekem1 pattern is defined as follows, as specified in [Noise-Hybrid]_ section 4:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
|
||||
For Bob:
|
||||
|
||||
(kem_ciphertext, kem_shared_key) = ENCAPS(encap_key)
|
||||
|
||||
// EncryptAndHash(kem_ciphertext)
|
||||
ciphertext = ENCRYPT(k, n, kem_ciphertext, ad)
|
||||
MixHash(ciphertext)
|
||||
|
||||
// MixKey
|
||||
MixKey(kem_shared_key)
|
||||
|
||||
|
||||
For Alice:
|
||||
|
||||
// DecryptAndHash(ciphertext)
|
||||
kem_ciphertext = DECRYPT(k, n, ciphertext, ad)
|
||||
MixHash(ciphertext)
|
||||
|
||||
// MixKey
|
||||
kem_shared_key = DECAPS(kem_ciphertext, decap_key)
|
||||
MixKey(kem_shared_key)
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
|
||||
Defined ML-KEM Operations
|
||||
-------------------------
|
||||
|
||||
We define the following functions corresponding to the cryptographic building blocks used
|
||||
as defined in [FIPS203]_.
|
||||
|
||||
(encap_key, decap_key) = PQ_KEYGEN()
|
||||
Alice creates the encapsulation and decapsulation keys
|
||||
The encapsulation key is sent in the NS message.
|
||||
encap_key and decap_key sizes vary based on ML-KEM variant.
|
||||
|
||||
(ciphertext, kem_shared_key) = ENCAPS(encap_key)
|
||||
Bob calculates the ciphertext and shared key,
|
||||
using the ciphertext received in the NS message.
|
||||
The ciphertext is sent in the NSR message.
|
||||
ciphertext size varies based on ML-KEM variant.
|
||||
The kem_shared_key is always 32 bytes.
|
||||
|
||||
kem_shared_key = DECAPS(ciphertext, decap_key)
|
||||
Alice calculates the shared key,
|
||||
using the ciphertext received in the NSR message.
|
||||
The kem_shared_key is always 32 bytes.
|
||||
|
||||
Note that both the encap_key and the ciphertext are encrypted inside ChaCha/Poly
|
||||
blocks in the Noise handshake messages 1 and 2.
|
||||
They will be decrypted as part of the handshake process.
|
||||
|
||||
The kem_shared_key is mixed into the chaining key with MixHash().
|
||||
See below for details.
|
||||
|
||||
|
||||
|
||||
Noise Handshake KDF
|
||||
---------------------
|
||||
|
||||
|
||||
Overview
|
||||
````````
|
||||
|
||||
The hybrid handshake is defined in [Noise-Hybrid]_.
|
||||
The first message, from Alice to Bob, contains e1, the encapsulation key, before the message payload.
|
||||
This is treated as an additional static key; call EncryptAndHash() on it (as Alice)
|
||||
or DecryptAndHash() (as Bob).
|
||||
Then process the message payload as usual.
|
||||
|
||||
The second message, from Bob to Alice, contains ekem1, the ciphertext, before the message payload.
|
||||
This is treated as an additional static key; call EncryptAndHash() on it (as Bob)
|
||||
or DecryptAndHash() (as Alice).
|
||||
Then, calculate the kem_shared_key and call MixKey(kem_shared_key).
|
||||
Then process the message payload as usual.
|
||||
|
||||
|
||||
|
||||
Noise identifiers
|
||||
`````````````````
|
||||
|
||||
These are the Noise initialization strings:
|
||||
|
||||
- "Noise_IKhfselg2_25519+MLKEM512_ChaChaPoly_SHA256"
|
||||
- "Noise_IKhfselg2_25519+MLKEM768_ChaChaPoly_SHA256"
|
||||
- "Noise_IKhfselg2_25519+MLKEM1024_ChaChaPoly_SHA256"
|
||||
|
||||
|
||||
|
||||
Alice KDF for NS Message
|
||||
`````````````````````````
|
||||
|
||||
After the 'es' message pattern and before the 's' message pattern, add:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='text' %}
|
||||
This is the "e1" message pattern:
|
||||
(encap_key, decap_key) = PQ_KEYGEN()
|
||||
|
||||
// EncryptAndHash(encap_key)
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, encap_key, ad)
|
||||
n++
|
||||
|
||||
// MixHash(ciphertext)
|
||||
h = SHA256(h || ciphertext)
|
||||
|
||||
|
||||
End of "e1" message pattern.
|
||||
|
||||
NOTE: For the next section (payload for XK or static key for IK),
|
||||
the keydata and chain key remain the same,
|
||||
and n now equals 1 (instead of 0 for non-hybrid).
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Bob KDF for NS Message
|
||||
`````````````````````````
|
||||
|
||||
After the 'es' message pattern and before the 's' message pattern, add:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='text' %}
|
||||
This is the "e1" message pattern:
|
||||
|
||||
// DecryptAndHash(encap_key_section)
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
n = 0
|
||||
ad = h
|
||||
encap_key = DECRYPT(k, n, encap_key_section, ad)
|
||||
n++
|
||||
|
||||
// MixHash(encap_key_section)
|
||||
h = SHA256(h || encap_key_section)
|
||||
|
||||
End of "e1" message pattern.
|
||||
|
||||
NOTE: For the next section (payload for XK or static key for IK),
|
||||
the keydata and chain key remain the same,
|
||||
and n now equals 1 (instead of 0 for non-hybrid).
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Bob KDF for NSR Message
|
||||
`````````````````````````
|
||||
|
||||
After the 'ee' message pattern and before the 'se' message pattern, add:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='text' %}
|
||||
This is the "ekem1" message pattern:
|
||||
|
||||
(kem_ciphertext, kem_shared_key) = ENCAPS(encap_key)
|
||||
|
||||
// EncryptAndHash(kem_ciphertext)
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
n = 0
|
||||
ad = h
|
||||
ciphertext = ENCRYPT(k, n, kem_ciphertext, ad)
|
||||
|
||||
// MixHash(ciphertext)
|
||||
h = SHA256(h || ciphertext)
|
||||
|
||||
// MixKey(kem_shared_key)
|
||||
keydata = HKDF(chainKey, kem_shared_key, "", 64)
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
End of "ekem1" message pattern.
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Alice KDF for NSR Message
|
||||
`````````````````````````
|
||||
|
||||
After the 'ee' message pattern and before the 'ss' message pattern, add:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='text' %}
|
||||
This is the "ekem1" message pattern:
|
||||
|
||||
// DecryptAndHash(kem_ciphertext_section)
|
||||
// AEAD parameters
|
||||
k = keydata[32:63]
|
||||
n = 0
|
||||
ad = h
|
||||
kem_ciphertext = DECRYPT(k, n, kem_ciphertext_section, ad)
|
||||
|
||||
// MixHash(kem_ciphertext_section)
|
||||
h = SHA256(h || kem_ciphertext_section)
|
||||
|
||||
// MixKey(kem_shared_key)
|
||||
kem_shared_key = DECAPS(kem_ciphertext, decap_key)
|
||||
keydata = HKDF(chainKey, kem_shared_key, "", 64)
|
||||
chainKey = keydata[0:31]
|
||||
|
||||
End of "ekem1" message pattern.
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
|
||||
KDF for split()
|
||||
```````````````
|
||||
unchanged
|
||||
|
||||
|
||||
Message Format
|
||||
--------------
|
||||
|
||||
NS Format
|
||||
`````````
|
||||
|
||||
Changes: Current ratchet contained the static key in the first ChaCha section,
|
||||
and the payload in the second section.
|
||||
With ML-KEM, there are now three sections.
|
||||
The first section contains the encrypted PQ public key.
|
||||
The second section contains the static key.
|
||||
The third section contains the payload.
|
||||
|
||||
|
||||
Encrypted format:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ +
|
||||
| New Session Ephemeral Public Key |
|
||||
+ 32 bytes +
|
||||
| Encoded with Elligator2 |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ ML-KEM encap_key +
|
||||
| ChaCha20 encrypted data |
|
||||
+ (see table below for length) +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for encap_key Section +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ X25519 Static Key +
|
||||
| ChaCha20 encrypted data |
|
||||
+ 32 bytes +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for Static Key Section +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ Payload Section +
|
||||
| ChaCha20 encrypted data |
|
||||
~ ~
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for Payload Section +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Decrypted format:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
Payload Part 1:
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ ML-KEM encap_key +
|
||||
| |
|
||||
+ (see table below for length) +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
Payload Part 2:
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ X25519 Static Key +
|
||||
| |
|
||||
+ (32 bytes) +
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
Payload Part 3:
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ Payload Section +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Sizes:
|
||||
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
Type Type Code X len NS len NS Enc len NS Dec len PQ key len pl len
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
X25519 4 32 96+pl 64+pl pl -- pl
|
||||
MLKEM512_X25519 5 32 912+pl 880+pl 800+pl 800 pl
|
||||
MLKEM768_X25519 6 32 1296+pl 1360+pl 1184+pl 1184 pl
|
||||
MLKEM1024_X25519 7 32 1680+pl 1648+pl 1568+pl 1568 pl
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
|
||||
Note that the payload must contain a DateTime block, so the minimum payload size is 7.
|
||||
The minimum NS sizes may be calculated accordingly.
|
||||
|
||||
|
||||
|
||||
NSR Format
|
||||
``````````
|
||||
|
||||
Changes: Current ratchet has an empty payload for the first ChaCha section,
|
||||
and the payload in the second section.
|
||||
With ML-KEM, there are now three sections.
|
||||
The first section contains the encrypted PQ ciphertext.
|
||||
The second section has an empty payload.
|
||||
The third section contains the payload.
|
||||
|
||||
|
||||
Encrypted format:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Session Tag 8 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ Ephemeral Public Key +
|
||||
| |
|
||||
+ 32 bytes +
|
||||
| Encoded with Elligator2 |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ +
|
||||
| ChaCha20 encrypted ML-KEM ciphertext |
|
||||
+ (see table below for length) +
|
||||
~ ~
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for ciphertext Section +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for key Section (no data) +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ Payload Section +
|
||||
| ChaCha20 encrypted data |
|
||||
~ ~
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| Poly1305 Message Authentication Code |
|
||||
+ (MAC) for Payload Section +
|
||||
| 16 bytes |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Decrypted format:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='dataspec' %}
|
||||
Payload Part 1:
|
||||
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ ML-KEM ciphertext +
|
||||
| |
|
||||
+ (see table below for length) +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
Payload Part 2:
|
||||
|
||||
empty
|
||||
|
||||
Payload Part 3:
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| |
|
||||
+ Payload Section +
|
||||
| |
|
||||
~ ~
|
||||
| |
|
||||
+ +
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
Sizes:
|
||||
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
Type Type Code Y len NSR len NSR Enc len NSR Dec len PQ CT len opt len
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
X25519 4 32 72+pl 32+pl pl -- pl
|
||||
MLKEM512_X25519 5 32 856+pl 816+pl 768+pl 768 pl
|
||||
MLKEM768_X25519 6 32 1176+pl 1136+pl 1088+pl 1088 pl
|
||||
MLKEM1024_X25519 7 32 1656+pl 1616+pl 1568+pl 1568 pl
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
|
||||
Note that while NSR will normally have a nonzero payload,
|
||||
the ratchet specification [ECIES]_ does not require it, so the minimum payload size is 0.
|
||||
The minimum NSR sizes may be caculated accordingly.
|
||||
|
||||
|
||||
|
||||
Overhead Analysis
|
||||
=================
|
||||
|
||||
Key Exchange
|
||||
-------------
|
||||
|
||||
Size increase (bytes):
|
||||
|
||||
================ ============== =============
|
||||
Type Pubkey (NS) Cipertext (NSR)
|
||||
================ ============== =============
|
||||
MLKEM512_X25519 +816 +784
|
||||
MLKEM768_X25519 +1200 +1104
|
||||
MLKEM1024_X25519 +1584 +1584
|
||||
================ ============== =============
|
||||
|
||||
Speed:
|
||||
|
||||
Speeds as reported by [CLOUDFLARE]_:
|
||||
|
||||
================ ==============
|
||||
Type Relative speed
|
||||
================ ==============
|
||||
X25519 DH/keygen baseline
|
||||
MLKEM512 2.25x faster
|
||||
MLKEM768 1.5x faster
|
||||
MLKEM1024 1x (same)
|
||||
XK 4x DH (keygen + 3 DH)
|
||||
MLKEM512_X25519 4x DH + 2x PQ (keygen + enc/dec) = 4.9x DH = 22% slower
|
||||
MLKEM768_X25519 4x DH + 2x PQ (keygen + enc/dec) = 5.3x DH = 32% slower
|
||||
MLKEM1024_X25519 4x DH + 2x PQ (keygen + enc/dec) = 6x DH = 50% slower
|
||||
================ ==============
|
||||
|
||||
|
||||
Security Analysis
|
||||
=================
|
||||
|
||||
NIST security categories are summarized in [NIST-PQ-END]_ slide 10.
|
||||
Preliminary criteria:
|
||||
Our minimum NIST security category should be 2 for hybrid protocols
|
||||
and 3 for PQ-only.
|
||||
|
||||
======== ======
|
||||
Category As Secure As
|
||||
======== ======
|
||||
1 AES128
|
||||
2 SHA256
|
||||
3 AES192
|
||||
4 SHA384
|
||||
5 AES256
|
||||
======== ======
|
||||
|
||||
|
||||
Handshakes
|
||||
----------
|
||||
These are all hybrid protocols.
|
||||
Probably need to prefer MLKEM768; MLKEM512 is not secure enough.
|
||||
|
||||
NIST security categories [FIPS203]_ :
|
||||
|
||||
========= ========
|
||||
Algorithm Security Category
|
||||
========= ========
|
||||
MLKEM512 1
|
||||
MLKEM768 3
|
||||
MLKEM1024 5
|
||||
========= ========
|
||||
|
||||
|
||||
Type Preferences
|
||||
=================
|
||||
|
||||
|
||||
The recommended type for initial support, based on security category and key length, is:
|
||||
|
||||
MLKEM768_X25519 (type 6)
|
||||
|
||||
|
||||
|
||||
Implementation Notes
|
||||
=====================
|
||||
|
||||
Library Support
|
||||
---------------
|
||||
|
||||
Bouncycastle, BoringSSL, and WolfSSL libraries support MLKEM now.
|
||||
OpenSSL support is be in their 3.5 release April 8, 2025 [OPENSSL]_.
|
||||
|
||||
|
||||
Shared Tunnels
|
||||
--------------
|
||||
|
||||
Auto-classify/detect of multiple protocols on the same tunnels should be possible based
|
||||
on a length check of message 1 (New Session Message).
|
||||
Using MLKEM512_X25519 as an example, message 1 length is 816 bytes larger
|
||||
than current ratchet protocol, and the minimum message 1 size (with only a DateTime payload included)
|
||||
is 919 bytes. Most message 1 sizes with current ratchet have a payload less than
|
||||
816 bytes, so they can be classified as non-hybrid ratchet.
|
||||
Large messages are probably POSTs which are rare.
|
||||
|
||||
So the recommended strategy is:
|
||||
|
||||
- If message 1 is less than 919 bytes, it's the current ratchet protocol.
|
||||
- If message 1 is greater than or equal to 919 bytes, it's probably MLKEM512_X25519.
|
||||
Try MLKEM512_X25519 first, and if it fails, try the current ratchet protocol.
|
||||
|
||||
This should allow us to efficiently support standard ratchet and hybrid ratchet
|
||||
on the same destination, just as we previously supported ElGamal and ratchet
|
||||
on the same destination. Therefore, we can migrate to the MLKEM hybrid protocol
|
||||
much more quickly than if we could not support dual-protocols for the same destination,
|
||||
because we can add MLKEM support to existing destinations.
|
||||
|
||||
The required supported combinations are:
|
||||
|
||||
- X25519 + MLKEM512
|
||||
- X25519 + MLKEM768
|
||||
- X25519 + MLKEM1024
|
||||
|
||||
The following combinations may be complex, and are NOT required to be supported,
|
||||
but may be, implementation-dependent:
|
||||
|
||||
- More than one MLKEM
|
||||
- ElG + one or more MLKEM
|
||||
- X25519 + one or more MLKEM
|
||||
- ElG + X25519 + one or more MLKEM
|
||||
|
||||
It is not required to support multiple MLKEM algorithms
|
||||
(for example, MLKEM512_X25519 and MLKEM_768_X25519)
|
||||
on the same destination. Pick just one.
|
||||
Implementation-dependent.
|
||||
|
||||
It is not required to support three algorithms (for example X25519, MLKEM512_X25519, and MLKEM769_X25519)
|
||||
on the same destination. The classification and retry strategy may be too complex.
|
||||
The configuration and configuration UI may be too complex.
|
||||
Implementation-dependent.
|
||||
|
||||
It is not required to support ElGamal and hybrid algorithms on the same destination.
|
||||
ElGamal is obsolete, and ElGamal + hybrid only (no X25519) doesn't make much sense.
|
||||
Also, ElGamal and Hybrid New Session Messages are both large, so
|
||||
classification strategies would often have to try both decryptions,
|
||||
which would be inefficient.
|
||||
Implementation-dependent.
|
||||
|
||||
Clients may use the same or different X25519 static keys for the X25519
|
||||
and the hybrid protocols on the same tunnels, implementation-dependent.
|
||||
|
||||
|
||||
Forward Secrecy
|
||||
---------------
|
||||
The ECIES specification allows Garlic Messages in the New Session Message payload,
|
||||
which allows for 0-RTT delivery of the initial streaming packet,
|
||||
usually a HTTP GET, together with the client's leaseset.
|
||||
However, the New Session Message payload does not have forward secrecy.
|
||||
As this proposal is emphasizing enhanced forward secrecy for ratchet,
|
||||
implementations may or should defer inclusion of the streaming payload,
|
||||
or the full streaming message, until the first Existing Session Message.
|
||||
This would be at the expense of 0-RTT delivery.
|
||||
Strategies may also depend on traffic type or tunnel type,
|
||||
or on GET vs. POST, for example.
|
||||
Implementation-dependent.
|
||||
|
||||
|
||||
New Session Size
|
||||
----------------
|
||||
MLKEM will dramatically increase
|
||||
the size of the New Session Message, as described above.
|
||||
This may significantly decrease the reliability of New Session Message
|
||||
delivery through tunnels, where they must be fragmented into
|
||||
multiple 1024 byte tunnel messages. Delivery success is
|
||||
proportional to the exponential number of fragments.
|
||||
Implementations may use various strategies to limit the size of the message,
|
||||
at the expense of 0-RTT delivery.
|
||||
Implementation-dependent.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [CLOUDFLARE]
|
||||
https://blog.cloudflare.com/pq-2024/
|
||||
|
||||
.. [COMMON]
|
||||
{{ spec_url('common-structures') }}
|
||||
|
||||
.. [ECIES]
|
||||
{{ spec_url('ecies') }}
|
||||
|
||||
.. [FORUM]
|
||||
http://zzz.i2p/topics/3294
|
||||
|
||||
.. [FIPS202]
|
||||
https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
|
||||
|
||||
.. [FIPS203]
|
||||
https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf
|
||||
|
||||
.. [NIST-PQ-END]
|
||||
https://www.nccoe.nist.gov/sites/default/files/2023-08/pqc-light-at-the-end-of-the-tunnel-presentation.pdf
|
||||
|
||||
.. [NIST-VECTORS]
|
||||
https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values
|
||||
|
||||
.. [Noise]
|
||||
https://noiseprotocol.org/noise.html
|
||||
|
||||
.. [Noise-Hybrid]
|
||||
https://github.com/noiseprotocol/noise_hfs_spec/blob/master/output/noise_hfs.pdf
|
||||
|
||||
.. [OPENSSL]
|
||||
https://openssl-library.org/post/2025-02-04-release-announcement-3.5/
|
||||
|
||||
.. [PQ-WIREGUARD]
|
||||
https://eprint.iacr.org/2020/379.pdf
|
||||
|
||||
.. [Prop169]
|
||||
{{ proposal_url('169') }}
|
@@ -3,8 +3,8 @@ ECIES-X25519-AEAD-Ratchet
|
||||
=========================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-04
|
||||
:accuratefor: 0.9.66
|
||||
:lastupdated: 2025-06
|
||||
:accuratefor: 0.9.67
|
||||
|
||||
.. contents::
|
||||
|
||||
@@ -22,6 +22,7 @@ The following features are not implemented as of 0.9.66:
|
||||
- Zero static key
|
||||
- Multicast
|
||||
|
||||
For the MLKEM PQ Hybrid version of this protocol, see [ECIES-HYBRID]_.
|
||||
|
||||
|
||||
Overview
|
||||
@@ -182,6 +183,44 @@ Bound sessions are similar to the Noise IK pattern.
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Security Properties
|
||||
```````````````````
|
||||
|
||||
Using Noise terminology, the establishment and data sequence is as follows:
|
||||
(Payload Security Properties from [Noise]_ )
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight lang='text' %}
|
||||
IK(s, rs): Authentication Confidentiality
|
||||
<- s
|
||||
...
|
||||
-> e, es, s, ss 1 2
|
||||
<- e, ee, se 2 4
|
||||
-> 2 5
|
||||
<- 2 5
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
Differences From XK
|
||||
```````````````````
|
||||
IK handshakes have several differences from XK handshakes used
|
||||
in [NTCP2]_ and [SSU2]_.
|
||||
|
||||
- Four total DH operations compared to three for XK
|
||||
- Sender authentication in first message: The payload is authenticated
|
||||
as belonging to the owner of the sender's public key, although
|
||||
the key could have been compromised (Authentication 1)
|
||||
XK requires another round trip before Alice is authenticated.
|
||||
- Full forward secrecy (Confidentiality 5) after the second message.
|
||||
Bob may send a payload immediately after the second message with
|
||||
full forward secrecy.
|
||||
XK requires another round trip for full forward secrecy.
|
||||
|
||||
In summary, IK allows 1-RTT delivery of the response payload from Bob to Alice
|
||||
with full forward secrecy, however the request payload is not forward-secret.
|
||||
|
||||
|
||||
Sessions
|
||||
--------
|
||||
|
||||
@@ -3018,7 +3057,7 @@ If the timer does fire, send an empty payload with the NSR or ES.
|
||||
|
||||
|
||||
|
||||
Protocol-layer Responses
|
||||
Ratchet-layer Responses
|
||||
````````````````````````
|
||||
|
||||
Initial implementations rely on bidirectional traffic at the higher layers.
|
||||
@@ -3031,7 +3070,7 @@ such that there is no higher-layer traffic to generate a timely response.
|
||||
Receipt of NS and NSR messages require a response;
|
||||
receipt of ACK Request and Next Key blocks also require a response.
|
||||
|
||||
A sophisticated implementation may start a timer when one of these
|
||||
Implementations should start a timer when one of these
|
||||
messages is received which requires a response,
|
||||
and generate an "empty" (no Garlic Clove block) response
|
||||
at the ECIES layer
|
||||
@@ -3042,6 +3081,51 @@ responses to NS and NSR messages, to shift the traffic to
|
||||
the efficient ES messages as soon as possible.
|
||||
|
||||
|
||||
NS Binding For NSR
|
||||
``````````````````
|
||||
|
||||
At the ratchet layer, as Bob, Alice is only known by static key.
|
||||
The NS message is authenticated ([Noise]_ IK sender authentication 1).
|
||||
However, this is not sufficient for the ratchet layer to be able to send anything
|
||||
to Alice, as network routing requires a full Destination.
|
||||
|
||||
Before the NSR may be sent, Alice's full Destination must be discovered either
|
||||
by the ratchet layer or a higher-layer repliable protocol,
|
||||
either repliable [Datagrams]_ or [Streaming]_.
|
||||
After finding the Leaseset for that Destination, that Leaseset
|
||||
will contain the same static key as contained in the NS.
|
||||
|
||||
Typically, the higher layer will respond, forcing a network database
|
||||
lookup of Alice's Leaseset by Alice's Destination Hash.
|
||||
That Leaseset will almost always be found locally, because the
|
||||
NS contained a Garlic Clove block, containing a Database Store message,
|
||||
containing Alice's Leaseset.
|
||||
|
||||
For Bob to be prepared to send a ratchet-layer NSR, and to bind
|
||||
the pending session to Alice's Destination, Bob should
|
||||
"capture" the Destination while processing the NS payload.
|
||||
If a Database Store message is found containing a Leaseset
|
||||
with a key matching the static key in the NS,
|
||||
the pending session is now bound to that Destination,
|
||||
and Bob knows where to send any NSR if the response timer expires.
|
||||
This is the recommended implementation.
|
||||
|
||||
An alternative design is to maintain a cache or database
|
||||
where the static key is mapped to a Destination.
|
||||
The security and practicality of this approach
|
||||
is a topic for further study.
|
||||
|
||||
Neither this specification nor others strictly require that
|
||||
every NS contains Alice's Leaseset.
|
||||
However, in practice, it should.
|
||||
The recommended ES tagset sender timeout (8 minutes)
|
||||
is shorter than the maximum Leaseset timeout (10 minutes),
|
||||
so there could be a small window where the previous session
|
||||
has expired, Alice thinks that Bob
|
||||
still has her valid Leaseset, and does not send a new Leaseset
|
||||
with the new NS. This is a topic for further study.
|
||||
|
||||
|
||||
Multiple NS Messages
|
||||
````````````````````
|
||||
|
||||
@@ -3168,6 +3252,12 @@ References
|
||||
.. [CRYPTO-ELG]
|
||||
{{ site_url('docs/how/cryptography', True) }}#elgamal
|
||||
|
||||
.. [ECIES-HYBRID]
|
||||
{{ spec_url('ecies-hybrid') }}
|
||||
|
||||
.. [Datagrams]
|
||||
{{ spec_url('datagrams') }}
|
||||
|
||||
.. [Elligator2]
|
||||
https://elligator.cr.yp.to/elligator-20130828.pdf
|
||||
https://www.imperialviolet.org/2013/12/25/elligator.html
|
||||
@@ -3239,6 +3329,12 @@ References
|
||||
.. [SSU]
|
||||
{{ site_url('docs/transport/ssu', True) }}
|
||||
|
||||
.. [SSU2]
|
||||
{{ spec_url('ssu2') }}
|
||||
|
||||
.. [Streaming]
|
||||
{{ spec_url('streaming') }}
|
||||
|
||||
.. [STS]
|
||||
Diffie, W.; van Oorschot P. C.; Wiener M. J., Authentication and
|
||||
Authenticated Key Exchanges
|
||||
|
@@ -3,8 +3,8 @@ Encrypted LeaseSet Specification
|
||||
================================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: June 2019
|
||||
:accuratefor: 0.9.41
|
||||
:lastupdated: 2025-05
|
||||
:accuratefor: 0.9.66
|
||||
|
||||
.. contents::
|
||||
|
||||
|
@@ -3,8 +3,8 @@ Access Filter Format Specification
|
||||
==================================
|
||||
.. meta::
|
||||
:category: Formats
|
||||
:lastupdated: April 2019
|
||||
:accuratefor: 0.9.40
|
||||
:lastupdated: 2025-05
|
||||
:accuratefor: 0.9.66
|
||||
|
||||
.. contents::
|
||||
|
||||
|
@@ -3,8 +3,8 @@ GeoIP File Specification
|
||||
========================
|
||||
.. meta::
|
||||
:category: Formats
|
||||
:lastupdated: December 2013
|
||||
:accuratefor: 0.9.9
|
||||
:lastupdated: 2025-05
|
||||
:accuratefor: 0.9.66
|
||||
|
||||
.. contents::
|
||||
|
||||
@@ -12,6 +12,12 @@ GeoIP File Specification
|
||||
Overview
|
||||
========
|
||||
|
||||
NOTE: OBSOLETE - We now support three formats, in order of preference:
|
||||
|
||||
- Maxmind geoip2 (GeoLite2-Country.mmdb) bundled with all installs except Debian packages and Android
|
||||
- Maxmind geoip1 (GeoIP.dat) in the Debian geoip-database package
|
||||
- The IPv4 Tor format (geoip.txt) and the custom IPv6 format (geoipv6.dat.gz) documented below, still supported but unused.
|
||||
|
||||
This page specifies the format of the various GeoIP files,
|
||||
used by the router to look up a country for an IP.
|
||||
|
||||
|
@@ -3,8 +3,8 @@ I2CP Specification
|
||||
==================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-04
|
||||
:accuratefor: 0.9.66
|
||||
:lastupdated: 2025-07
|
||||
:accuratefor: 0.9.67
|
||||
|
||||
.. contents::
|
||||
|
||||
@@ -237,10 +237,14 @@ below.
|
||||
============== ======================
|
||||
Version Required I2CP Features
|
||||
============== ======================
|
||||
0.9.67 PQ Hybrid ML-KEM (enc types 5-7) supported in LS
|
||||
|
||||
0.9.66 Host lookup/reply extensions (see proposal 167)
|
||||
|
||||
0.9.62 MessageStatus message Loopback error code
|
||||
|
||||
0.9.46 X25519 (enc type 4) supported in LS
|
||||
|
||||
0.9.43 BlindingInfo message supported
|
||||
|
||||
Additional HostReply message failure codes
|
||||
@@ -781,7 +785,9 @@ Description
|
||||
```````````
|
||||
This message is sent from a client to destroy a session.
|
||||
|
||||
Sent from Client to Router. The router responds with a SessionStatusMessage_.
|
||||
Sent from Client to Router. The router should respond with a SessionStatusMessage_ (Destroyed).
|
||||
However, see important notes below.
|
||||
|
||||
|
||||
Contents
|
||||
````````
|
||||
@@ -791,6 +797,26 @@ Notes
|
||||
`````
|
||||
The router at this point should release all resources related to the session.
|
||||
|
||||
Through API 0.9.66,
|
||||
the Java I2P router and client libraries deviate substantially from this specification.
|
||||
The router never sends a SessionStatus(Destroyed) response.
|
||||
If no sessions are left, it sends a DisconnectMessage_.
|
||||
If there are subsessions or the primary session is remaining, it does not reply.
|
||||
|
||||
The Java client library responds to a SessionStatus message by destroying
|
||||
all sessions and reconnecting.
|
||||
|
||||
Destroying individual subsessions on a connection with multiple sessions
|
||||
may not be fully tested or working on various router and client implementations.
|
||||
Use caution.
|
||||
|
||||
Implementations should treat a destroy for a primary session as a destroy
|
||||
for all subsessions, but allow a destroy for a single subsession
|
||||
and keep the connection open, but Java I2P does not do that now.
|
||||
If Java I2P behavior is changed in subsequent releases, it will be documented here.
|
||||
|
||||
|
||||
|
||||
.. _msg-Disconnect:
|
||||
|
||||
DisconnectMessage
|
||||
@@ -799,7 +825,8 @@ DisconnectMessage
|
||||
Description
|
||||
```````````
|
||||
Tell the other party that there are problems and the current connection is about to
|
||||
be destroyed. This does not necessarily end a session.
|
||||
be destroyed. This ends all sessions on that connection.
|
||||
The socket will be closed shortly.
|
||||
Sent either from router to client or from client to router.
|
||||
|
||||
Contents
|
||||
@@ -808,8 +835,8 @@ Contents
|
||||
|
||||
Notes
|
||||
`````
|
||||
Only implemented in the router-to-client direction. Disconnecting probably
|
||||
does end a session, in practice.
|
||||
Only implemented in the router-to-client direction, at least in Java I2P.
|
||||
|
||||
|
||||
.. _msg-GetBandwidthLimits:
|
||||
|
||||
|
@@ -3,7 +3,7 @@ I2NP Specification
|
||||
==================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-04
|
||||
:lastupdated: 2025-08
|
||||
:accuratefor: 0.9.66
|
||||
|
||||
.. contents::
|
||||
@@ -927,8 +927,9 @@ Contents
|
||||
`LeaseSet2`, `MetaLeaseSet`, or `EncryptedLeaseSet`.
|
||||
10 => RI lookup, return `RouterInfo` or
|
||||
`DatabaseSearchReplyMessage`
|
||||
11 => exploration lookup, return `DatabaseSearchReplyMessage`
|
||||
containing non-floodfill routers only (replaces an
|
||||
11 => exploration lookup, return `RouterInfo` or
|
||||
`DatabaseSearchReplyMessage` containing
|
||||
non-floodfill routers only (replaces an
|
||||
excludedPeer of all zeroes)
|
||||
bit 4: ECIESFlag
|
||||
before release 0.9.46 ignored
|
||||
|
@@ -3,8 +3,8 @@ NTCP 2
|
||||
======
|
||||
.. meta::
|
||||
:category: Transports
|
||||
:lastupdated: 2024-01
|
||||
:accuratefor: 0.9.61
|
||||
:lastupdated: 2025-05
|
||||
:accuratefor: 0.9.66
|
||||
|
||||
.. contents::
|
||||
|
||||
@@ -110,7 +110,7 @@ Alice Bob
|
||||
{% endhighlight %}
|
||||
|
||||
Using Noise terminology, the establishment and data sequence is as follows:
|
||||
(Payload Security Properties)
|
||||
(Payload Security Properties from [Noise]_ )
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@@ -368,7 +368,7 @@ Noise content: Alice's ephemeral key X
|
||||
Noise payload: 16 byte option block
|
||||
Non-noise payload: Random padding
|
||||
|
||||
(Payload Security Properties)
|
||||
(Payload Security Properties from [Noise]_ )
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@@ -574,6 +574,10 @@ Notes
|
||||
set a random timeout (range TBD) and then read a random number of bytes (range TBD),
|
||||
before closing the socket.
|
||||
|
||||
- Bob may do a fast MSB check for a valid key (X[31] & 0x80 == 0) before
|
||||
attempting decryption. If the high bit is set, implement probing resistance
|
||||
as for AEAD failures.
|
||||
|
||||
- DoS Mitigation: DH is a relatively expensive operation. As with the previous NTCP protocol,
|
||||
routers should take all necessary measures to prevent CPU or connection exhaustion.
|
||||
Place limits on maximum active connections and maximum connection setups in progress.
|
||||
@@ -703,7 +707,7 @@ Noise content: Bob's ephemeral key Y
|
||||
Noise payload: 16 byte option block
|
||||
Non-noise payload: Random padding
|
||||
|
||||
(Payload Security Properties)
|
||||
(Payload Security Properties from [Noise]_ )
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@@ -992,7 +996,7 @@ Noise content: Alice's static key
|
||||
Noise payload: Alice's RouterInfo and random padding
|
||||
Non-noise payload: none
|
||||
|
||||
(Payload Security Properties)
|
||||
(Payload Security Properties from [Noise]_ )
|
||||
|
||||
|
||||
.. raw:: html
|
||||
@@ -1267,7 +1271,7 @@ Types include date/time, I2NP message, options, termination, and padding.
|
||||
Note: Bob may, but is not required, to send his RouterInfo to Alice as
|
||||
his first message to Alice in the data phase.
|
||||
|
||||
(Payload Security Properties)
|
||||
(Payload Security Properties from [Noise]_ )
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
@@ -5,13 +5,23 @@ UDP Trackers
|
||||
:author: zzz
|
||||
:created: 2022-01-03
|
||||
:thread: http://zzz.i2p/topics/1634
|
||||
:lastupdated: 2025-04-23
|
||||
:status: Open
|
||||
:target: 0.9.68
|
||||
:lastupdated: 2025-06-25
|
||||
:status: Closed
|
||||
:target: 0.9.67
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
Status
|
||||
======
|
||||
|
||||
Approved at review 2025-06-24.
|
||||
Specification is at [UDP]_.
|
||||
Implementated in zzzot 0.20.0-beta2.
|
||||
Implementated in i2psnark as of API 0.9.67.
|
||||
Check documentation of other implementations for status.
|
||||
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
@@ -76,10 +86,12 @@ overhead where possible before PQ crypto is adopted in I2P.
|
||||
Design
|
||||
============
|
||||
|
||||
This proposal uses both repliable datagram2 and raw datagrams,
|
||||
This proposal uses repliable datagram2, repliable datagram3, and raw datagrams,
|
||||
as defined in [DATAGRAMS]_.
|
||||
Datagram2 is a new variant of repliable datagrams,
|
||||
defined in Proposal 163 [Prop163]_, that adds replay resistance.
|
||||
Datagram2 and Datagram3 are new variants of repliable datagrams,
|
||||
defined in Proposal 163 [Prop163]_.
|
||||
Datagram2 adds replay resistance and offline signature support.
|
||||
Datagram3 is smaller than the old datagram format, but without authentication.
|
||||
|
||||
|
||||
BEP 15
|
||||
@@ -113,9 +125,9 @@ for efficiency, and for security reasons discussed below:
|
||||
Client Tracker
|
||||
Connect Req. -------------> (Repliable Datagram2)
|
||||
<-------------- Connect Resp. (Raw)
|
||||
Announce Req. -------------> (Raw)
|
||||
Announce Req. -------------> (Repliable Datagram3)
|
||||
<-------------- Announce Resp. (Raw)
|
||||
Announce Req. -------------> (Raw)
|
||||
Announce Req. -------------> (Repliable Datagram3)
|
||||
<-------------- Announce Resp. (Raw)
|
||||
...
|
||||
{% endhighlight %}
|
||||
@@ -124,17 +136,40 @@ This potentially provides a large bandwidth savings over
|
||||
streaming (TCP) announces.
|
||||
While the Datagram2 is about the same size as a streaming SYN,
|
||||
the raw response is much smaller than the streaming SYN ACK.
|
||||
All subsequent requests/responses are raw.
|
||||
Subsequent requests use Datagram3, and the subsequent responses are raw.
|
||||
|
||||
The announce requests are Datagram3 so that the tracker need not
|
||||
maintain a large mapping table of connection IDs to announce destination or hash.
|
||||
Instead, the tracker may generate connection IDs cryptographically
|
||||
from the sender hash, the current timestamp (based on some interval),
|
||||
and a secret value.
|
||||
When an announce request is received, the tracker validates the
|
||||
connection ID, and then uses the
|
||||
Datagram3 sender hash as the send target.
|
||||
|
||||
|
||||
Tracker/Client support
|
||||
----------------------
|
||||
|
||||
Non-Java Tracker/Client support
|
||||
-------------------------------
|
||||
|
||||
For an integrated application (router and client in one process, for example i2psnark and the ZzzOT Java plugin),
|
||||
For an integrated application (router and client in one process, for example i2psnark, and the ZzzOT Java plugin),
|
||||
or for an I2CP-based application (for example BiglyBT),
|
||||
it should be straightforward to implement and route the streaming and datagram traffic separately.
|
||||
ZzzOT and i2psnark are expected to be the first tracker and client to implement this proposal.
|
||||
|
||||
Non-integrated trackers and clients are discussed below.
|
||||
|
||||
|
||||
Trackers
|
||||
````````
|
||||
|
||||
There are four known I2P tracker implementations:
|
||||
|
||||
- zzzot, an integrated Java router plugin, running at opentracker.dg2.i2p and several others
|
||||
- tracker2.postman.i2p, running presumably behind a Java router and HTTP Server tunnel
|
||||
- The old C opentracker, ported by zzz, with UDP support commented out
|
||||
- The new C opentracker, ported by r4sas, running at opentracker.r4sas.i2p and possibly others,
|
||||
running presumably behind a i2pd router and HTTP Server tunnel
|
||||
|
||||
For an external tracker application that currently uses an HTTP server tunnel to receive
|
||||
announce requests, the implementation could be quite difficult.
|
||||
A specialized tunnel could be developed to translate datagrams to local HTTP requests/responses.
|
||||
@@ -143,10 +178,14 @@ that would forward the datagrams to the external process.
|
||||
These design decisions will depend heavily on the specific router and tracker implementations,
|
||||
and are outside the scope of this proposal.
|
||||
|
||||
|
||||
Clients
|
||||
```````
|
||||
External SAM-based torrent clients such as qbittorrent and other libtorrent-based clients
|
||||
would require SAM v3.3 [SAMv3]_ which is not supported by i2pd.
|
||||
This is also required for DHT support, and is complex enough that no known
|
||||
SAM torrent client has implemented it.
|
||||
No SAM-based implementations of this proposal are expected soon.
|
||||
|
||||
|
||||
Connection Lifetime
|
||||
@@ -205,8 +244,10 @@ Specification
|
||||
Protocols and Ports
|
||||
-------------------
|
||||
|
||||
Repliable Datagram2 uses I2CP protocol 19; raw datagrams use I2CP protocol 18.
|
||||
Requests may be Datagram2 or raw. Responses are always raw.
|
||||
Repliable Datagram2 uses I2CP protocol 19;
|
||||
repliable Datagram3 uses I2CP protocol 20;
|
||||
raw datagrams use I2CP protocol 18.
|
||||
Requests may be Datagram2 or Datagram3. Responses are always raw.
|
||||
The older repliable datagram ("Datagram1") format using I2CP protocol 17
|
||||
must NOT be used for requests or replies; these must be dropped if received
|
||||
on the request/reply ports. Note that Datagram1 protocol 17
|
||||
@@ -294,7 +335,7 @@ Announce Request
|
||||
````````````````
|
||||
|
||||
Client to tracker.
|
||||
98 bytes minimum. Must be raw. Same as in [BEP15]_ except as noted below.
|
||||
98 bytes minimum. Must be repliable Datagram3. Same as in [BEP15]_ except as noted below.
|
||||
|
||||
The connection_id is as received in the connect response.
|
||||
|
||||
@@ -386,7 +427,8 @@ Scrape
|
||||
Scrape request/response from [BEP15]_ is not required by this proposal,
|
||||
but may be implemented if desired, no changes required.
|
||||
The client must acquire a connection ID first.
|
||||
The scrape request and response are always raw.
|
||||
The scrape request is always repliable Datagram3.
|
||||
The scrape response is always raw.
|
||||
|
||||
|
||||
|
||||
@@ -432,6 +474,10 @@ after an all-zeros 32-byte hash.
|
||||
Implementation guidelines
|
||||
==========================
|
||||
|
||||
See the design section above for a discussion of the challenges for
|
||||
non-integrated, non-I2CP clients and trackers.
|
||||
|
||||
|
||||
Clients
|
||||
--------
|
||||
|
||||
@@ -462,8 +508,24 @@ Trackers
|
||||
|
||||
Trackers with existing BEP 15 support should require only small modifications.
|
||||
This proposal differs from the 2014 proposal, in that the tracker
|
||||
must support reception of repliable datagram2 and raw datagrams on the same port.
|
||||
must support reception of repliable datagram2 and datagram3 on the same port.
|
||||
|
||||
To minimize tracker resource requirements,
|
||||
this protocol is designed to eliminate any requirement that the tracker
|
||||
store mappings of client hashes to connection IDs for later validation.
|
||||
This is possible because the announce request packet is a repliable
|
||||
Datagram3 packet, so it contains the sender's hash.
|
||||
|
||||
A recommended implementation is:
|
||||
|
||||
- Define the current epoch as the current time with a resolution of the connection lifetime,
|
||||
``epoch = now / lifetime``.
|
||||
- Define a cryptographic hash function ``H(secret, clienthash, epoch)`` which generates
|
||||
an 8 byte output.
|
||||
- Generate the random constant secret used for all connections.
|
||||
- For connect responses, generate ``connection_id = H(secret, clienthash, epoch)``
|
||||
- For announce requests, validate the received connection ID in the current epoch by verifying
|
||||
``connection_id == H(secret, clienthash, epoch) || connection_id == H(secret, clienthash, epoch - 1)``
|
||||
|
||||
|
||||
Migration
|
||||
@@ -471,7 +533,7 @@ Migration
|
||||
|
||||
Existing clients do not support UDP announce URLs and ignore them.
|
||||
|
||||
Existing trackers do not support reception of repliable datagram2 or raw datagrams, they will be dropped.
|
||||
Existing trackers do not support reception of repliable or raw datagrams, they will be dropped.
|
||||
|
||||
This proposal is completely optional. Neither clients nor trackers are required to implement it at any time.
|
||||
|
||||
@@ -511,3 +573,6 @@ References
|
||||
|
||||
.. [SPEC]
|
||||
{{ site_url('docs/applications/bittorrent', True) }}
|
||||
|
||||
.. [UDP]
|
||||
{{ spec_url('udp-announces') }}
|
||||
|
@@ -7,7 +7,7 @@ Datagram2 Protocol
|
||||
:thread: http://zzz.i2p/topics/3540
|
||||
:lastupdated: 2025-04-16
|
||||
:status: Closed
|
||||
:target: 0.9.67
|
||||
:target: 0.9.66
|
||||
|
||||
.. contents::
|
||||
|
||||
@@ -17,8 +17,7 @@ Status
|
||||
|
||||
Approved at review 2025-04-15.
|
||||
Changes incorporated into specs.
|
||||
Not yet supported in any known implenentations.
|
||||
Target implementation for Java I2P is API 0.9.67.
|
||||
Implementated in Java I2P as of API 0.9.66.
|
||||
Check implementation documentation for status.
|
||||
|
||||
|
||||
|
@@ -5,7 +5,7 @@ Post-Quantum Crypto Protocols
|
||||
:author: zzz, orignal, drzed, eyedeekay
|
||||
:created: 2025-01-21
|
||||
:thread: http://zzz.i2p/topics/3294
|
||||
:lastupdated: 2025-04-23
|
||||
:lastupdated: 2025-06-12
|
||||
:status: Open
|
||||
:target: 0.9.80
|
||||
|
||||
@@ -83,14 +83,10 @@ See the Priorities and Rollout section below for details.
|
||||
================================== ======
|
||||
Protocol / Feature Status
|
||||
================================== ======
|
||||
Hybrid EncTypes 5-7 Preliminary, final hash choices pending
|
||||
Hybrid Dests, Ratchet Tested on live net, no net upgrade required
|
||||
Select preferred combo Probably 6,4
|
||||
Combo Hybrid/X25519 Dests, Ratchet
|
||||
Combo Hybrid/X25519 NTCP2
|
||||
Combo Hybrid/X25519 SSU2
|
||||
Hybrid Routers, Dests, Ratchet
|
||||
MLDSA SigTypes 12-14 Probably final
|
||||
Hybrid MLKEM Ratchet and LS Approved 2026-06; beta target 2025-08; release target 2025-11
|
||||
Hybrid MLKEM NTCP2 Some details to be finalized
|
||||
Hybrid MLKEM SSU2 Some details to be finalized
|
||||
MLDSA SigTypes 12-14 Proposal is stable but may not be finalized until 2026
|
||||
MLDSA Dests Tested on live net, requires net upgrade for floodfill support
|
||||
Hybrid SigTypes 15-17 Preliminary
|
||||
Hybrid Dests
|
||||
@@ -124,9 +120,6 @@ NetDB N no no
|
||||
|
||||
PQ KEM provides ephemeral keys only, and does not directly support
|
||||
static-key handshakes such as Noise XK and IK.
|
||||
While there is some recent research [PQ-WIREGUARD]_ on adapting Wireguard (IK)
|
||||
for pure PQ crypto, there are several open questions, and
|
||||
this approach is unproven.
|
||||
|
||||
Noise N does not use a two-way key exchange and so it is not suitable
|
||||
for hybrid encryption.
|
||||
@@ -246,7 +239,7 @@ New Crypto Required
|
||||
Test vectors for SHA3-256, SHAKE128, and SHAKE256 are at [NIST-VECTORS]_.
|
||||
|
||||
Note that the Java bouncycastle library supports all the above.
|
||||
C++ library support will be in OpenSSL 3.5 [OPENSSL]_.
|
||||
C++ library support is in OpenSSL 3.5 [OPENSSL]_.
|
||||
|
||||
|
||||
Alternatives
|
||||
@@ -257,6 +250,33 @@ We will not support the upcoming FIPS206 (Falcon), it is not yet standardized.
|
||||
We will not support NTRU or other PQ candidates that were not standardized by NIST.
|
||||
|
||||
|
||||
Rosenpass
|
||||
`````````
|
||||
|
||||
There is some research [PQ-WIREGUARD]_ on adapting Wireguard (IK)
|
||||
for pure PQ crypto, but there are several open questions in that paper.
|
||||
Later, this approach was implemented as Rosenpass [Rosenpass]_ [Rosenpass-Whitepaper]_
|
||||
for PQ Wireguard.
|
||||
|
||||
Rosenpass uses a Noise KK-like handshake with preshared Classic McEliece 460896 static keys
|
||||
(500 KB each) and Kyber-512 (essentially MLKEM-512) ephemeral keys.
|
||||
As the Classic McEliece ciphertexts are only 188 bytes, and the Kyber-512
|
||||
public keys and ciphertexts are reasonable, both handshake messages fit in a standard UDP MTU.
|
||||
The output shared key (osk) from the PQ KK handshake is used as the input preshared key (psk)
|
||||
for the standard Wireguard IK handshake.
|
||||
So there are two complete handshakes in total, one pure PQ and one pure X25519.
|
||||
|
||||
We can't do any of this to replace our XK and IK handshakes because:
|
||||
|
||||
- We can't do KK, Bob doesn't have Alice's static key
|
||||
- 500KB static keys are far too big
|
||||
- We don't want an extra round-trip
|
||||
|
||||
There is a lot of good information in the whitepaper,
|
||||
and we will review it for ideas and inspiration. TODO.
|
||||
|
||||
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
@@ -941,7 +961,7 @@ MLKEM1024_X25519 7 32 1680+pl 1648+pl 1568+pl
|
||||
================ ========= ===== ========= ============= ============= ========== =======
|
||||
|
||||
Note that the payload must contain a DateTime block, so the minimum payload size is 7.
|
||||
The minimum message 1 sizes may be caculated accordingly.
|
||||
The minimum message 1 sizes may be calculated accordingly.
|
||||
|
||||
|
||||
|
||||
@@ -1053,7 +1073,7 @@ MLKEM1024_X25519 7 32 1656+pl 1616+pl 1568+pl
|
||||
|
||||
Note that while message 2 will normally have a nonzero payload,
|
||||
the ratchet specification [ECIES]_ does not require it, so the minimum payload size is 0.
|
||||
The minimum message 2 sizes may be caculated accordingly.
|
||||
The minimum message 2 sizes may be calculated accordingly.
|
||||
|
||||
|
||||
|
||||
@@ -1819,8 +1839,7 @@ Library Support
|
||||
---------------
|
||||
|
||||
Bouncycastle, BoringSSL, and WolfSSL libraries support MLKEM and MLDSA now.
|
||||
OpenSSL support will be in their 3.5 release scheduled for April 8, 2025 [OPENSSL]_.
|
||||
3.5-alpha will be availabe March 11, 2025.
|
||||
OpenSSL support is be in their 3.5 release April 8, 2025 [OPENSSL]_.
|
||||
|
||||
The southernstorm.com Noise library adapted by Java I2P contained preliminary support for
|
||||
hybrid handshakes, but we removed it as unused; we will have to add it back
|
||||
@@ -2279,6 +2298,12 @@ References
|
||||
.. [RFC-2104]
|
||||
https://tools.ietf.org/html/rfc2104
|
||||
|
||||
.. [Rosenpass]
|
||||
https://rosenpass.eu/
|
||||
|
||||
.. [Rosenpass-Whitepaper]
|
||||
https://raw.githubusercontent.com/rosenpass/rosenpass/papers-pdf/whitepaper.pdf
|
||||
|
||||
.. [SSH-HYBRID]
|
||||
https://datatracker.ietf.org/doc/draft-ietf-sshm-mlkem-hybrid-kex/
|
||||
|
||||
|
@@ -3,7 +3,7 @@ SSU2
|
||||
======
|
||||
.. meta::
|
||||
:category: Transports
|
||||
:lastupdated: 2025-03
|
||||
:lastupdated: 2025-04
|
||||
:accuratefor: 0.9.65
|
||||
|
||||
.. contents::
|
||||
@@ -1549,7 +1549,7 @@ Payload
|
||||
- DateTime block
|
||||
- Address block
|
||||
- Relay Tag block (optional)
|
||||
- New Token block (optional)
|
||||
- New Token block (not recommended, see note)
|
||||
- First Packet Number block (optional)
|
||||
- Options block (optional)
|
||||
- Termination block (not recommended, send in a retry message instead)
|
||||
@@ -1589,6 +1589,10 @@ Notes
|
||||
|
||||
- Bob sends a relay tag block if requested by Alice in the Session Request.
|
||||
|
||||
- New Token block is not recommended in Session Created, because Bob
|
||||
should do validation of the Session Confirmed first. See
|
||||
the Tokens section below.
|
||||
|
||||
|
||||
Issues
|
||||
``````
|
||||
@@ -4219,7 +4223,9 @@ stores the values and associated IP and port (in-memory or persistently).
|
||||
The generator may not generate an opaque value, for example,
|
||||
using the SipHash (with a secret seed K0, K1) of the IP, port, and current hour or day,
|
||||
to create tokens that do not need to be saved in-memory,
|
||||
because this method make it difficult to reject reused tokens and replay attacks.
|
||||
because this method makes it difficult to reject reused tokens and replay attacks.
|
||||
However, it is a topic for further study if we may migrate to such a scheme,
|
||||
as [WireGuard]_ does, using a 16-byte HMAC of a server secret and IP address.
|
||||
|
||||
Tokens may only be used once.
|
||||
A token sent from Bob to Alice in a Retry message must be used immediately, and expires
|
||||
@@ -4228,7 +4234,8 @@ A token sent in a New Token block in an established session
|
||||
may be used in a subsequent connection, and it
|
||||
expires at the time specified in that block.
|
||||
Expiration is specified by the sender; recommended values are
|
||||
one hour minimum, several hours maximum.
|
||||
several minutes minimum, one or more hours maximum, depending on
|
||||
desired maximum overhead of stored tokens.
|
||||
|
||||
If a router's IP or port changes, it must delete all saved tokens
|
||||
(both inbound and outbound) for the old IP or port, as they are no longer valid.
|
||||
@@ -4239,9 +4246,15 @@ A router may choose to limit token storage, and remove the oldest stored tokens
|
||||
even if they have not expired.
|
||||
|
||||
New Token blocks may be sent from Alice to Bob or Bob to Alice.
|
||||
They would typically be sent once, during or soon after session establishment.
|
||||
The token may be resent before or after expiration with a new expiration time,
|
||||
or a new token may be sent.
|
||||
They would typically be sent at least once, during or soon after session establishment.
|
||||
Due to validation checks of the RouterInfo in the Session Confirmed message,
|
||||
Bob should not send a New Token block in the Session Created message,
|
||||
it may be sent with the ACK 0 and Router Info after the Session Confirmed is received
|
||||
and validated.
|
||||
|
||||
As session lifetimes are often longer than token expiration,
|
||||
the token should be resent before or after expiration with a new expiration time,
|
||||
or a new token should be sent.
|
||||
Routers should assume that only the last token received is valid;
|
||||
there is no requirement to store multiple inbound or outbound tokens for the same IP/port.
|
||||
|
||||
@@ -6114,6 +6127,22 @@ Total 1314
|
||||
================== =========== ===== ====== ======= ====== =====
|
||||
|
||||
|
||||
Issues and Future Work
|
||||
======================
|
||||
|
||||
Tokens
|
||||
------
|
||||
|
||||
We specify above that the token must be a randomly-generated 8 byte value,
|
||||
not generate an opaque value such as a hash or HMAC of a server secret
|
||||
and the IP, port, due to reuse attacks.
|
||||
However, this requires temporary and (optionally) persistent storage of
|
||||
delivered tokens.
|
||||
[WireGuard]_ uses a 16-byte HMAC of a server secret and IP address,
|
||||
and the server secret rotates every two minutes.
|
||||
We should investigate something similar, with a longer server secret lifetime.
|
||||
If we embed a timestamp in the token, that may be a solution, but
|
||||
an 8-byte token may not be large enough for that.
|
||||
|
||||
|
||||
|
||||
|
@@ -3,8 +3,8 @@ ECIES-X25519 Tunnel Creation
|
||||
=============================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-03
|
||||
:accuratefor: 0.9.65
|
||||
:lastupdated: 2025-06
|
||||
:accuratefor: 0.9.66
|
||||
|
||||
.. contents::
|
||||
|
||||
@@ -18,7 +18,7 @@ It is a portion of the overall proposal
|
||||
|
||||
There are two versions specified.
|
||||
The first uses the existing build messages and build record size, for compatibility with ElGamal routers.
|
||||
This specification is implemented as of release 0.9.48.
|
||||
This specification was implemented as of release 0.9.48 and is now deprecated.
|
||||
The second uses two new build messages and a smaller build record size, and may only be used with ECIES routers.
|
||||
This specification is implemented as of release 0.9.51.
|
||||
|
||||
@@ -138,6 +138,7 @@ ECIES replies use ChaCha20/Poly1305 AEAD for integrity, and authentication.
|
||||
Long Record Specification
|
||||
=========================
|
||||
|
||||
NOTE: Deprecated, obsolete. Use the Short Record format specified below.
|
||||
|
||||
|
||||
Build Request Records
|
||||
@@ -913,10 +914,9 @@ The recommended minimum number of build records is 4.
|
||||
If there are more build records than hops, "fake" records must be added,
|
||||
containing random or implementation-specific data.
|
||||
For inbound tunnel builds, there must always be one "fake" record for the
|
||||
originating router, with the correct 16-byte hash prefix, otherwise
|
||||
originating router, with the correct 16-byte hash prefix
|
||||
and a real X25519 ephemeral key, otherwise
|
||||
the closest hop will know that the next hop is the originator.
|
||||
The MSB of the ephemeral key (data[47] & 0x80) must also be cleared
|
||||
so it looks like a real X25519 public key.
|
||||
|
||||
The remainder of the "fake" record may be random data, or may encrypted in any format
|
||||
for the originator to send data to itself about the build,
|
||||
@@ -926,6 +926,7 @@ Originators of inbound tunnels must use some method to validate
|
||||
that their "fake" record has not been modified by the previous hop,
|
||||
as this may also be used for deanonimization.
|
||||
The orignator may store and verify a checksum of the record,
|
||||
or include the checksum in the record,
|
||||
or use an AEAD encryption/decryption function, implementation-dependent.
|
||||
If the 16-byte hash prefix or other build record contents were
|
||||
modified, the router must discard the tunnel.
|
||||
|
@@ -3,8 +3,8 @@ Tunnel Creation Specification
|
||||
=============================
|
||||
.. meta::
|
||||
:category: Design
|
||||
:lastupdated: July 2019
|
||||
:accuratefor: 0.9.41
|
||||
:lastupdated: 2025-05
|
||||
:accuratefor: 0.9.66
|
||||
|
||||
.. contents::
|
||||
|
||||
@@ -14,6 +14,9 @@ Tunnel Creation Specification
|
||||
Overview
|
||||
========
|
||||
|
||||
NOTE: OBSOLETE - This is the ElGamal tunnel build specification.
|
||||
See {{ spec_url('tunnel-creation-ecies') }} for the X25519 tunnel build specification.
|
||||
|
||||
This document specifies the details of the encrypted tunnel build messages used
|
||||
to create tunnels using a "non-interactive telescoping" method. See the tunnel
|
||||
build document [TUNNEL-IMPL]_ for an overview of the process, including peer
|
||||
|
457
i2p2www/spec/udp-announces.rst
Normal file
457
i2p2www/spec/udp-announces.rst
Normal file
@@ -0,0 +1,457 @@
|
||||
================================
|
||||
UDP Trackers
|
||||
================================
|
||||
.. meta::
|
||||
:category: Protocols
|
||||
:lastupdated: 2025-06
|
||||
:accuratefor: 0.9.67
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
This specification documents the protocol for UDP bittorrent announces in I2P.
|
||||
For the overall specification of bittorrent in I2P, see [SPEC]_.
|
||||
For background and additional information on the development
|
||||
of this specification, see Proposal 160 [Prop160]_.
|
||||
|
||||
|
||||
Design
|
||||
============
|
||||
|
||||
This proposal uses repliable datagram2, repliable datagram3, and raw datagrams,
|
||||
as defined in [DATAGRAMS]_.
|
||||
Datagram2 and Datagram3 are new variants of repliable datagrams,
|
||||
defined in Proposal 163 [Prop163]_.
|
||||
Datagram2 adds replay resistance and offline signature support.
|
||||
Datagram3 is smaller than the old datagram format, but without authentication.
|
||||
|
||||
|
||||
BEP 15
|
||||
-------
|
||||
|
||||
For reference, the message flow defined in [BEP15]_ is as follows:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight %}
|
||||
Client Tracker
|
||||
Connect Req. ------------->
|
||||
<-------------- Connect Resp.
|
||||
Announce Req. ------------->
|
||||
<-------------- Announce Resp.
|
||||
Announce Req. ------------->
|
||||
<-------------- Announce Resp.
|
||||
{% endhighlight %}
|
||||
|
||||
The connect phase is required to prevent IP address spoofing.
|
||||
The tracker returns a connection ID that the client uses in subsequent announces.
|
||||
This connection ID expires by default in one minute at the client, and in two minutes at the tracker.
|
||||
|
||||
I2P will use the same message flow as BEP 15,
|
||||
for ease of adoption in existing UDP-capable client code bases:
|
||||
for efficiency, and for security reasons discussed below:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight %}
|
||||
Client Tracker
|
||||
Connect Req. -------------> (Repliable Datagram2)
|
||||
<-------------- Connect Resp. (Raw)
|
||||
Announce Req. -------------> (Repliable Datagram3)
|
||||
<-------------- Announce Resp. (Raw)
|
||||
Announce Req. -------------> (Repliable Datagram3)
|
||||
<-------------- Announce Resp. (Raw)
|
||||
...
|
||||
{% endhighlight %}
|
||||
|
||||
This potentially provides a large bandwidth savings over
|
||||
streaming (TCP) announces.
|
||||
While the Datagram2 is about the same size as a streaming SYN,
|
||||
the raw response is much smaller than the streaming SYN ACK.
|
||||
Subsequent requests use Datagram3, and the subsequent responses are raw.
|
||||
|
||||
The announce requests are Datagram3 so that the tracker need not
|
||||
maintain a large mapping table of connection IDs to announce destination or hash.
|
||||
Instead, the tracker may generate connection IDs cryptographically
|
||||
from the sender hash, the current timestamp (based on some interval),
|
||||
and a secret value.
|
||||
When an announce request is received, the tracker validates the
|
||||
connection ID, and then uses the
|
||||
Datagram3 sender hash as the send target.
|
||||
|
||||
|
||||
|
||||
|
||||
Connection Lifetime
|
||||
-------------------
|
||||
|
||||
[BEP15]_ specifies that the connection ID expires in one minute at the client, and in two minutes at the tracker.
|
||||
It is not configurable.
|
||||
That limits the potential efficiency gains, unless
|
||||
clients batched announces to do all of them within a one-minute window.
|
||||
i2psnark does not currently batch announces; it spreads them out, to avoid bursts of traffic.
|
||||
Power users are reported to be running thousands of torrents at once,
|
||||
and bursting that many announces into one minute is not realistic.
|
||||
|
||||
Here, we propose to extend the connect response to add an optional connection lifetime field.
|
||||
The default, if not present, is one minute. Otherwise, the lifetime specified
|
||||
in seconds, shall be used by the client, and the tracker will maintain the
|
||||
connection ID for one minute more.
|
||||
|
||||
|
||||
Compatibility with BEP 15
|
||||
-------------------------
|
||||
|
||||
This design maintains compatibility with [BEP15]_ as much as possible
|
||||
to limit changes required in existing clients and trackers.
|
||||
|
||||
The only required change is the format of peer info in the announce response.
|
||||
The addition of the lifetime field in the connect response is not required
|
||||
but is strongly recommended for efficiency, as explained above.
|
||||
|
||||
|
||||
|
||||
Security Analysis
|
||||
------------------
|
||||
|
||||
An important goal of a UDP announce protocol is to prevent address spoofing.
|
||||
The client must actually exist and bundle a real leaseset.
|
||||
It must have inbound tunnels to receive the Connect Response.
|
||||
These tunnels could be zero-hop and built instantly, but that would
|
||||
expose the creator.
|
||||
This protocol accomplishes that goal.
|
||||
|
||||
|
||||
|
||||
Issues
|
||||
------
|
||||
|
||||
- This protocol does not support blinded destinations,
|
||||
but may be extended to do so. See below.
|
||||
|
||||
|
||||
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
Protocols and Ports
|
||||
-------------------
|
||||
|
||||
Repliable Datagram2 uses I2CP protocol 19;
|
||||
repliable Datagram3 uses I2CP protocol 20;
|
||||
raw datagrams use I2CP protocol 18.
|
||||
Requests may be Datagram2 or Datagram3. Responses are always raw.
|
||||
The older repliable datagram ("Datagram1") format using I2CP protocol 17
|
||||
must NOT be used for requests or replies; these must be dropped if received
|
||||
on the request/reply ports. Note that Datagram1 protocol 17
|
||||
is still used for the DHT protocol.
|
||||
|
||||
Requests use the I2CP "to port" from the announce URL; see below.
|
||||
The request "from port" is chosen by the client, but should be nonzero,
|
||||
and a different port from those used by DHT, so that responses
|
||||
may be easily classified.
|
||||
Trackers should reject requests received on the wrong port.
|
||||
|
||||
Responses use the I2CP "to port" from the request.
|
||||
The request "from port" is the "to port" from the request.
|
||||
|
||||
|
||||
Announce URL
|
||||
------------
|
||||
|
||||
The announce URL format is not specified in [BEP15]_,
|
||||
but as in clearnet, UDP announce URLs are of the form "udp://host:port/path".
|
||||
The path is ignored and may be empty, but is typically "/announce" on clearnet.
|
||||
The :port part should always be present, however,
|
||||
if the ":port" part is omitted, use a default I2CP port of 6969,
|
||||
as that is the common port on clearnet.
|
||||
There may also be cgi parameters &a=b&c=d appended,
|
||||
those may be processed and provided in the announce request, see [BEP41]_.
|
||||
If there are no parameters or path, the trailing / may also be omitted,
|
||||
as implied in [BEP41]_.
|
||||
|
||||
|
||||
Datagram Formats
|
||||
----------------
|
||||
|
||||
All values are send in network byte order (big endian).
|
||||
Do not expect packets to be exactly of a certain size.
|
||||
Future extensions could increase the size of packets.
|
||||
|
||||
|
||||
|
||||
Connect Request
|
||||
```````````````
|
||||
|
||||
Client to tracker.
|
||||
16 bytes. Must be repliable Datagram2. Same as in [BEP15]_. No changes.
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight %}
|
||||
Offset Size Name Value
|
||||
0 64-bit integer protocol_id 0x41727101980 // magic constant
|
||||
8 32-bit integer action 0 // connect
|
||||
12 32-bit integer transaction_id
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
|
||||
Connect Response
|
||||
````````````````
|
||||
|
||||
Tracker to client.
|
||||
16 or 18 bytes. Must be raw. Same as in [BEP15]_ except as noted below.
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight %}
|
||||
Offset Size Name Value
|
||||
0 32-bit integer action 0 // connect
|
||||
4 32-bit integer transaction_id
|
||||
8 64-bit integer connection_id
|
||||
16 16-bit integer lifetime optional // Change from BEP 15
|
||||
{% endhighlight %}
|
||||
|
||||
The response MUST be sent to the I2CP "to port" that was received as the request "from port".
|
||||
|
||||
The lifetime field is optional and indicates the connection_id client lifetime in seconds.
|
||||
The default is 60, and the minimum if specified is 60.
|
||||
The maximum is 65535 or about 18 hours.
|
||||
The tracker should maintain the connection_id for 60 seconds more than the client lifetime.
|
||||
|
||||
|
||||
|
||||
Announce Request
|
||||
````````````````
|
||||
|
||||
Client to tracker.
|
||||
98 bytes minimum. Must be repliable Datagram3. Same as in [BEP15]_ except as noted below.
|
||||
|
||||
The connection_id is as received in the connect response.
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight %}
|
||||
Offset Size Name Value
|
||||
0 64-bit integer connection_id
|
||||
8 32-bit integer action 1 // announce
|
||||
12 32-bit integer transaction_id
|
||||
16 20-byte string info_hash
|
||||
36 20-byte string peer_id
|
||||
56 64-bit integer downloaded
|
||||
64 64-bit integer left
|
||||
72 64-bit integer uploaded
|
||||
80 32-bit integer event 0 // 0: none; 1: completed; 2: started; 3: stopped
|
||||
84 32-bit integer IP address 0 // default, unused in I2P
|
||||
88 32-bit integer key
|
||||
92 32-bit integer num_want -1 // default
|
||||
96 16-bit integer port // must be same as I2CP from port
|
||||
98 varies options optional // As specified in BEP 41
|
||||
{% endhighlight %}
|
||||
|
||||
Changes from [BEP15]_:
|
||||
|
||||
- key is ignored
|
||||
- IP address is unused
|
||||
- port is probably ignored but must be same as I2CP from port
|
||||
- The options section, if present, is as defined in [BEP41]_
|
||||
|
||||
The response MUST be sent to the I2CP "to port" that was received as the request "from port".
|
||||
Do not use the port from the announce request.
|
||||
|
||||
|
||||
|
||||
Announce Response
|
||||
`````````````````
|
||||
|
||||
Tracker to client.
|
||||
20 bytes minimum. Must be raw. Same as in [BEP15]_ except as noted below.
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight %}
|
||||
Offset Size Name Value
|
||||
0 32-bit integer action 1 // announce
|
||||
4 32-bit integer transaction_id
|
||||
8 32-bit integer interval
|
||||
12 32-bit integer leechers
|
||||
16 32-bit integer seeders
|
||||
20 32 * n 32-byte hash binary hashes // Change from BEP 15
|
||||
... // Change from BEP 15
|
||||
{% endhighlight %}
|
||||
|
||||
Changes from [BEP15]_:
|
||||
|
||||
- Instead of 6-byte IPv4+port or 18-byte IPv6+port, we return
|
||||
a multiple of 32-byte "compact responses" with the SHA-256 binary peer hashes.
|
||||
As with TCP compact responses, we do not include a port.
|
||||
|
||||
The response MUST be sent to the I2CP "to port" that was received as the request "from port".
|
||||
Do not use the port from the announce request.
|
||||
|
||||
I2P datagrams have a very large maximum size of about 64 KB;
|
||||
however, for reliable delivery, datagrams larger than 4 KB should be avoided.
|
||||
For bandwidth efficiency, trackers should probably limit the maximum peers
|
||||
to about 50, which corresponds to about a 1600 byte packet before overhead
|
||||
at various layers, and should be within a two-tunnel-message payload limit
|
||||
after fragmentation.
|
||||
|
||||
As in BEP 15, there is no count included of the number of peer addresses
|
||||
(IP/port for BEP 15, hashes here) to follow.
|
||||
While not contemplated in BEP 15, an end-of-peers marker
|
||||
of all zeros could be defined to indicate that the peer info is complete
|
||||
and some extension data follows.
|
||||
|
||||
So that extension is possible in the future, clients should ignore
|
||||
a 32-byte all-zeros hash, and any data that follows.
|
||||
Trackers should reject announces from an all-zeros hash,
|
||||
although that hash is already banned by Java routers.
|
||||
|
||||
|
||||
Scrape
|
||||
``````
|
||||
|
||||
Scrape request/response from [BEP15]_ is not required by this specification,
|
||||
but may be implemented if desired, no changes required.
|
||||
The client must acquire a connection ID first.
|
||||
The scrape request is always repliable Datagram3.
|
||||
The scrape response is always raw.
|
||||
|
||||
|
||||
|
||||
Error Response
|
||||
``````````````
|
||||
|
||||
Tracker to client.
|
||||
8 bytes minimum (if the message is empty).
|
||||
Must be raw. Same as in [BEP15]_. No changes.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
{% highlight %}
|
||||
|
||||
Offset Size Name Value
|
||||
0 32-bit integer action 3 // error
|
||||
4 32-bit integer transaction_id
|
||||
8 string message
|
||||
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
|
||||
Extensions
|
||||
=============
|
||||
|
||||
Extension bits or a version field are not included.
|
||||
Clients and trackers should not assume packets to be of a certain size.
|
||||
This way, additional fields can be added without breaking compatibility.
|
||||
The extensions format defined in [BEP41]_ is recommended if required.
|
||||
|
||||
The connect response is modified to add an optional connection ID lifetime.
|
||||
|
||||
If blinded destination support is required, we can either add the
|
||||
blinded 35-byte address to the end of the announce request,
|
||||
or request blinded hashes in the responses,
|
||||
using the [BEP41]_ format (paramters TBD).
|
||||
The set of blinded 35-byte peer addresses could be added to the end of the announce reply,
|
||||
after an all-zeros 32-byte hash.
|
||||
|
||||
|
||||
|
||||
Implementation guidelines
|
||||
==========================
|
||||
|
||||
See the design section above for a discussion of the challenges for
|
||||
non-integrated, non-I2CP clients and trackers.
|
||||
|
||||
|
||||
Clients
|
||||
--------
|
||||
|
||||
For a given tracker hostname, a client should prefer UDP over HTTP URLs,
|
||||
and should not announce to both.
|
||||
|
||||
Clients with existing BEP 15 support should require only small modifications.
|
||||
|
||||
If a client support DHT or other datagram protocols, it should probably
|
||||
select a different port as the request "from port" so that the replies
|
||||
come back to that port and are not mixed up with DHT messages.
|
||||
The client only receives raw datagrams as replies.
|
||||
Trackers will never send a repliable datagram2 to the client.
|
||||
|
||||
Clients with a default list of opentrackers should update the list to
|
||||
add UDP URLs after the known opentrackers are known to support UDP.
|
||||
|
||||
Clients may or may not implement retransmission of requests.
|
||||
Retransmissions, if implemented, should use an initial timeout
|
||||
of at least 15 seconds, and double the timeout for each retransmission
|
||||
(exponential backoff).
|
||||
|
||||
Clients must back off after receiving an error response.
|
||||
|
||||
|
||||
Trackers
|
||||
---------
|
||||
|
||||
Trackers with existing BEP 15 support should require only small modifications.
|
||||
This specification differs from the 2014 proposal, in that the tracker
|
||||
must support reception of repliable datagram2 and datagram3 on the same port.
|
||||
|
||||
To minimize tracker resource requirements,
|
||||
this protocol is designed to eliminate any requirement that the tracker
|
||||
store mappings of client hashes to connection IDs for later validation.
|
||||
This is possible because the announce request packet is a repliable
|
||||
Datagram3 packet, so it contains the sender's hash.
|
||||
|
||||
A recommended implementation is:
|
||||
|
||||
- Define the current epoch as the current time with a resolution of the connection lifetime,
|
||||
``epoch = now / lifetime``.
|
||||
- Define a cryptographic hash function ``H(secret, clienthash, epoch)`` which generates
|
||||
an 8 byte output.
|
||||
- Generate the random constant secret used for all connections.
|
||||
- For connect responses, generate ``connection_id = H(secret, clienthash, epoch)``
|
||||
- For announce requests, validate the received connection ID in the current epoch by verifying
|
||||
``connection_id == H(secret, clienthash, epoch) || connection_id == H(secret, clienthash, epoch - 1)``
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [BEP15]
|
||||
http://www.bittorrent.org/beps/bep_0015.html
|
||||
|
||||
.. [BEP41]
|
||||
http://www.bittorrent.org/beps/bep_0041.html
|
||||
|
||||
.. [DATAGRAMS]
|
||||
{{ spec_url('datagrams') }}
|
||||
|
||||
.. [Prop160]
|
||||
{{ proposal_url('160') }}
|
||||
|
||||
.. [Prop163]
|
||||
{{ proposal_url('163') }}
|
||||
|
||||
.. [Prop169]
|
||||
{{ proposal_url('169') }}
|
||||
|
||||
.. [SAMv3]
|
||||
{{ site_url('docs/api/samv3') }}
|
||||
|
||||
.. [SPEC]
|
||||
{{ site_url('docs/applications/bittorrent', True) }}
|
@@ -3,8 +3,8 @@ Software Update Specification
|
||||
=============================
|
||||
.. meta::
|
||||
:category: Design
|
||||
:lastupdated: 2022-08
|
||||
:accuratefor: 0.9.55
|
||||
:lastupdated: 2025-04
|
||||
:accuratefor: 0.9.65
|
||||
|
||||
.. contents::
|
||||
|
||||
@@ -371,6 +371,21 @@ SU3 Details
|
||||
hash).dat", as in the old reseed mechanism. The I2P base 64 alphabet must be
|
||||
used.
|
||||
|
||||
|
||||
Notes
|
||||
`````
|
||||
* Warning: Several reseeds are known to be unresponsive via IPv6.
|
||||
Forcing or preferring IPv4 is recommended.
|
||||
|
||||
* Warning: Some reseeds use selfsigned CA certificates.
|
||||
Implementations must either import and trust these CAs when
|
||||
reseeding, or omit the selfsigned reseeds from the reseed list.
|
||||
|
||||
* Reseed signer keys are distributed to implementations as
|
||||
selfsigned X.509 certificates with RSA-4096 keys (signature type 6).
|
||||
Implementations should enforce the valid dates in the certificates.
|
||||
|
||||
|
||||
SU3 Plugin File Specification
|
||||
-----------------------------
|
||||
|
||||
|
@@ -65,3 +65,5 @@ r4sas.i2p=ABQFq3xLCaQ4wCOuL2rMdwPyQwVz1xrktkLMLShZJo2L7VZJgfTBWbfUWHCzWXKcIzxmzj
|
||||
opentracker.r4sas.i2p=P8CBg89WyA17SFPZJSQn9do~iCo2j8i-c8YmaByQS3TgY92or5-z7uml-5v6aV63LmO5epPptCN1pCzPyKg6aAa0mFuAG0jsV0GyjOqsQ57I~PomGZDYWnK3-Oj-ZDg128BwdXfNEa2YKxTTQGu2h5n141ObTm~NRGJBNeb0E4MGnRqvA24kI75LTtacq8M75ACW7CfhpBoWDCRTnrV0nHbH0yR4NiYRHs8WllUcP2oe2H~sNJYOuGkHxxaSTvD0wPTLL-Wx0weWV6v~QPkFA6ZkEaIAJbQjOCP4u0WJ1auaaljjnxTs-pSpd2UMV5uIN~4RIWEf6D2Q1RZg3IW9ulmP6FV2-UgZTsZ9UU3leQ2Qdt7ZOo49Nws5bKr9Lg4PeAeIa3Xx86yemDmzDO8YPjEEErcspz-SSrglnJP~PuGLJtN0v6uBZlGyKbBO7Z4tQc-nA2oHWGX9TVwQkWpcAGiZmDcoHqNhDj1OzsQ87WzkLt9X9fx4NsJUSch0Qm61BQAEAAcAAA==#!action=addsubdomain#date=1640739404#olddest=ABQFq3xLCaQ4wCOuL2rMdwPyQwVz1xrktkLMLShZJo2L7VZJgfTBWbfUWHCzWXKcIzxmzjcnvRfp5Y5udL1HmU5CVZ2bp1jis3FPgjcJoGqcsM7w~Lad5aYkf7If8IcH7DIpavJt3ch~yxt8571CVmv2F9R4TorSOnc04kHkOrqjIyHGHCN7TsyZ23FtADGM7uaRdEk8Cbtx6905ZW4mrc1AW6F6YqiLCnSC8vLEH80ELTR3FTTkveGenKg-9ITGW3X-99qcCvp-Br1QlUAyV-XorUym2dkpWPWDV2WXUZEX6WdQMBOvU0gQ6ig6WsNBvrKXop6R4Q333gsT7XkXSg5~I74c9ntFVuewZYbfuwu-ws-4Gb2ZyRVkccUpt1AYgruXwqyxLkx4GFVN4EYX0N~JYKPaU1yb7Xw~nnCVXH5uAbeIv3glAleK4huUfqK-1ZJRy0h81ualE--XLEsOEKNGFW8bleltl~6MxGSOiEaMawHHICW2FdCEmebG6JJHBQAEAAEAAA==#oldname=r4sas.i2p#oldsig=qtQ2nLeD87nD4oqCQvv8YMrcBtpLgYa3eDWQi5MDyNT8npG2yuxRwtYcU5zukyaod6MqoXNLNh9oAORVOU25~Q==#sig=ORrgekcqTYUnrxM5NZHl7I19x5lX~oVmOJsROufRkJ4fG1JaCjhh1zi1mRa4Y8k4XO6hQYr9N6sWN0na5hMKBw==
|
||||
skank.i2p=kagASzrpRCxoEzpKoGiA1KBTl-8-VAoDqaqq-iheMu5jmOt69pVIzsKJ571klT30zUCPJkW~6eTY3Kt4HhUoCcBxQOOdTc2yrW7wHmHjt~q~Ci92Cmz8xd~NwiZzdjONpA6AD~fQkl7oN4pKjmk58ZrOHNEXJYjZzceCtlCnoOgXMCUigTFr45nvTeloDOgCnU5vdjNbv-28Cwfy0hXEAHrPcEJdOdguD9HNiTeexjb0hxrl8ugwRaNBMFpMMhQgKwR1NJuvqol87XXvv2DE9mp2Gs~hdaHuJL2DGXitoq-OT3Si~~axGUyKKpo~unfwy9JSAA0aNkzRJ6SPBFNnsqZDzsMMnhupT3YDVeEzMjQSb08kYaHeBWM-hz7IUGI7tGNcb2g3kZlUKYAB9~QHF7m6kS0xbvwx8L~nDRpLpX~UURCsvy5LxoQkebvn7UGa1r6AAbDbaJoqPWeY98RU5m3V-cbG-1D4iSB8OvRUELjlE3vL7y7JCyMdJhAJxGCzBQAEAAcAAA==#!date=1507614292#sig=5INCXrtvcn9Q7YlouY4qEPghL6OD5ZQDN30GYKdcNli9PrTUfpYYAFvcBLx5R4KwJSIUoJMe5Uh37t2FyQ3KBw==
|
||||
opentracker.skank.i2p=5tSb-9kujvxfA9v-pgRPe4Fxv6FtLU~lykVKYRCPfwXS8Uizy-Ljn~yE9vGCf3KBeUudLUfRGTYBflJE04kYInZf28lLeG5xkLI29Hwz4lbUX~13BFZrPc-lnCVA6gyr4dAtcVf0b9YJSX2idOPiuZXkasa02SQb6k5yT5~4UvHHsTchO-XDkf38hsx~xjumfhg9DHI2CWrsuRFNR8K0CN9Z6H608jxWfizqsMH0EE6bohfmC42HVkZWXInAmtH1mSyC5t0RZiIVKcT8SvSoRr6QQpwBWsoUi6SyoWTRKT8LD9pT-3LNxabR60S28eiAgX1khDkIZEQvDXcie6TDIihZc0HhaYs2T67WlOKUovHQ4CqtfGDsD9Fpud3SyxXsq-A40NNlXTYStIW2JnwetTot8of5~PF1uv1XPMbfItvqDlMBz9TBtI5BJujD3SinHkcaWDVgr6bddsTJrjBZVojZurfeSMbEB~Y6NScr1O8V4BR2fpr6fFxWiqE5lTDDBQAEAAcAAA==#!action=addsubdomain#date=1711375599#olddest=kagASzrpRCxoEzpKoGiA1KBTl-8-VAoDqaqq-iheMu5jmOt69pVIzsKJ571klT30zUCPJkW~6eTY3Kt4HhUoCcBxQOOdTc2yrW7wHmHjt~q~Ci92Cmz8xd~NwiZzdjONpA6AD~fQkl7oN4pKjmk58ZrOHNEXJYjZzceCtlCnoOgXMCUigTFr45nvTeloDOgCnU5vdjNbv-28Cwfy0hXEAHrPcEJdOdguD9HNiTeexjb0hxrl8ugwRaNBMFpMMhQgKwR1NJuvqol87XXvv2DE9mp2Gs~hdaHuJL2DGXitoq-OT3Si~~axGUyKKpo~unfwy9JSAA0aNkzRJ6SPBFNnsqZDzsMMnhupT3YDVeEzMjQSb08kYaHeBWM-hz7IUGI7tGNcb2g3kZlUKYAB9~QHF7m6kS0xbvwx8L~nDRpLpX~UURCsvy5LxoQkebvn7UGa1r6AAbDbaJoqPWeY98RU5m3V-cbG-1D4iSB8OvRUELjlE3vL7y7JCyMdJhAJxGCzBQAEAAcAAA==#oldname=skank.i2p#oldsig=1qmKeCQ93tGCmP9oQuH-AgTwnyEqGuK58A6aIYAzb9qmUS37K6xJPzQH7okbexmPzhADMzDUojRuJSEaDn~QBQ==#sig=OZKaH6LbB5Ff-ErNWAA5vK8EIUC6Sjjy-uOHZISasxlPQcPezAW3cNx4yxgMTMyA40RzDaw1H2pDidZgw8OXAg==
|
||||
simp.i2p=aOytzLqlQKuvEHG1G0mGtfHy~Hq~vNvsQUKKPc1vtA5o7K3MuqVAq68QcbUbSYa18fL8er-82-xBQoo9zW-0Dmjsrcy6pUCrrxBxtRtJhrXx8vx6v7zb7EFCij3Nb7QOaOytzLqlQKuvEHG1G0mGtfHy~Hq~vNvsQUKKPc1vtA5o7K3MuqVAq68QcbUbSYa18fL8er-82-xBQoo9zW-0Dmjsrcy6pUCrrxBxtRtJhrXx8vx6v7zb7EFCij3Nb7QOaOytzLqlQKuvEHG1G0mGtfHy~Hq~vNvsQUKKPc1vtA5o7K3MuqVAq68QcbUbSYa18fL8er-82-xBQoo9zW-0Dmjsrcy6pUCrrxBxtRtJhrXx8vx6v7zb7EFCij3Nb7QOaOytzLqlQKuvEHG1G0mGtfHy~Hq~vNvsQUKKPc1vtA5o7K3MuqVAq68QcbUbSYa18fL8er-82-xBQoo9zW-0DswF20vQDnADcqJFNTR2G4jqIjeO2IkXxyOFSMIHXpNLBQAEAAcAAA==#!date=1728461275#sig=2S1UMdQSsYPn~JY9kX4MUGW3kBda6aFtoEEgqswJ8Vgl1OshMeNKh00kGPt0UaLhOOf7HI4c-YNFfi~bAvCjBA==
|
||||
opentracker.simp.i2p=ReYRdCMFKW9paQyQzBPDhbAP38rQDqC0Wektf0Zd9slF5hF0IwUpb2lpDJDME8OFsA~fytAOoLRZ6S1~Rl32yUXmEXQjBSlvaWkMkMwTw4WwD9~K0A6gtFnpLX9GXfbJReYRdCMFKW9paQyQzBPDhbAP38rQDqC0Wektf0Zd9slF5hF0IwUpb2lpDJDME8OFsA~fytAOoLRZ6S1~Rl32yUXmEXQjBSlvaWkMkMwTw4WwD9~K0A6gtFnpLX9GXfbJReYRdCMFKW9paQyQzBPDhbAP38rQDqC0Wektf0Zd9slF5hF0IwUpb2lpDJDME8OFsA~fytAOoLRZ6S1~Rl32yUXmEXQjBSlvaWkMkMwTw4WwD9~K0A6gtFnpLX9GXfbJReYRdCMFKW9paQyQzBPDhbAP38rQDqC0Wektf0Zd9slF5hF0IwUpb2lpDJDME8OFsA~fytAOoLRZ6S1~Rl32ydyHFiVs5x0YG8XettDPDR7zCxUp-vUcVNsUC58F-99JBQAEAAcAAA==#!action=addsubdomain#date=1747105562#olddest=aOytzLqlQKuvEHG1G0mGtfHy~Hq~vNvsQUKKPc1vtA5o7K3MuqVAq68QcbUbSYa18fL8er-82-xBQoo9zW-0Dmjsrcy6pUCrrxBxtRtJhrXx8vx6v7zb7EFCij3Nb7QOaOytzLqlQKuvEHG1G0mGtfHy~Hq~vNvsQUKKPc1vtA5o7K3MuqVAq68QcbUbSYa18fL8er-82-xBQoo9zW-0Dmjsrcy6pUCrrxBxtRtJhrXx8vx6v7zb7EFCij3Nb7QOaOytzLqlQKuvEHG1G0mGtfHy~Hq~vNvsQUKKPc1vtA5o7K3MuqVAq68QcbUbSYa18fL8er-82-xBQoo9zW-0Dmjsrcy6pUCrrxBxtRtJhrXx8vx6v7zb7EFCij3Nb7QOaOytzLqlQKuvEHG1G0mGtfHy~Hq~vNvsQUKKPc1vtA5o7K3MuqVAq68QcbUbSYa18fL8er-82-xBQoo9zW-0DswF20vQDnADcqJFNTR2G4jqIjeO2IkXxyOFSMIHXpNLBQAEAAcAAA==#oldname=simp.i2p#oldsig=FSZjv~Dlgu~xfhTbg9xw5S4MoOrXOA2DR62zvf3sLm-GvRcR3h5qwowXeMfGdTO9NfrW0mQk9pS2eQ4yj7JGAw==#sig=-EFE-hfW5OgUFEro~GHxJsQVlTr03rCWZ8H3PWYbhIasGuGR4Eh1yz-QPOrdkDvuDDfglip~UwL~k2xSVsNsCQ==
|
||||
|
Binary file not shown.
@@ -153,18 +153,18 @@ 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
|
||||
@@ -218,63 +218,76 @@ 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
|
||||
=Tgt6
|
||||
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
|
||||
bc5ucGN3t5b/iDrKyTcPc8cC1IFa1Mc=
|
||||
=uM54
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
@@ -25,7 +25,7 @@ body::before {
|
||||
}
|
||||
|
||||
a {
|
||||
color: #4a4a4a;
|
||||
color: #282898;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@@ -1044,4 +1044,4 @@ html {
|
||||
font-family: sans-serif;
|
||||
line-height: 1.15;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user