prop 144 updates

This commit is contained in:
zzz
2019-04-06 16:36:57 +00:00
parent 5a18dd1191
commit 23cd9a41e8

View File

@@ -5,7 +5,7 @@ ECIES-X25519-AEAD-Ratchet
:author: zzz :author: zzz
:created: 2018-11-22 :created: 2018-11-22
:thread: http://zzz.i2p/topics/2639 :thread: http://zzz.i2p/topics/2639
:lastupdated: 2019-04-03 :lastupdated: 2019-04-06
:status: Open :status: Open
.. contents:: .. contents::
@@ -186,16 +186,15 @@ Existing I2P router implementations will require implementations for
the following standard cryptographic primitives, the following standard cryptographic primitives,
which are not required for current I2P protocols: which are not required for current I2P protocols:
1) ECIES (but this is essentially X25519) - ECIES (but this is essentially X25519)
- Elligator2
Existing I2P router implementations that have not yet implemented NTCP2 (Proposal 111) Existing I2P router implementations that have not yet implemented NTCP2 (Proposal 111)
will also require implementations for: will also require implementations for:
1) X25519 key generation and DH - X25519 key generation and DH
- AEAD_ChaCha20_Poly1305 (abbreviated as ChaChaPoly below)
2) AEAD_ChaCha20_Poly1305 (abbreviated as ChaChaPoly below) - HKDF
3) HKDF
Detailed Proposal Detailed Proposal
@@ -448,8 +447,8 @@ Alice-Bob new session message:
- 3 byte I2NP block overhead ? - 3 byte I2NP block overhead ?
- 16 byte Poly1305 tag - 16 byte Poly1305 tag
Total: Total:
212 bytes 212 bytes
{% endhighlight %} {% endhighlight %}
Bob-Alice existing session message: Bob-Alice existing session message:
@@ -590,6 +589,74 @@ Multicast
TBD TBD
Definitions
-----------
We define the following functions corresponding to the cryptographic building blocks used.
ZEROLEN
zero-length byte array
CSRNG(n)
n-byte output from a cryptographically-secure random number generator.
H(p, d)
SHA-256 hash function that takes a personalization string p and data d, and
produces an output of length 32 bytes.
Use SHA-256 as follows::
H(p, d) := SHA-256(p || d)
STREAM
The ChaCha20/Poly1305 AEAD as specified in [RFC-7539]_.
S_KEY_LEN = 32 and S_IV_LEN = 12.
ENCRYPT(k, n, plaintext, ad)
Encrypts plaintext using the cipher key k, and nonce n which MUST be unique for
the key k.
Associated data ad is optional.
Returns a ciphertext that is the size of the plaintext + 16 bytes for the HMAC.
The entire ciphertext must be indistinguishable from random if the key is secret.
DECRYPT(k, n, ciphertext, ad)
Decrypts ciphertext using the cipher key k, and nonce n.
Associated data ad is optional.
Returns the plaintext.
DH
X25519 public key agreement system. Private keys of 32 bytes, public keys of 32
bytes, produces outputs of 32 bytes. It has the following
functions:
GENERATE_PRIVATE()
Generates a new private key.
DERIVE_PUBLIC(privkey)
Returns the public key corresponding to the given private key.
GENERATE_PRIVATE_ELG2()
Generates a new private key suitable for Elligator2.
DERIVE_PUBLIC_ELG2(privkey)
Returns the Elligator2 public key corresponding to the given private key (inverse mapping).
MAP_PUBLIC_ELG2(pubkey)
Returns the public key corresponding to the given Elligator2 public key.
DH(privkey, pubkey)
Generates a shared secret from the given private and public keys.
HKDF(salt, ikm, info, n)
A cryptographic key derivation function which takes some input key material ikm (which
should have good entropy but is not required to be a uniformly random string), a salt
of length 32 bytes, and a context-specific 'info' value, and produces an output
of n bytes suitable for use as key material.
Use HKDF as specified in [RFC-5869]_, using the HMAC hash function SHA-256
as specified in [RFC-2104]_. This means that SALT_LEN is 32 bytes max.
1) Message format 1) Message format
----------------- -----------------
@@ -742,9 +809,8 @@ Some recommended strategies include:
1a) New session format 1a) New session format
---------------------- ----------------------
Public key (32 bytes) New Session One Time Public key (32 bytes)
Nonce (8 bytes) Encrypted data and MAC (remaining bytes)
Encrypted data and MAC (see section 3 below)
Format Format
@@ -757,28 +823,12 @@ Encrypted:
+----+----+----+----+----+----+----+----+ +----+----+----+----+----+----+----+----+
| | | |
+ + + +
| New Session Public Key | | New Session One Time Public Key |
+ + + +
| | | |
+ + + +
| | | |
+----+----+----+----+----+----+----+----+ +----+----+----+----+----+----+----+----+
| Nonce 8 bytes |
+----+----+----+----+----+----+----+----+
| |
+ +
| ChaCha20 encrypted data |
+ +
| |
+ +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| Poly1305 Message Authentication Code |
+ (MAC) +
| 16 bytes |
+----+----+----+----+----+----+----+----+
| | | |
+ + + +
| ChaCha20 encrypted data | | ChaCha20 encrypted data |
@@ -794,64 +844,156 @@ Encrypted:
Public Key :: 32 bytes, little endian, cleartext Public Key :: 32 bytes, little endian, cleartext
Nonce :: 8 bytes, little endian? cleartext encrypted data :: remaining data minus 16 bytes
encrypted data 1 :: 55 bytes MAC :: Poly1305 message authentication code, 16 bytes
MAC 1 :: Poly1305 message authentication code, 16 bytes
encrypted data 2 :: Same size as plaintext data, Size varies
MAC 2 :: Poly1305 message authentication code, 16 bytes
{% endhighlight %} {% endhighlight %}
Decrypted data 1: Decrypted data
``````````````
See AEAD section below.
Encrypted length is 71 bytes.
Decrypted length is 55 bytes.
Contents must be the following blocks in the following order:
================================== ============= ============
Payload Block Type Type Number Block Length
================================== ============= ============
Options 5 9
Message Number 6 9
Next Key 7 37
================================== ============= ============
Block Total 55
HMAC 16
Total 71
================================== ============= ============
Decrypted data 2:
See AEAD section below. See AEAD section below.
Encrypted length is the remainder of the data. Encrypted length is the remainder of the data.
Decrypted length is 16 less than the encrypted length. Decrypted length is 16 less than the encrypted length.
All types are supported. All block types are supported.
Typical contents include the following blocks:
================================== ============= ============
Payload Block Type Type Number Block Length
================================== ============= ============
DateTime 0 7
I2NP Message 3 varies
Options 5 9
Message Number 6 9
Next Key 7 37
ACK Request 9 varies
Padding 254 varies
================================== ============= ============
DateTime Message Contents
~~~~~~~~~~~~~~~~~~~~~~~~~
The current time.
I2NP Message Contents
~~~~~~~~~~~~~~~~~~~~~
The I2NP message sent.
Options Contents
~~~~~~~~~~~~~~~~
- STL = 8
Message Number Contents
~~~~~~~~~~~~~~~~~~~~~~~
- Key ID = 0
- PN = 0
- N starts with 0, incremented with every new session message sent with this key
Next Key Contents
~~~~~~~~~~~~~~~~~
- Key ID = 0
- Key = Alice's first ratchet public key rapk (See KDF for part 2 below),
remains constant for every new session message for this session
ACK Request Contents
~~~~~~~~~~~~~~~~~~~~
Delivery instructions for the ack.
Padding Contents
~~~~~~~~~~~~~~~~
As desired.
KDF for Encrypted Contents
KDF ``````````````````````````
```
.. raw:: html .. raw:: html
{% highlight lang='text' %} {% highlight lang='text' %}
See message key ratchet below. // Bob's X25519 static keys
// bpk is published in leaseset
bsk = GENERATE_PRIVATE()
bpk = DERIVE_PUBLIC(bsk)
// Alice's X25519 one-time-use ephemeral keys
ask = GENERATE_PRIVATE_ELG2()
// eapk is sent in cleartext in the
// beginning of the new session message
eapk = DERIVE_PUBLIC_ELG2(ask)
apk = MAP_PUBLIC_ELG2(eapk)
INITIAL_ROOT_KEY = SHA256("144-ECIES-X25519-AEAD-Ratchet")
sharedSecret = DH(ask, bpk) = DH(bsk, apk)
// ChaChaPoly parameters to encrypt/decrypt part 1
k = HKDF(INITIAL_ROOT_KEY, sharedSecret, "NewSessionTmpKey", 32)
n = 0
ad = SHA-256(eapk)
{% endhighlight %}
KDF for Ratchets
````````````````
.. raw:: html
{% highlight lang='text' %}
// Bob's X25519 static keys
// bpk is published in leaseset
bsk = GENERATE_PRIVATE()
bpk = DERIVE_PUBLIC(bsk)
// Alice's first ratchet X25519 ephemeral keys
rask = GENERATE_PRIVATE()
// rapk is sent encrypted in part 1
// of the new session message
rapk = DERIVE_PUBLIC(rask)
INITIAL_ROOT_KEY = SHA256("144-ECIES-X25519-AEAD-Ratchet")
sharedSecret = DH(rask, bpk) = DH(bsk, rapk)
// KDF_RK(rk, dh_out)
keydata = HKDF(INITIAL_ROOT_KEY, sharedSecret, "FirstRatchetStep", 64)
nextRootKey = keydata[0:31]
ck = keydata[32:63]
// KDF_CK(ck, constant)
CONSTANT = SHA256("KDF_CK_constant")
keydata[0] = HKDF(ck, CONSTANT, "DeriveFirstChain", 64)
chainKey[0] = keydata[0:31]
k[0] = keydata[32:63]
// repeat as necessary to get to k[n]
keydata[n] = HKDF(chainKey[n-1], CONSTANT, "DeriveFirstChain", 64)
chainKey[n] = keydata[0:31]
k[n] = keydata[32:63]
// ChaChaPoly parameters to encrypt/decrypt part 2
n = N from message number block (type 6) in part 1
k = k[n]
ad = ZEROLEN
Key: KDF TBD
IV: As published in a LS2 property?
Nonce: From header
{% endhighlight %} {% endhighlight %}
@@ -886,11 +1028,6 @@ Issues
- Obfuscation of cleartext key? We could do Elligator 2 but that's expensive. - Obfuscation of cleartext key? We could do Elligator 2 but that's expensive.
- Do we need a nonce? Does it need to be 8 bytes? 4?
- IV is in the LS2 property? Alternative: Send a 16 byte IV instead of 8 byte nonce,
and use a nonce of 0.
1b) Existing session format 1b) Existing session format
@@ -1067,16 +1204,16 @@ Inputs to the encryption/decryption functions:
{% highlight lang='dataspec' %} {% highlight lang='dataspec' %}
k :: 32 byte cipher key, as generated from KDF k :: 32 byte cipher key, as generated from KDF
nonce :: Counter-based nonce, 12 bytes. n :: Counter-based nonce, 12 bytes.
Starts at 0 and incremented for each message. Starts at 0 and incremented for each message.
First four bytes are always zero. First four bytes are always zero.
In new session message: In new session message:
Last eight bytes are the nonce from the message header. Last eight bytes are the nonce from the message header.
In existing session message: In existing session message:
Last eight bytes are the message number (N), little-endian encoded. Last eight bytes are the message number (N), little-endian encoded.
Maximum value is 2**64 - 2. Maximum value is 2**64 - 2.
Session must be ratcheted before N reaches that value. Session must be ratcheted before N reaches that value.
The value 2**64 - 1 must never be used. The value 2**64 - 1 must never be used.
ad :: In new session message: ad :: In new session message:
Associated data, 32 bytes. Associated data, 32 bytes.
@@ -1138,7 +1275,8 @@ Notes
AEAD Error Handling AEAD Error Handling
``````````````````` ```````````````````
TBD All received data that fails the AEAD verification must be discarded.
No response is returned.
Justification Justification
@@ -1154,7 +1292,8 @@ Notes
Issues Issues
`````` ``````
We may need a different AEAD with a larger nonce that's resistant to nonce reuse, Avoid using random nonces. If we do need random nonces,
we may need a different AEAD with a larger nonce that's resistant to nonce reuse,
so we can use random nonces. (SIV?) so we can use random nonces. (SIV?)
@@ -1404,8 +1543,9 @@ so the max unencrypted data is 65519 bytes.
~ . . . ~ ~ . . . ~
blk :: 1 byte blk :: 1 byte
0-2 reserved (used in NTCP2) 0 datetime
3 for I2NP message (Garlic Message only) 1-2 reserved
3 I2NP message (Garlic Message only)
4 termination 4 termination
5 options 5 options
6 message number and previous message number (ratchet) 6 message number and previous message number (ratchet)
@@ -1431,21 +1571,16 @@ so the max unencrypted data is 65519 bytes.
Block Ordering Rules Block Ordering Rules
```````````````````` ````````````````````
In first decrypted part of the new session message, In the new session message,
the following three blocks are required, in the following order: the following blocks are required, in the following order:
- Options (type 5) (must be total length = 9) - Options (type 5) (must be total length = 9)
- Message Number (type 6) - Message Number (type 6)
- New Key (type 7) - New Key (type 7)
No other blocks are allowed. Other allowed blocks:
In second decrypted part of the new session message, - I2NP message (type 3)
three blocks are required, and padding is optional, in the following order:
- Message Number (type 6)
- New Key (type 7)
- I2NP message (type 3) (one or more)
- Padding (type 254) - Padding (type 254)
No other blocks are allowed. No other blocks are allowed.
@@ -1463,6 +1598,26 @@ a single frame, but it is not prohibited.
DateTime
````````
Timestamp for replay prevention:
.. raw:: html
{% highlight lang='dataspec' %}
+----+----+----+----+----+----+----+
| 0 | 4 | timestamp |
+----+----+----+----+----+----+----+
blk :: 0
size :: 2 bytes, big endian, value = 4
timestamp :: Unix timestamp, unsigned seconds.
Wraps around in 2106
{% endhighlight %}
I2NP Message I2NP Message
```````````` ````````````
@@ -1553,9 +1708,13 @@ Additional reasons listed are for consistency, logging, debugging, or if policy
Options Options
``````` ```````
Pass updated options. Pass updated options.
Options include: TBD. Options include various parameters for the session.
Options block will be variable length. In a new session message, the options block is fixed length,
nine bytes, as more_options is not present.
In an existing session message, the options block may be variable length,
nine or more bytes, as more_options may be present.
.. raw:: html .. raw:: html
@@ -1572,11 +1731,11 @@ Options block will be variable length.
+----+----+----+----+----+----+----+----+ +----+----+----+----+----+----+----+----+
blk :: 5 blk :: 5
size :: 2 bytes, big endian, size of options to follow, TBD bytes minimum size :: 2 bytes, big endian, size of options to follow, 6 bytes minimum
STL :: Session tag length (default 8), min and max TBD STL :: Session tag length (default 8), min and max TBD
OTW :: Outbound Session tag window (max lookahead) OTW :: Outbound Session tag window (max lookahead)
STimeout :: Session idle timeout STimeout :: Session idle timeout
MITW :: Max Inbound Session tag window (max lookahead) MITW :: Max Inbound Session Tag window (max lookahead)
flg :: 1 byte flags flg :: 1 byte flags
bit order: 76543210 bit order: 76543210
bit 0: 1 to request a ratchet (new key), 0 if not bit 0: 1 to request a ratchet (new key), 0 if not
@@ -1598,9 +1757,10 @@ Options Notes
Options Issues Options Issues
`````````````` ``````````````
- Options format is TBD. - more_options format is TBD.
- Options negotiation is TBD. - Options negotiation is TBD.
- Padding parameters also? - Padding parameters also?
- Is 255 big enough for max MITW?
Message Numbers Message Numbers
@@ -1638,7 +1798,8 @@ Notes
- N is not strictly needed in an existing session message, as it's associated with the Session Tag - N is not strictly needed in an existing session message, as it's associated with the Session Tag
- This is similar to what Signal does, but in Signal, PN and N are in the header. - PN and N are as defined in Signal.
This is similar to what Signal does, but in Signal, PN and N are in the header.
Here, they're in the encrypted message body. Here, they're in the encrypted message body.
- Key ID can be just an incrementing counter. - Key ID can be just an incrementing counter.
@@ -1677,7 +1838,6 @@ at the beginning.
key ID :: 2 bytes, big endian, used for ack key ID :: 2 bytes, big endian, used for ack
Public Key :: The next public key, 32 bytes, little endian Public Key :: The next public key, 32 bytes, little endian
TBD :: Format TBD
{% endhighlight %} {% endhighlight %}
@@ -1814,6 +1974,8 @@ Issues
- Is the next public key the right thing to sign? - Is the next public key the right thing to sign?
- Use alice's static pubkey instead?
Padding Padding
@@ -1958,6 +2120,11 @@ TODO
References References
========== ==========
.. [Elligator2]
https://elligator.cr.yp.to/elligator-20130828.pdf
https://www.imperialviolet.org/2013/12/25/elligator.html
See also OBFS4 code
.. [Prop111] .. [Prop111]
{{ proposal_url('111') }} {{ proposal_url('111') }}