proposal 152 updates

This commit is contained in:
zzz
2019-07-19 12:39:50 +00:00
parent 9b68d0a887
commit 8520beb51f

View File

@ -6,7 +6,7 @@ ECIES Tunnels
:author: chisana :author: chisana
:created: 2019-07-04 :created: 2019-07-04
:thread: http://zzz.i2p/topics/2737 :thread: http://zzz.i2p/topics/2737
:lastupdated: 2019-07-18 :lastupdated: 2019-07-19
:status: Open :status: Open
.. contents:: .. contents::
@ -24,7 +24,8 @@ Specifications for how to handle mixed tunnel hops are provided.
No changes will be made to the format, processing, or encryption of ElGamal hops. No changes will be made to the format, processing, or encryption of ElGamal hops.
All ElGamal routers are treated as though running without changes from this document. ElGamal tunnel creators will need to create ephemeral X25519 keypairs per-hop, and
follow this spec for creating tunnels containing ECIES hops.
The proposal is split into two sections: The proposal is split into two sections:
@ -90,9 +91,12 @@ bytes 0-3: tunnel ID to receive messages as, nonzero
byte 72: flags byte 72: flags
bytes 73-76: request time (in hours since the epoch, rounded down) bytes 73-76: request time (in hours since the epoch, rounded down)
bytes 77-80: next message ID bytes 77-80: next message ID
bytes 81-464: tunnel build options / random padding
{% endhighlight %} {% endhighlight %}
The tunnel build options block will be defined by [Tunnel-Build-Options]_.
Request Record Spec Encrypted (ECIES) Request Record Spec Encrypted (ECIES)
````````````````````````````````````` `````````````````````````````````````
@ -102,8 +106,7 @@ Request Record Spec Encrypted (ECIES)
bytes 0-15: hop's truncated identity hash bytes 0-15: hop's truncated identity hash
bytes 16-47: sender's ephemeral public key bytes 16-47: sender's ephemeral public key
bytes 48-128: ChaChaPoly AEAD encrypted build request record bytes 48-511: ChaChaPoly AEAD encrypted BuildRequestRecord
bytes 129-511: Random padding
bytes 512-527: Poly1305 MAC bytes 512-527: Poly1305 MAC
{% endhighlight %} {% endhighlight %}
@ -123,11 +126,8 @@ Bit order: 76543210 (bit 7 is MSB)
bit 7: if set, allow messages from anyone bit 7: if set, allow messages from anyone
bit 6: if set, allow messages to anyone, and send the reply to the bit 6: if set, allow messages to anyone, and send the reply to the
specified next hop in a Tunnel Build Reply Message specified next hop in a Tunnel Build Reply Message
bit 5: if set, ChaCha20 reply encryption selected (ECIES build record), bit 5: if set, only ECIES hops in the tunnel, use Blowfish+ChaCha20 layer encryption
also indicates next hop is ECIES bits 4-0: Undefined, must set to 0 for compatibility with future options
AES256/CBC (ElGamal) otherwise
bit 4: if set, only ECIES hops in the tunnel, use Blowfish+ChaCha20 layer encryption
bits 3-0: Undefined, must set to 0 for compatibility with future options
{% endhighlight %} {% endhighlight %}
@ -142,10 +142,12 @@ Reply Record Spec Unencrypted (ECIES)
{% highlight lang='dataspec' %} {% highlight lang='dataspec' %}
bytes 0: Reply byte bytes 0: Reply byte
bytes 1-511: Random padding bytes 1-511: Tunnel Build Options / Random padding
{% endhighlight %} {% endhighlight %}
For options formatting refer to the [Tunnel-Build-Options]_ spec.
Reply flags for ECIES reply records should use the following values to avoid fingerprinting: Reply flags for ECIES reply records should use the following values to avoid fingerprinting:
- 0x00 (accept) - 0x00 (accept)
@ -189,17 +191,11 @@ Symmetric cryptography preprocessing will run in the same way:
- once by the hop - once by the hop
- once on final reply processing - once on final reply processing
When mixed routers are hops in the same tunnel, and the current hop is ECIES, When mixed tunnels are used, tunnel creators will need to base the symmetric encryption
it will check if reply encryption flag is set (indicating ChaCha20). of BuildRequestRecord on the current and previous hop's encryption type.
If the current hop is an ECIES hop, and ChaCha20 reply encryption is selected, Each hop will use it's own encryption type for encrypting BuildReplyRecords, and the other
the reply key is used to ChaCha20 "decrypt" its reply and other records. records in the VariableTunnelBuildMessage (VTBM).
If the current hop is an ElGamal hop, the reply encryption bit is ignored,
and the reply key is used to AES256/CBC "decrypt" its reply and other records.
This means later hops in the tunnel are preprocessed using a mix of ChaCha20
and AES256/CBC, using the reply key of preceding hops.
On the reply path, the endpoint (sender) will need to undo the [Multiple-Encryption]_, using each hop's reply key. On the reply path, the endpoint (sender) will need to undo the [Multiple-Encryption]_, using each hop's reply key.
@ -207,15 +203,17 @@ As a clarifying example, let's look at an outbound tunnel w/ ECIES surrounded by
- Sender (OBGW) -> ElGamal (H1) -> ECIES (H2) -> ElGamal (H3) - Sender (OBGW) -> ElGamal (H1) -> ECIES (H2) -> ElGamal (H3)
All records are in their encrypted state (using ElGamal or ECIES). All BuildRequestRecords are in their encrypted state (using ElGamal or ECIES).
AES256/CBC cipher, when used, is still used for each record, without chaining across multiple records. AES256/CBC cipher, when used, is still used for each record, without chaining across multiple records.
Likewise, ChaCha20 will be used to encrypt each record, not streaming across the entire VTBM.
The request records are preprocessed by the Sender (OBGW): The request records are preprocessed by the Sender (OBGW):
- H3's record is "encrypted" using: - H3's record is "encrypted" using:
- H2's reply key (AES256/CBC) - H2's reply key (ChaCha20)
- H1's reply key (AES256/CBC) - H1's reply key (AES256/CBC)
- H2's record is "encrypted" using: - H2's record is "encrypted" using:
@ -226,8 +224,6 @@ The request records are preprocessed by the Sender (OBGW):
Only H2 checks the reply encryption flag, and sees its followed by AES256/CBC. Only H2 checks the reply encryption flag, and sees its followed by AES256/CBC.
H3 checks the flags, sees it is an OBEP (bit 6 set), and ignores the reply encryption bit.
After being processed by each hop, the records are in a "decrypted" state: After being processed by each hop, the records are in a "decrypted" state:
- H3's record is "decrypted" using: - H3's record is "decrypted" using:
@ -237,15 +233,15 @@ After being processed by each hop, the records are in a "decrypted" state:
- H2's record is "decrypted" using: - H2's record is "decrypted" using:
- H3's reply key (AES256/CBC) - H3's reply key (AES256/CBC)
- H2's reply key (AES256/CBC) - H2's reply key (ChaCha20-Poly1305)
- H1's record is "decrypted" using: - H1's record is "decrypted" using:
- H3's reply key (AES256/CBC) - H3's reply key (AES256/CBC)
- H2's reply key (AES256/CBC) - H2's reply key (ChaCha20)
- H1's reply key (AES256/CBC) - H1's reply key (AES256/CBC)
When there are no inbound tunnels at startup, the Sender (IBEP) postprocesses the reply: The tunnel creator, a.k.a. Inbound Endpoint (IBEP), postprocesses the reply:
- H3's record is "encrypted" using: - H3's record is "encrypted" using:
@ -254,76 +250,19 @@ When there are no inbound tunnels at startup, the Sender (IBEP) postprocesses th
- H2's record is "encrypted" using: - H2's record is "encrypted" using:
- H3's reply key (AES256/CBC) - H3's reply key (AES256/CBC)
- H2's reply key (AES256/CBC) - H2's reply key (ChaCha20-Poly1305)
- H1's record is "encrypted" using: - H1's record is "encrypted" using:
- H3's reply key (AES256/CBC) - H3's reply key (AES256/CBC)
- H2's reply key (AES256/CBC)
- H1's reply key (AES256/CBC)
If H3 (OBEP) is an ECIES hop, it checks the reply encryption flag for
ChaCha20 (bit 5 set) or AES256/CBC (bit 5 unset).
H2 would also see that the reply encryption flag is set, and "decrypt" its reply
and other records using ChaCha20.
So our example changes to the following hops:
- Sender (OBGW) -> ElGamal (H1) -> ECIES (H2) -> ECIES (H3)
The request records are preprocessed by the Sender (OBGW):
- H3's record is "encrypted" using:
- H2's reply key (ChaCha20)
- H1's reply key (AES256/CBC)
- H2's record is "encrypted" using:
- H1's reply key (AES256/CBC)
- H1's record goes out without symmetric encryption
After being processed by each hop, the records are in a "decrypted" state:
- H3's record is "decrypted" using:
- H3's reply key (ChaCha20)
- H2's record is "decrypted" using:
- H3's reply key (ChaCha20)
- H2's reply key (ChaCha20)
- H1's record is "decrypted" using:
- H3's reply key (ChaCha20)
- H2's reply key (ChaCha20)
- H1's reply key (AES256/CBC)
When there are no inbound tunnels at startup, the Sender (IBEP) postprocesses the reply:
- H3's record is "encrypted" using:
- H3's reply key (ChaCha20)
- H2's record is "encrypted" using:
- H3's reply key (ChaCha20)
- H2's reply key (ChaCha20)
- H1's record is "encrypted" using:
- H3's reply key (ChaCha20)
- H2's reply key (ChaCha20) - H2's reply key (ChaCha20)
- H1's reply key (AES256/CBC) - H1's reply key (AES256/CBC)
Request Record Key, Reply Key, Tunnel Layer Key, and IV Key KDF (ECIES) Request Record Key, Reply Key, Tunnel Layer Key, and IV Key KDF (ECIES)
--------------------------------------------------------------------------------- -----------------------------------------------------------------------
The ``recordKey`` takes the place of the product of the ElGamal exchange. It is used The ``recordKey`` takes the place of the product of the ElGamal exchange. It is used
to AEAD encrypt request and reply records for ECIES hops. to AEAD encrypt request records for ECIES hops.
Below is a description of how to derive the keys previously transmitted in request records. Below is a description of how to derive the keys previously transmitted in request records.
@ -331,7 +270,7 @@ Below is a description of how to derive the keys previously transmitted in reque
{% highlight lang='dataspec' %} {% highlight lang='dataspec' %}
// Sender generates an X25519 ephemeral keypair per VTBM (sesk, sepk) // Sender generates an X25519 ephemeral keypair per ECIES hop in the VTBM (sesk, sepk)
sesk = GENERATE_PRIVATE() sesk = GENERATE_PRIVATE()
sepk = DERIVE_PUBLIC(sesk) sepk = DERIVE_PUBLIC(sesk)
@ -360,42 +299,58 @@ Below is a description of how to derive the keys previously transmitted in reque
{% endhighlight %} {% endhighlight %}
``replyKey``, ``layerKey`` and ``IVKey`` must still be included inside ElGamal records, ``replyKey``, ``layerKey`` and ``IVKey`` must still be included inside ElGamal records,
and can be generated randomly. For ElGamal, the ``recordKey`` is just the result of ElGamal multiplication. and can be generated randomly. For ElGamal, the ``recordKey`` is not needed, since the
tunnel creator can directly encrypt to an ElGamal hop's public key.
Keys are omitted from ECIES records (since they can be derived at the hop). Keys are omitted from ECIES records (since they can be derived at the hop).
Request Record Preprocessing for ECIES Hops BuildRequestRecord Encryption for ECIES Hops
------------------------------------------- --------------------------------------------
.. raw:: html .. raw:: html
{% highlight lang='dataspec' %} {% highlight lang='dataspec' %}
// See record key KDF for key generation // See record key KDF for key generation
(ciphertext, mac) = ChaCha20-Poly1305(msg = unencrypted record, nonce = 0, AD = Sha256(recordKey), key = recordKey) // Repeat for each ECIES hop record in the VTBM
(ciphertext, mac) = ChaCha20-Poly1305(msg = unencrypted record, nonce = 0, AD = Sha256(hop's recordKey), key = hop's recordKey)
encryptedRecord = ciphertext \|\| MAC
// For subsequent records past the initial hop For subsequent records past the initial hop, pre-emptively decrypt for each preceding hop in the tunnel
// nonce = one \+ zero-indexed order of record in the TunnelBuildMessage
symCiphertext = ChaCha20(msg = ciphertext \|\| MAC, nonce, key = replyKey of preceding hop) // If the preceding hop is ECIES:
nonce = one \+ zero-indexed order of record in the VariableTunnelBuildMessage
key = replyKey of preceding hop
symCiphertext = ChaCha20(msg = encryptedRecord, nonce, key)
// If the preceding hop is ElGamal:
IV = reply IV of preceding hop
key = reply key of preceding hop
symCiphertext = AES256/CBC-Decrypt(msg = encryptedRecord, IV, key)
{% endhighlight %} {% endhighlight %}
Request Record Encryption from ElGamal Tunnel Creators Request Record Encryption from ElGamal + ECIES Tunnel Creators
------------------------------------------------------ --------------------------------------------------------------
No changes are made for how ElGamal routers preprocess and encrypt request records. ElGamal tunnel creators will need to generate an ephemeral X25519 keypair for each
ECIES hop in the tunnel, and use scheme above for encrypting their BuildRequestRecord.
ElGamal tunnel creators will use the scheme prior to this spec for encrypting to ElGamal hops.
This means ECIES hops will behave like ElGamal hops in ElGamal created tunnels. ECIES tunnel creators will need to encrypt to the ElGamal hop's public key using the
scheme prior to this spec. ECIES tunnel creators will use the above scheme for encrypting
to ECIES hops.
For ECIES hops to detect ElGamal tunnel creators, trial-decryption is needed. This means that tunnel hops will only see encrypted records from their same encryption type.
It will be necessary to first try decrypting the request record as though it came from an ECIES router. For ElGamal and ECIES tunnel creators, they will generate unique ephemeral X25519 keypairs
per-hop for encrypting to ECIES hops.
If trial-decryption fails, attempt decryption as though from an ElGamal router. **WARNING**: if the same ephemeral keypair is used for more than one hop, it can only be
used for at most **two** hops, and the hops must be **consecutive**.
If the record includes expected fields (keys + IV, flags, etc, and valid Sha256 of preceding data), ElGamal decryption was succesful. **WARNING**: Using the same ephemeral keys for non-consecutive hops, or more than two hops,
allows colluding hops to know they're in the same tunnel, **VERY BAD**!!!
If ElGamal decryption fails, drop the message without reply, or forwarding to next hop.
Reply Record Encryption for ECIES Hops Reply Record Encryption for ECIES Hops
-------------------------------------- --------------------------------------
@ -409,27 +364,14 @@ See [RFC-7539-S4]_ Security Considerations for more information.
{% highlight lang='dataspec' %} {% highlight lang='dataspec' %}
// See reply key KDF for key generation // See reply key KDF for key generation
(ciphertext, MAC) = ChaCha20-Poly1305(msg = reply byte, nonce = 0, AD = Sha256(replyKey), key = replyKey) msg = reply byte \|\| build options \|\| random padding
(ciphertext, MAC) = ChaCha20-Poly1305(msg, nonce = 0, AD = Sha256(replyKey), key = replyKey)
If ChaCha20 reply encryption is set in the request record (flags bit 5 set):
// Use a unique nonce per-record
nonce = one \+ zero-indexed order of record in the VariableTunnelBuildMessage
symCiphertext = ChaCha20(msg = ciphertext \|\| MAC \|\| random padding, nonce, key = replyKey)
// Other request/reply record encryption // Other request/reply record encryption
// Use a unique nonce per-record // Use a unique nonce per-record
nonce = one \+ number of records \+ zero-indexed order of record in the VariableTunnelBuildMessage nonce = one \+ number of records \+ zero-indexed order of record in the VariableTunnelBuildMessage
symCiphertext = ChaCha20(msg = multiple encrypted record, nonce, key = replyKey) symCiphertext = ChaCha20(msg = multiple encrypted record, nonce, key = replyKey)
If AES256/CBC reply encryption is set in the request record (flag bit 5 unset):
// Other request/reply record encryption
msg = multiple encrypted record
key = replyKey
IV = Sha256(replyKey \|\| hop static public key)
symCiphertext = AES256-CBC-Encrypt(msg, key, IV)
{% endhighlight %} {% endhighlight %}
While mixed tunnels are used, reply records are the same size, though the format is different. While mixed tunnels are used, reply records are the same size, though the format is different.
@ -439,7 +381,9 @@ After full transition to ECIES, random padding can be a range of included paddin
When ranged padding is used, random padding will be formatted using the Padding block structure from [ECIES-X25519]_ and [NTCP2]_. When ranged padding is used, random padding will be formatted using the Padding block structure from [ECIES-X25519]_ and [NTCP2]_.
For symmetric encryption by other hops, it's necessary to know full record length (w/ padding) without asymmetric decryption. For symmetric encryption by other hops, it's necessary to know full record length (w/ padding) without asymmetric decryption.
When/if records become variable-length, it may become necessary to include an unencrypted Data block header before each record, TBD. When/if records become variable-length, it may become necessary to include an unencrypted Data block header before each record, TBD.
BuildReplyRecord may or may not need to match BuildRequestRecord length if both are preceded by Data block header, TBD. BuildReplyRecord may or may not need to match BuildRequestRecord length if both are preceded by Data block header, TBD.
Reply Record Encryption for ElGamal Hops Reply Record Encryption for ElGamal Hops
@ -516,7 +460,7 @@ Inbound tunnels:
- Use 8-byte ``tunnelNonce`` given the lifetime of tunnels - Use 8-byte ``tunnelNonce`` given the lifetime of tunnels
- Destroy tunnel before 2^(64/2 - 1) messages: 2^31 = 2,147,483,648 - Destroy tunnel before 2^(64/2 - 1) messages: 2^31 = 2,147,483,648
- Nonce limit in place to avoid Sweet32 attack on Blowfish - Nonce limit in place to avoid [Sweet32]_ attack on [Blowfish]_
- Nonce limit unlikely to ever be reached, given this would be ~3,579,139 msgs/second for 10 minute tunnels - Nonce limit unlikely to ever be reached, given this would be ~3,579,139 msgs/second for 10 minute tunnels
- Nonce cannot be truncated. For shorter nonce, a different method must be used with smaller state space. - Nonce cannot be truncated. For shorter nonce, a different method must be used with smaller state space.
@ -602,7 +546,7 @@ To validate received ``tunnelNonce``, the participant checks against its Bloom f
After validation, the participant: After validation, the participant:
- Blowfish encrypts the ``tunnelNonce`` with its ``IVKey`` - [Blowfish]_ encrypts the ``tunnelNonce`` with its ``IVKey``
- Uses the encrypted ``tunnelNonce`` & its ``layerKey`` to ChaCha20 encrypt the tunnel message(s) - Uses the encrypted ``tunnelNonce`` & its ``layerKey`` to ChaCha20 encrypt the tunnel message(s)
- Sends the tuple {``tunnelId``, encrypted ``tunnelNonce``, ciphertext} to the next hop. - Sends the tuple {``tunnelId``, encrypted ``tunnelNonce``, ciphertext} to the next hop.
@ -634,7 +578,7 @@ For ECIES-only tunnels, the following scheme will be used:
- Validate the received ``tunnelNonce`` against the Bloom filter - Validate the received ``tunnelNonce`` against the Bloom filter
- ChaCha20 decrypt the encrypted data using the received ``tunnelNonce`` & the hop's ``layerKey`` - ChaCha20 decrypt the encrypted data using the received ``tunnelNonce`` & the hop's ``layerKey``
- Blowfish decrypt the ``tunnelNonce`` using the hop's ``IVKey`` to get the preceding ``tunnelNonce`` - [Blowfish]_ decrypt the ``tunnelNonce`` using the hop's ``IVKey`` to get the preceding ``tunnelNonce``
- ChaCha20 decrypt the encrypted data using the decrypted ``tunnelNonce`` & the preceding hop's ``layerKey`` - ChaCha20 decrypt the encrypted data using the decrypted ``tunnelNonce`` & the preceding hop's ``layerKey``
- Repeat for each hop in the tunnel, back to the IBGW - Repeat for each hop in the tunnel, back to the IBGW
@ -663,25 +607,25 @@ Security Analysis for Blowfish+ChaCha20 Tunnel Layer Encryption
Switching from AES256/ECB to ChaCha20 has a number of advantages, and new security considerations. Switching from AES256/ECB to ChaCha20 has a number of advantages, and new security considerations.
The biggest security considerations to account for, are that ChaCha20 nonces must be unique per-message, The biggest security considerations to account for, are that ChaCha20 nonces must be unique per-message,
for the life of the key being used, and Blowfish is susceptible to Sweet32 birthday attacks. for the life of the key being used, and [Blowfish]_ is susceptible to [Sweet32]_ birthday attacks.
Failing to use unique nonces with the same key on different messages breaks ChaCha20. Failing to use unique nonces with the same key on different messages breaks ChaCha20.
Nonce uniqueness is main reason for using an Blowfish, see [RFC-7539-S4]_. Nonce uniqueness is main reason for using an [Blowfish]_, see [RFC-7539-S4]_.
Simple counters cannot be used, since they require syncing for proper decryption. Simple counters cannot be used, since they require syncing for proper decryption.
Syncing the counter can't be guaranteed at the IBEP, without further changes to tunnel protocols. Syncing the counter can't be guaranteed at the IBEP, without further changes to tunnel protocols.
Blowfish is only used for nonce encryption to guarantee unique nonces, and prevent non-consecutive [Blowfish]_ is only used for nonce encryption to guarantee unique nonces, and prevent non-consecutive
hops in the same tunnel from colluding to know they are in the same tunnel. hops in the same tunnel from colluding to know they are in the same tunnel.
The tunnel lifetime of ten minutes and nonce limit of 2^31 messages guarantees that Sweet32 attacks The tunnel lifetime of ten minutes and nonce limit of 2^31 messages guarantees that [Sweet32]_ attacks
are ineffective against Blowfish. Exceeding the limit would require over ~3,579,139 messages/second in each tunnel. are ineffective against Blowfish. Exceeding the limit would require over ~3,579,139 messages/second in each tunnel.
Even if 2^31 messages proves to not be a strict enough limit, we can safely reduce the limit by another power of two, Even if 2^31 messages proves to not be a strict enough limit, we can safely reduce the limit by another power of two,
without ever realistically reaching the limit. without ever realistically reaching the limit.
Even if a Sweet32 attack were successful, an attacker would only gain access to the ``tunnelNonce`` Even if a [Sweet32]_ attack were successful, an attacker would only gain access to the ``tunnelNonce``
for the colliding message, which doesn't break the ChaCha20 encryption. Non-consecutive hops for the colliding message, which doesn't break the ChaCha20 encryption. Non-consecutive hops
would only be able to confirm they are participants in the same tunnel. would only be able to confirm they are participants in the same tunnel.
@ -698,6 +642,34 @@ double-encryption.
The chosen-plaintext producing a recovered IV cannot be used to perform The chosen-plaintext producing a recovered IV cannot be used to perform
a padding-oracle attack against AES256/CBC layer encryption, since duplicate IVs are rejected. a padding-oracle attack against AES256/CBC layer encryption, since duplicate IVs are rejected.
Justification for Blowfish
--------------------------
[Blowfish]_ is needed to symmetrically encrypt ChaCha20 nonces used in tunnel layer encryption. It was chosen for
its 64-bit block size, and ability to symmetrically encrypt without using a nonce.
A 64-bit block size is needed to generate unique nonces for ChaCha20. ChaCha20 has a maximum nonce size of 96-bits,
using the IETF variant. Nonces of smaller sizes can be used, and are padded with zeroes. However, larger nonces, like
the 128-bit AES256/CBC IV cannot safely be truncated, as 96-bit segments may be identical for two otherwise
unique IVs.
HKDF and other hashing functions cannot be used to safely truncate the received IV, since it must be possible
for Inbound Endpoints to recover the IV of preceding hops in the tunnel.
Of the 64-bit ciphers, [Blowfish]_ is the most secure, with the widest support in well-audited cryptography libraries.
Other alternatives like DES and 3DES, are more cumbersome, and weaker in comparison. Despite its comparative strength,
[Blowfish]_ is still vulnerable to [Sweet32]_ attacks. This means that in ~2^32 blocks, there will be a block collision,
allowing for recovery of the nonce from that block. Given the lifetime of tunnels, the restriction on unique received
nonces, and the limit of 2^31 messages, [Blowfish]_ would not vulnerable to [Sweet32]_ in the I2P ECIES Tunnels context.
Realistically, much fewer than 2^29 nonces will ever be seen by any tunnel, since this would be over 894,784 msgs/sec.
For comparison, Google receives ~76,000 searches per second. Even assuming 10 messages per search, a tunnel would have
to be over 100,000 msgs/sec busier than Google. Vanishingly unlikely.
Statistics from: https://www.internetlivestats.com/one-second/
Tunnel Message Overhead for ECIES Tunnel Message Overhead for ECIES
================================= =================================
@ -760,6 +732,9 @@ References
.. [ECIES-X25519] .. [ECIES-X25519]
{{ proposal_url('144') }} {{ proposal_url('144') }}
.. [Tunnel-Build-Options]
{{ proposal_url('143') }}
.. [NTCP2] .. [NTCP2]
https://geti2p.net/spec/ntcp2 https://geti2p.net/spec/ntcp2
@ -775,5 +750,8 @@ References
.. [RFC-7539-S4] .. [RFC-7539-S4]
https://tools.ietf.org/html/rfc7539#section-4 https://tools.ietf.org/html/rfc7539#section-4
.. [SplitMix64] .. [Blowfish]
http://xoshiro.di.unimi.it/splitmix64.c https://www.schneier.com/academic/blowfish/
.. [Sweet32]
https://sweet32.info/