Compare commits
28 Commits
787817bc6b
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3041e87ebe | ||
![]() |
9fafe29f32 | ||
![]() |
4f048f75a7 | ||
![]() |
513339fa41 | ||
![]() |
1dbd337512 | ||
![]() |
0206eb63cb | ||
![]() |
ee7ed83062 | ||
![]() |
dd14d5ccf8 | ||
![]() |
c497a9a840 | ||
![]() |
4c4cffbc6d | ||
![]() |
dbfa21d523 | ||
![]() |
836cdb9cd0 | ||
![]() |
80972af6b3 | ||
![]() |
b6ac602c8d | ||
![]() |
d9d2fcac82 | ||
![]() |
6b4634fb21 | ||
![]() |
dabf40a185 | ||
![]() |
d3df17be81 | ||
![]() |
0d70474034 | ||
![]() |
3952d48b3c | ||
![]() |
287e7149de | ||
![]() |
422ec5aa3a | ||
![]() |
5cb8e81a09 | ||
![]() |
2515a42427 | ||
![]() |
0dfc92de5e | ||
![]() |
68d3546fb0 | ||
![]() |
de5aba25b8 | ||
![]() |
93fbccb206 |
2
.github/workflows/sync.yaml
vendored
2
.github/workflows/sync.yaml
vendored
@@ -62,5 +62,5 @@ name: Sync Primary Repository to GitHub Mirror
|
||||
"on":
|
||||
push: {}
|
||||
schedule:
|
||||
- cron: 0 * * * *
|
||||
- cron: 0 0 * * *
|
||||
workflow_dispatch: {}
|
||||
|
17
Dockerfile
17
Dockerfile
@@ -1,7 +1,10 @@
|
||||
FROM debian:oldoldstable as builder
|
||||
FROM debian:buster as builder
|
||||
ENV SERVERNAME=geti2p.net \
|
||||
SERVERMAIL=example@geti2p.net
|
||||
|
||||
# Replace the buster repos with the archive.debian.org versions
|
||||
RUN sed -i 's|http://deb.debian.org/debian|http://archive.debian.org/debian|g' /etc/apt/sources.list
|
||||
|
||||
# Install only build dependencies first
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
@@ -9,8 +12,10 @@ RUN apt-get update && \
|
||||
python-pip \
|
||||
patch \
|
||||
python-virtualenv \
|
||||
virtualenv \
|
||||
git \
|
||||
python-polib && \
|
||||
python-polib \
|
||||
build-essential && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /build
|
||||
@@ -34,7 +39,10 @@ RUN . env/bin/activate && \
|
||||
echo "Git revision: $(git log -n 1 | grep commit | sed 's/commit //' | sed 's/ .*$//')" > ./i2p2www/pages/include/mtnversion
|
||||
|
||||
# Start second stage with same old base image
|
||||
FROM debian:oldoldstable
|
||||
FROM debian:buster
|
||||
|
||||
# Replace the buster repos with the archive.debian.org versions
|
||||
RUN sed -i 's|http://deb.debian.org/debian|http://archive.debian.org/debian|g' /etc/apt/sources.list
|
||||
|
||||
# Install only runtime dependencies
|
||||
RUN apt-get update && \
|
||||
@@ -42,7 +50,8 @@ RUN apt-get update && \
|
||||
apache2 \
|
||||
apache2-utils \
|
||||
libapache2-mod-wsgi \
|
||||
python2-minimal && \
|
||||
python2-minimal \
|
||||
build-essential && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /var/www/i2p.www
|
||||
|
@@ -22,8 +22,8 @@ except ImportError:
|
||||
###########
|
||||
# Constants
|
||||
|
||||
CURRENT_I2P_VERSION = '2.9.0'
|
||||
CURRENT_I2P_FIREFOX_PROFILE_VERSION = '2.8.2'
|
||||
CURRENT_I2P_VERSION = '2.10.0'
|
||||
CURRENT_I2P_FIREFOX_PROFILE_VERSION = '2.9.0'
|
||||
CURRENT_I2P_OSX_VERSION = '1.9.0'
|
||||
|
||||
CANONICAL_DOMAIN = 'geti2p.net'
|
||||
|
45
i2p2www/blog/2025/09/08/2.10.0_release.rst
Normal file
45
i2p2www/blog/2025/09/08/2.10.0_release.rst
Normal file
@@ -0,0 +1,45 @@
|
||||
{% trans -%}
|
||||
==================
|
||||
I2P 2.10.0 Release
|
||||
==================
|
||||
{%- endtrans %}
|
||||
.. meta::
|
||||
:author: idk
|
||||
:date: 2025-09-08
|
||||
:category: release
|
||||
:excerpt: {% trans %}I2P 2.10.0 Release{% endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Work continues on the implementation and deployment of post-quantum cryptography in I2P.
|
||||
In this release post-quantum cryptography is available but not turned on by default for new tunnels.
|
||||
Those of you interested in testing post-quantum support should enable it via the "Hidden Service Manager" under "Encryption Types."
|
||||
Be sure to get in touch on #i2p-dev in IRC2P for help and to report any issues you encounter.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
I2PSnark now supports UDP trackers.
|
||||
This should help the network overall by reducing the load of torrent trackers.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Stability improvements have been made to the Hidden Mode which will reduce the chance of running out of RouterInfos.
|
||||
{%- endtrans %}
|
||||
|
||||
{% trans -%}
|
||||
Important! In the next release, I2P will require Java 17 or later.
|
||||
{%- 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 %}**
|
||||
|
||||
::
|
||||
|
||||
f96110b00c28591691d409bd2f1768b7906b80da5cab2e20ddc060cbb4389fbf i2pinstall_2.10.0_windows.exe
|
||||
76372d552dddb8c1d751dde09bae64afba81fef551455e85e9275d3d031872ea i2pinstall_2.10.0.jar
|
||||
3b651b761da530242f6db6536391fb781bc8e07129540ae7e96882bcb7bf2375 i2psource_2.10.0.tar.bz2
|
||||
c89f568ebdc7d75c6fde59c4f68ac09031543d3ce8643c08e0f46d97513e90aa i2pupdate_2.10.0.zip
|
||||
04aa738517d5268c157ec267348b9fdda89b5f26052603b21cd4a1bd217c2f66 i2pupdate.su3
|
@@ -1,11 +1,13 @@
|
||||
from flask import abort, redirect, render_template, request
|
||||
from flask import abort, redirect, render_template, request, jsonify
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
import simplejson as json
|
||||
from random import randint
|
||||
import re
|
||||
import os.path
|
||||
|
||||
from i2p2www import CURRENT_I2P_VERSION, MIRRORS_FILE
|
||||
from i2p2www import CURRENT_I2P_VERSION, MIRRORS_FILE, TEMPLATE_DIR
|
||||
|
||||
DEFAULT_MIRROR = {
|
||||
"net": "clearnet",
|
||||
@@ -73,6 +75,85 @@ def read_mirrors():
|
||||
ret[net][protocol][domain]=obj
|
||||
return ret
|
||||
|
||||
# Extract hashes and filenames from macros file
|
||||
def extract_hashes_from_macros():
|
||||
macros_path = os.path.join(TEMPLATE_DIR, 'downloads', 'macros')
|
||||
if not os.path.exists(macros_path):
|
||||
return {}
|
||||
|
||||
with open(macros_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Dictionary to store hash variable name to hash value mapping
|
||||
hashes = {}
|
||||
|
||||
# Regex to extract hash variables
|
||||
hash_pattern = re.compile(r'{%\s*set\s+(\w+_hash)\s*=\s*[\'"]([a-fA-F0-9]+)[\'"]')
|
||||
|
||||
for match in hash_pattern.finditer(content):
|
||||
var_name = match.group(1)
|
||||
hash_value = match.group(2)
|
||||
hashes[var_name] = hash_value
|
||||
|
||||
# Now map hash variables to their corresponding file patterns
|
||||
hash_to_file = {}
|
||||
|
||||
# Extract the filename patterns for each package type
|
||||
if 'i2pinstall_windows_hash' in hashes:
|
||||
hash_to_file['i2pinstall_windows_hash'] = {
|
||||
'hash': hashes['i2pinstall_windows_hash'],
|
||||
'filename_pattern': 'i2pinstall_{version}_windows.exe'
|
||||
}
|
||||
|
||||
if 'i2pinstall_jar_hash' in hashes:
|
||||
hash_to_file['i2pinstall_jar_hash'] = {
|
||||
'hash': hashes['i2pinstall_jar_hash'],
|
||||
'filename_pattern': 'i2pinstall_{version}.jar'
|
||||
}
|
||||
|
||||
if 'i2psource_hash' in hashes:
|
||||
hash_to_file['i2psource_hash'] = {
|
||||
'hash': hashes['i2psource_hash'],
|
||||
'filename_pattern': 'i2psource_{version}.tar.bz2'
|
||||
}
|
||||
|
||||
if 'i2pupdate_hash' in hashes:
|
||||
hash_to_file['i2pupdate_hash'] = {
|
||||
'hash': hashes['i2pupdate_hash'],
|
||||
'filename_pattern': 'i2pupdate_{version}.zip'
|
||||
}
|
||||
|
||||
if 'i2p_android_hash' in hashes:
|
||||
hash_to_file['i2p_android_hash'] = {
|
||||
'hash': hashes['i2p_android_hash'],
|
||||
'filename_pattern': 'app.apk'
|
||||
}
|
||||
|
||||
if 'i2p_macnative_hash' in hashes:
|
||||
# Extract the OSX launcher version from macros
|
||||
osx_version_pattern = re.compile(r'{%\s*set\s+i2p_macosx_launcher_version\s*=\s*[\'"]([^\'\"]+)[\'"]')
|
||||
osx_match = osx_version_pattern.search(content)
|
||||
osx_version = osx_match.group(1) if osx_match else '1.9.0'
|
||||
|
||||
hash_to_file['i2p_macnative_hash'] = {
|
||||
'hash': hashes['i2p_macnative_hash'],
|
||||
'filename_pattern': 'I2PMacLauncher-{version}-beta-' + osx_version + '.dmg'
|
||||
}
|
||||
|
||||
if 'i2p_bundle_hash' in hashes:
|
||||
hash_to_file['i2p_bundle_hash'] = {
|
||||
'hash': hashes['i2p_bundle_hash'],
|
||||
'filename_pattern': 'i2p-bundle-{version}.exe'
|
||||
}
|
||||
|
||||
# Generate final JSON with actual filenames using current version
|
||||
result = {}
|
||||
for key, data in hash_to_file.items():
|
||||
filename = data['filename_pattern'].format(version=CURRENT_I2P_VERSION)
|
||||
result[filename] = data['hash']
|
||||
|
||||
return result
|
||||
|
||||
# List of downloads
|
||||
def downloads_list():
|
||||
# TODO: read mirror list or list of available files
|
||||
@@ -178,3 +259,10 @@ def downloads_redirect(version, net, protocol, domain, file):
|
||||
return render_template('downloads/redirect.html',
|
||||
version=version, protocol=protocol, domain=domain, file=file,
|
||||
url=mirrors[domain]['url'] % data)
|
||||
|
||||
# JSON endpoint for hashes
|
||||
def downloads_hashes():
|
||||
"""Return JSON with hashes and filenames from the macros file"""
|
||||
hashes = extract_hashes_from_macros()
|
||||
return jsonify(hashes)
|
||||
|
||||
|
@@ -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
|
||||
@@ -47,7 +47,7 @@ start an installer, "double-click" the downloaded .exe file.
|
||||
<p>{% trans -%}
|
||||
Running the installer will create a shortcut to start browsing I2P in your start
|
||||
menu and on your desktop. Clicking this shortcut will start I2P if necessary,
|
||||
then start an I2P Browser. On the first run, you will also be promted with the
|
||||
then start an I2P Browser. On the first run, you will also be prompted with the
|
||||
bandwidth wizard in your browser window. You will also see a "Toopie" icon in
|
||||
your taskbar to indicate that I2P is working when the browser window is closed.
|
||||
{%- endtrans %}</p>
|
||||
@@ -60,7 +60,7 @@ special configuration. You don't even need to close existing Firefox windows.
|
||||
{%- set name = 'Windows' -%}
|
||||
{%- set icon = 'images/download/windows.png' -%}
|
||||
{%- set filename = 'I2P-Easy-Install-Bundle-%s.exe' -%}
|
||||
{%- set hash = 'a8e7e02b00428a150d8287774879c3babd4f0eeede7b691403dc283c05bda750' -%}
|
||||
{%- set hash = i2p_bundle_hash -%}
|
||||
|
||||
{% call package_outer('windows', name, icon) %}
|
||||
<div class = "file">
|
||||
@@ -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
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{% extends "global/layout.html" %}
|
||||
{%- from "downloads/macros" import package_outer with context -%}
|
||||
{%- from "downloads/macros" import package, package_outer with context -%}
|
||||
{% block title %}Firefox Profile{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
@@ -14,105 +14,4 @@ time it installs the browser profile. This page has been kept to document the
|
||||
motivations and design of the included Firefox profile. To learn more about the
|
||||
new bundle, visit <a href="{{ nsis }}">The Easy Install Bundle Page</a>.
|
||||
{%- endtrans %}</p>
|
||||
<p>{% trans -%}
|
||||
The latest I2P Easy-Install bundle for Windows has been released unsigned.
|
||||
Please verify that the hashes match the downloads when installing the bundle.
|
||||
{%- endtrans %}</p>
|
||||
<h2>{{ _('I2P Firefox Browser Profile') }}</h2>
|
||||
<p>{% trans -%}
|
||||
Now that you have joined the I2P network, you will want to see I2P Sites and and
|
||||
other content that is hosted on the network. The Firefox browser profile is
|
||||
pre-configured to allow you to access the content available on the network.
|
||||
{%- endtrans %}</p>
|
||||
<h2>{{ _('Why should I use it?') }}</h2>
|
||||
<p>{% trans -%}
|
||||
Browsers are highly complex and powerful engines for executing code and displaying
|
||||
information obtained mainly from strangers on the internet. By default, they
|
||||
tend to leak a great deal of information about the person using them to the servers
|
||||
they retrieve information from. Using this browser profile allows you to become
|
||||
part of a "common" set of very similar browser users, instead of appearing unique
|
||||
or revealing details of your hardware or software. Because this involves disabling
|
||||
some browser features, this also reduces the attack surface available to outsiders.
|
||||
This keeps you safer while browsing the Invisible Web.
|
||||
{%- endtrans %}</p>
|
||||
<h2>{{ _('How do I use it?') }}</h2>
|
||||
<p>{% trans firefox="https://www.mozilla.org/" -%}
|
||||
First, download and install <a href="{{ firefox }}">Firefox</a>, then,
|
||||
just download and install this installer(below). To
|
||||
start an installer, "double-click" the downloaded .exe file.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
{%- set name = 'Windows' -%}
|
||||
{%- set icon = 'images/download/windows.png' -%}
|
||||
{%- set filename = 'I2P-Easy-Install-Bundle-%s.exe' -%}
|
||||
{%- set hash = 'a8e7e02b00428a150d8287774879c3babd4f0eeede7b691403dc283c05bda750' -%}
|
||||
|
||||
{% call package_outer('windows', name, icon) %}
|
||||
<div class = "file">
|
||||
<a class = "default" href="{{ url_for('downloads_redirect', version=pver(), net=def_mirror.net, protocol=def_mirror.protocol, domain=def_mirror.domain, file=pver(filename) )}}">
|
||||
<span class = "name">{{ pver(filename) }}</span><br/>
|
||||
<span class="mirror">{{ _('Mirror:') }} <img src="{{ url_for('static', filename='images/flags/'+def_mirror.country+'.png') }}" /> {{ def_mirror.org }}</span>
|
||||
</a>
|
||||
<a class="mirrors" href="{{ get_url('downloads_select', version=pver(), file=pver(filename)) }}">{{ _('select alternate mirror') }}</a>
|
||||
</div>
|
||||
<div class="meta">
|
||||
<div class="hash">
|
||||
<code>{{ hash }}</code>
|
||||
</div>
|
||||
</div>
|
||||
<p>{% trans -%}
|
||||
Download that file and run it.
|
||||
{%- endtrans %}</p>
|
||||
{% endcall %}
|
||||
|
||||
<h2>{{ _('What is in it?') }}</h2>
|
||||
<p><strong>{% trans -%}
|
||||
A Jpackaged I2P Router: {%- endtrans %}</strong>
|
||||
{% trans -%}The I2P router is "jpackaged" which means that it includes all
|
||||
the required Java components it needs to run successfully. It does not require
|
||||
a separate Java installation, because it bundles a Java 16 Runtime which is only
|
||||
used for I2P.
|
||||
{%- endtrans %}</p>
|
||||
<p><strong>{% trans -%}
|
||||
Browser Extensions: {%- endtrans %}</strong>
|
||||
{% trans -%}The browser profile also includes both the NoScript and HTTPSEverywhere plugin for
|
||||
better protection Javascript based attacks and HTTPS support where available. It
|
||||
also keeps your I2P search activity separate from your visible internet search
|
||||
activity. The profile configures the I2P Proxy for all sites and browser features.
|
||||
I2P In Private Browsing is used to provide I2P-Specific browser integrations.
|
||||
{%- endtrans %}</p>
|
||||
<h3>{{ _('Source Code and Issue Tracking') }}</h3>
|
||||
<div>{% trans -%}
|
||||
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://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>
|
||||
<div>{% trans -%}
|
||||
If you wish to file an issue about the Firefox profile, 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.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
|
||||
settings, combined with an I2P router and some launcher scripts. That means that
|
||||
it requires Firefox(Or Tor Browser) to be installed before you can use it. This
|
||||
is for security reasons, it is important that you are able to recieve reliable
|
||||
updates from a trustworthy vendor.
|
||||
{%- endtrans %}</p>
|
||||
<p>{% trans -%}
|
||||
I2P routers are designed to have long uptimes, and so unlike Tor Browser, the
|
||||
lifetime of your I2P Router is not tied to the lifetime of your I2P browsing
|
||||
session. The browser profile will manage your history, your browser's local
|
||||
storage and cache, and your browsing context but it will never stop your I2P
|
||||
router on its own. You may stop the router using the web interface on the
|
||||
router console homepage.
|
||||
{%- endtrans %}</p>
|
||||
|
||||
{% endblock %}
|
||||
|
@@ -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,9 +1,10 @@
|
||||
{% set i2pinstall_windows_hash = 'fe106319dcf5972b7c833150292cb72ae6a764cf18929f043dfb9f10340ee782' %}
|
||||
{% set i2pinstall_jar_hash = 'fee438e9f42345eeef3f5255842bbcf725eb01f1f84589791a525cd45143555b' %}
|
||||
{% set i2psource_hash = '03989319e186d9b06ed96ea0efa6ac95af1bc57af956d7f5f06f52f8da64fcd7' %}
|
||||
{% set i2pupdate_hash = '1b79b2593bbe60e08da3f84411d48a5f1fe0c8cfd934f1c90d2fece436c1f2b5' %}
|
||||
{% set i2pinstall_windows_hash = 'f96110b00c28591691d409bd2f1768b7906b80da5cab2e20ddc060cbb4389fbf' %}
|
||||
{% set i2pinstall_jar_hash = '76372d552dddb8c1d751dde09bae64afba81fef551455e85e9275d3d031872ea' %}
|
||||
{% set i2psource_hash = '3b651b761da530242f6db6536391fb781bc8e07129540ae7e96882bcb7bf2375' %}
|
||||
{% set i2pupdate_hash = 'c89f568ebdc7d75c6fde59c4f68ac09031543d3ce8643c08e0f46d97513e90aa' %}
|
||||
{% set i2p_android_hash = '13b6e3c35756605e8e65804ab91cb34521c819fcfaebafb348eba5d40bed6699' %}
|
||||
{% set i2p_macnative_hash = '18cb22cfcc3cbe0cec150e89a394d1a35703cb508ed627ef48084b7ba7c90dde' %}
|
||||
{% set i2p_bundle_hash = 'e2b70423b4f4bef4179bf54dee4284d897a8b48f1c3c63a3f24acb45388a38c8' %}
|
||||
|
||||
{% set i2p_windows_subver = '' %}
|
||||
{% set i2p_macosx_launcher_version = '1.9.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>
|
||||
|
@@ -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
|
||||
@@ -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,18 +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>
|
||||
UDP tracker support (prop. 160)
|
||||
Hybrid PQ MLKEM Ratchet final, enable by default (prop. 169)
|
||||
</li>
|
||||
<li>
|
||||
Implement LS service record parameter (prop. 167)
|
||||
Jetty 12, require Java 17+
|
||||
</li>
|
||||
<li>
|
||||
Continue work on PQ (prop. 169);
|
||||
Start checking in MLKEM parts of PQ (prop. 169)
|
||||
Continue work on PQ (transports) (prop. 169)
|
||||
</li>
|
||||
<li>
|
||||
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)
|
||||
@@ -37,10 +70,19 @@
|
||||
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>
|
||||
|
||||
|
@@ -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>.
|
||||
|
@@ -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
|
||||
|
||||
|
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
|
||||
@@ -3251,6 +3252,9 @@ References
|
||||
.. [CRYPTO-ELG]
|
||||
{{ site_url('docs/how/cryptography', True) }}#elgamal
|
||||
|
||||
.. [ECIES-HYBRID]
|
||||
{{ spec_url('ecies-hybrid') }}
|
||||
|
||||
.. [Datagrams]
|
||||
{{ spec_url('datagrams') }}
|
||||
|
||||
|
@@ -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::
|
||||
@@ -917,18 +917,18 @@ Contents
|
||||
through release 0.9.5, must be set to 00
|
||||
as of release 0.9.6, ignored
|
||||
as of release 0.9.16:
|
||||
00 => normal lookup, return `RouterInfo` or `LeaseSet` or
|
||||
`DatabaseSearchReplyMessage`
|
||||
Not recommended when sending to routers
|
||||
with version 0.9.16 or higher.
|
||||
00 => ANY lookup, return `RouterInfo` or `LeaseSet` or
|
||||
`DatabaseSearchReplyMessage`. DEPRECATED.
|
||||
Use LS or RI lookup as of 0.9.16.
|
||||
01 => LS lookup, return `LeaseSet` or
|
||||
`DatabaseSearchReplyMessage`
|
||||
As of release 0.9.38, may also return a
|
||||
`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
|
||||
|
@@ -5,13 +5,23 @@ UDP Trackers
|
||||
:author: zzz
|
||||
:created: 2022-01-03
|
||||
:thread: http://zzz.i2p/topics/1634
|
||||
:lastupdated: 2025-06-09
|
||||
: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
|
||||
========
|
||||
|
||||
@@ -563,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
|
||||
@@ -243,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
|
||||
@@ -965,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.
|
||||
|
||||
|
||||
|
||||
@@ -1077,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.
|
||||
|
||||
|
||||
|
||||
@@ -1843,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
|
||||
|
@@ -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
|
||||
|
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) }}
|
Binary file not shown.
@@ -153,18 +153,18 @@ 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
|
||||
@@ -218,63 +218,76 @@ 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
|
||||
=Tgt6
|
||||
kAe7GmEdVfKpKtJUfQtzaIw5kRrLTMxeGm/o0WdzG3qZNs7nFqveHmZzjYkCVAQT
|
||||
AQoAPgIbAwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgBYhBHhA52EPKLkEdTVJ12fs
|
||||
5WBbzxNGBQJhO2zUBQkSwP3yAAoJEGfs5WBbzxNGRw4P/1J5jBaTt0Qc9HSMB4Db
|
||||
+ig8Zlg79D7MqFjg1TMiTfGuwd5jxPoJIxgWL6wuMsP1Huqomvup9qVbJjt719ii
|
||||
WsXTSNRybiPyaa5q6WquCdrethoU77yeOy+OB5W7ylYU03SQUZ2t+vr8VF7XRn4U
|
||||
Y+XNx3+SlwkWkAhy1j2LaPFWTZ+NZyCBsGfq+vJ8Jhn62mwyVDEuBtLtcvWt5PMw
|
||||
oP/UXzdEQQGeS9VYhNp0kzeLZRdH7AexWWCX2JxI2gQ1sqO4I6EWgm9BwpJMrVGv
|
||||
YSJiQW/OzUTXgi2MiyJ2rwYD+MbiuV8r7xuHTbgQLc/D0OSH/JZbavxfmaGpzAky
|
||||
zLCCCRcxSA33pVeqKPSS05VlGSjtXGF0DKVAI6zRkGqgLdkkQhyBgth+HyQ3n0Bn
|
||||
Sy5jpet0xWq641WwJci+W7hL+x8pBYBGaZ04GoIMpX5GBDTLrs39Va4K86c7h5Ke
|
||||
nvGXq8ZsPaE78o8cvlglHW0hIvLCY/uJUxOMWH3zIPkXnsbaFmqo/+u/FfSoNjF0
|
||||
gCyxLJSog63UbY7+0nq3jDk3uHQMGzvFCSEVGhz8lMnJKqvKe7N7hLW8jjA3XPmE
|
||||
s08EXNc+7y34YBC8xB+bBKq2NMh95FEapD20L07KRYuD/tDpkRg74Mya9LSS0Io2
|
||||
/ypdNiIwFPDf+1yU4M55GP4ouQINBFMsfjYBEADVswBSBoFSCYijr9lTY6WoloZC
|
||||
BCVUB7nf8hiysI0TE3PqIduXx9pqGDiFxmxEOMWw55crIu1LhBjatokLFBYXSCQ/
|
||||
xHGJolg8rHdELgr13oKHxqITM7Vrl8OrCdy2PQqtd36BLYXC6G+Waybknbzca7FP
|
||||
zN8FAtPgK4oYSmoUVKSnUeDzWM+MfoZHbmJfoFGibab0QISXilH7nb4zyEiWw0dH
|
||||
K9vLUzboLNBe1QLgFiE0L5r6jAbkMtzgVDF3ag058IZ/NoyyMpZmTNnVyW8wuTWp
|
||||
6eASpiPQ1/Fvi1qDeRoVFFUUcRPusZOKVg0p8i3W22Kch0WlL6wxLNvjYkOGMCXj
|
||||
bQozXq0CwXIUNq2ZJZso9yggmKi1rCaLevAQyMXT4+moUZY8JFSdlSQ7EGalu2Ax
|
||||
zgxOda6wcKxZCfuMUdaoeEjVbcCzhr2MkY7MFanKcRDlz3ZbsZUdezOjFM7VOA1c
|
||||
HaRstaPtefmfFQGMiXrhvTF/tcedHVt4PozO/nMSiDFOr3EHJ+m9vz466vCvnwJ7
|
||||
+Ym/hyYJ2D5Oc51LJzx1AfHqBlZ6p/sHGhvFCuEpxhekpYdT0SIwHqv7Q9dfIc6W
|
||||
LEii5Bd44exNSJQ0M1WdrrN4vUTGBC8GpY4W+1Z3vCnDa+Cest2I8Vjz8rEVNxMt
|
||||
WJDXZbQMfGNCcBbL3QARAQABiQREBBgBCgAPAhsCBQJWDevOBQkEwqEVAinBXSAE
|
||||
GQEKAAYFAlMsfjYACgkQ0kHOvzyrXgYJJg/7BQagkXz4uxLu1wfMHD0ZUrXjVAgN
|
||||
q+mKUDGsCVPI6ULPsPlzptyl6v7NJIR12Kb7YKrTXlmGSBNsyUNaYHXPRn2EYTx7
|
||||
ix+JCx1Kq3eOlOob3HtfKdd3hl0d480XULgE+iSwsb52RwkVinX52+vfOs0D5APm
|
||||
Ewd4+a5QoUZbtCwHvWOKgVDQVr4NQHV6WGtJ+hlNeMRC7DGk+uDmXq1dQFWH4oEc
|
||||
FkONP20vsR1ok2fd71/e/oQFTeDdGjh2Q2istLkrQnaz+7ig+ciXtXfAGF2Kngot
|
||||
XE4sW6vAY5wGWxx6YhhCjzgohPDzxGsvUSy7WPN1cFdqDo4a/66PjXAv8z1OzIbL
|
||||
Fn5AIXftf8RprRn20IZQOOACcZkVPNRzkUR5/y8JoEYbbNMHgZkNNhYH9DRqmXdj
|
||||
nTPYEl3McZcLKwfcEoj9+mGOFUrZSKNHiUdT0IGW43dMqMMKiki1sLHX4kxlVtSX
|
||||
gXzteZiOEby0corySfd9pqxyQetCPWft+yDUMAX/Ax1u5+4bBsD5qzm4MFfcM393
|
||||
A25rwou8Bq4RMWmhKQhzJXG4DnBlgrhJeg44s51ucpfY0PGfYFe5MRGACRg8ji6/
|
||||
vZe/yU8wue60BUtTdjp01n51Bb9mZTJzSVjCkg7f7FH9hdyTgJljLxPLuu/e0f+o
|
||||
qS7boQX4G32X6kUJEGfs5WBbzxNGoLUP/26Fi5umtFoJxTstqXFqla5/8rQ69nQJ
|
||||
6UPc6j/FLvJKRGyd9aP/lu3aKWG6CAm6oJR/7msAMFDbPl4irzQqCtTWGr5ciAB1
|
||||
6nimqyQYaPnqo2sgKGVlgMlwJ24FzfDQD2HBVyvYvW2NWG1C8cJ3gmG4rX28xD28
|
||||
63II0KPQH8AqVb8Vsb2FYQUx0L8ODqL00ZwqIVmE3kivObyiNZEaFK7ywYfI/ml/
|
||||
wukA5k4qO7HpPpY+OgWZ4x2HjOL+LyT8A4tgPKohbatlLzxfMi5qNbdina1+lqGI
|
||||
93Od9Vm0qitT0XKjZekJ0iHx6BlHPLa53y3iHvqfoWZnAc3MvqVaVBv8i5wLrTI6
|
||||
Oc/DgBPcCqvoumvBVkz4wSkJPmkqB1s8b3zFVtrguVioq2g4vz+5j+7CkriFhIuM
|
||||
21a99OdWomU1/RROnIvrSpFg2Un8dq6Ewi5eGsFdiiB5doCG8OYOCF/h+8+wtD+Z
|
||||
ylabsqd+eJEB66MHaPUhzPw8nOHa5nw81BxZzOQw2zsSKAIFONniUMLQRO3/FgXL
|
||||
uI7qVyBkzq0goM5M3Na4fmxTSN08HvW4+dEB/aAgssP0NXh0/J6lOeMJvW8kVVTJ
|
||||
jBAwsKT2ocd9LXRqAvz8cGrj22FquwvT+C+vX/65HfGhIcBk/8aiMaYV3tiHeiBd
|
||||
c6KVsmGx2CeMiQRbBBgBCgAmAhsCFiEEeEDnYQ8ouQR1NUnXZ+zlYFvPE0YFAmiD
|
||||
hxMFCRmC590CKcFdIAQZAQoABgUCUyx+NgAKCRDSQc6/PKteBgkmD/sFBqCRfPi7
|
||||
Eu7XB8wcPRlSteNUCA2r6YpQMawJU8jpQs+w+XOm3KXq/s0khHXYpvtgqtNeWYZI
|
||||
E2zJQ1pgdc9GfYRhPHuLH4kLHUqrd46U6hvce18p13eGXR3jzRdQuAT6JLCxvnZH
|
||||
CRWKdfnb6986zQPkA+YTB3j5rlChRlu0LAe9Y4qBUNBWvg1AdXpYa0n6GU14xELs
|
||||
MaT64OZerV1AVYfigRwWQ40/bS+xHWiTZ93vX97+hAVN4N0aOHZDaKy0uStCdrP7
|
||||
uKD5yJe1d8AYXYqeCi1cTixbq8BjnAZbHHpiGEKPOCiE8PPEay9RLLtY83VwV2oO
|
||||
jhr/ro+NcC/zPU7MhssWfkAhd+1/xGmtGfbQhlA44AJxmRU81HORRHn/LwmgRhts
|
||||
0weBmQ02Fgf0NGqZd2OdM9gSXcxxlwsrB9wSiP36YY4VStlIo0eJR1PQgZbjd0yo
|
||||
wwqKSLWwsdfiTGVW1JeBfO15mI4RvLRyivJJ932mrHJB60I9Z+37INQwBf8DHW7n
|
||||
7hsGwPmrObgwV9wzf3cDbmvCi7wGrhExaaEpCHMlcbgOcGWCuEl6DjiznW5yl9jQ
|
||||
8Z9gV7kxEYAJGDyOLr+9l7/JTzC57rQFS1N2OnTWfnUFv2ZlMnNJWMKSDt/sUf2F
|
||||
3JOAmWMvE8u6797R/6ipLtuhBfgbfZfqRQkQZ+zlYFvPE0bn+A//b7kVBYGBP7K5
|
||||
sZsyl0wbSy6qR1KqZi/yge8FPlQaj1jwkvr0P45yRvxw4SgUEUEnuSOrwf0Iugo6
|
||||
nxqLNdl6OWeJPi8zqgSVnAcuedJBJ0NOtpfKKqaE679VwcWcVvGlGUYMOBk1Ys5W
|
||||
2IHN9ujbMq1s2YtX23zo6+eS3eK3ApH/m9zI7n2UwTCm7G2o0rPueD8AvkVuB5ny
|
||||
ur9dtm6mPz1T7/JFXfYsBtja8O1w+2OKMLIhTGOcBu96pUN4mwBXjP1dWojOiJWZ
|
||||
CZl0XoVh5vFb2mS/gf3utynKnEUIerfnOizAoiFpI7sUm9U2myWaCmEmDZnyV5ip
|
||||
yNgZ/2qsyHw/BW1V4ythXhswrKHmpw7IYXTXHKKz5zbE3O+ERAz/oEZpyx+jQMFF
|
||||
YZSj4dOXIFOQnY8bjhN2z34TLL+DBqWxbyjWEwojJduHf3Bdd44fqFWAmQYIV1IP
|
||||
KsSsIvl6hLpBJf5Oyv5VhurM9yOnEsleGgFIIcj1iMWlRTDHGqA5qOuUa/55INRV
|
||||
FiKdvw+cLm25H21y3tOCbliGowTBdjDiP80CfLCx66BGk1aWoOvAA2SdpiN8/WyS
|
||||
eUcUiEq3fjbPrvYi+hUa2AttvOdsvVbfQKa/GcI1lu2tFA0JZqphLKyIaRjBq69R
|
||||
bc5ucGN3t5b/iDrKyTcPc8cC1IFa1Mc=
|
||||
=uM54
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
@@ -99,6 +99,7 @@ url('/<lang:lang>/download/firefox', 'downloads.downloads_firefox')
|
||||
url('/<lang:lang>/download/config', 'downloads.downloads_config')
|
||||
url('/<lang:lang>/download/lab', 'downloads.downloads_lab')
|
||||
url('/<lang:lang>/download/mac', 'downloads.downloads_mac')
|
||||
url('/<lang:lang>/download/hashes.json', 'downloads.downloads_hashes')
|
||||
url('/<lang:lang>/download/<string:version>/<path:file>/mirrors', 'downloads.downloads_select')
|
||||
url('/<lang:lang>/download/<string:version>/<string:net>/any/<path:file>/download', 'downloads.downloads_redirect', defaults={'protocol': None, 'domain': None})
|
||||
url('/<lang:lang>/download/<string:version>/<string:net>/<string:protocol>/any/<path:file>/download', 'downloads.downloads_redirect', defaults={'domain': None})
|
||||
|
Reference in New Issue
Block a user