diff --git a/i2p2www/pages/site/docs/index.html b/i2p2www/pages/site/docs/index.html
index 023dc27f..b9d1e041 100644
--- a/i2p2www/pages/site/docs/index.html
+++ b/i2p2www/pages/site/docs/index.html
@@ -1,7 +1,7 @@
{% extends "global/layout.html" %}
{% block title %}{% trans %}Index to Technical Documentation{% endtrans %}{% endblock %}
-{% block lastupdated %}2020-08{% endblock %}
-{% block accuratefor %}0.9.47{% endblock %}
+{% block lastupdated %}2020-11{% endblock %}
+{% block accuratefor %}0.9.48{% endblock %}
{% block content %}
{% trans -%}
Following is an index to the technical documentation for I2P.
@@ -158,7 +158,8 @@ Traditionally used only by Java applications and higher-level APIs.
{{ _('Tunnel building and encryption') }}
{{ _('ElGamal/AES') }} {{ _('for build request encryption') }}
{{ _('ElGamal and AES cryptography details') }}
-{{ _('Tunnel building specification') }}
+{{ _('Tunnel building specification') }} (ElGamal)
+{{ _('Tunnel building specification') }} (ECIES-X25519)
{{ _('Low-level tunnel message specification') }}
{{ _('Unidirectional Tunnels') }}
{{ _('Peer Profiling and Selection in the I2P Anonymous Network') }}
diff --git a/i2p2www/spec/i2np.rst b/i2p2www/spec/i2np.rst
index f80f607b..16f479ce 100644
--- a/i2p2www/spec/i2np.rst
+++ b/i2p2www/spec/i2np.rst
@@ -3,7 +3,7 @@ I2NP Specification
==================
.. meta::
:category: Protocols
- :lastupdated: 2020-10
+ :lastupdated: 2020-11
:accuratefor: 0.9.48
.. contents::
@@ -42,6 +42,8 @@ below.
============== ================================================================
Version Required I2NP Features
============== ================================================================
+ 0.9.48 ECIES-X25519 Build Request/Response records
+
0.9.46 DatabaseLookup flag bit 4 for AEAD reply
0.9.44 X25519 keys in LeaseSet2
@@ -225,16 +227,17 @@ Description
```````````
One Record in a set of multiple records to request the creation of one hop in
the tunnel. For more details see the tunnel overview [TUNNEL-IMPL]_ and the
-tunnel creation specification [TUNNEL-CREATION]_.
+ElGamal tunnel creation specification [TUNNEL-CREATION]_.
-Contents
-````````
+For ECIES-X25519 BuildRequestRecords, see [TUNNEL-CREATION-ECIES].
+
+
+Contents (ElGamal)
+```````````````````
[TunnelId]_ to receive messages on, followed by the [Hash]_ of our
[RouterIdentity]_. After that the [TunnelId]_ and the [Hash]_ of the next
router's [RouterIdentity]_ follow.
-Definition
-``````````
ElGamal and AES encrypted:
.. raw:: html
@@ -397,6 +400,18 @@ Notes
BuildResponseRecord
-------------------
+Description
+```````````
+One Record in a set of multiple records with responses to a build request.
+For more details see the tunnel overview [TUNNEL-IMPL]_ and the
+ElGamal tunnel creation specification [TUNNEL-CREATION]_.
+
+For ECIES-X25519 BuildResponseRecords, see [TUNNEL-CREATION-ECIES].
+
+
+Contents (ElGamal)
+```````````````````
+
.. raw:: html
{% highlight lang='dataspec' %}
@@ -1412,6 +1427,8 @@ TunnelBuild
Notes
`````
+* As of 0.9.48, may also contain ECIES-X25519 BuildRequestRecords, see [TUNNEL-CREATION-ECIES]_.
+
* See also the tunnel creation specification [TUNNEL-CREATION]_.
* The I2NP message ID for this message must be set according to the tunnel
@@ -1434,6 +1451,8 @@ Same format as `TunnelBuildMessage`, with `BuildResponseRecord`s
Notes
`````
+* As of 0.9.48, may also contain ECIES-X25519 BuildResponseRecords, see [TUNNEL-CREATION-ECIES]_.
+
* See also the tunnel creation specification [TUNNEL-CREATION]_.
* The I2NP message ID for this message must be set according to the tunnel
@@ -1468,6 +1487,8 @@ VariableTunnelBuild
Notes
`````
+* As of 0.9.48, may also contain ECIES-X25519 BuildRequestRecords, see [TUNNEL-CREATION-ECIES]_.
+
* This message was introduced in router version 0.7.12, and may not be sent to
tunnel participants earlier than that version.
@@ -1495,6 +1516,8 @@ VariableTunnelBuildReply
Notes
`````
+* As of 0.9.48, may also contain ECIES-X25519 BuildResponseRecords, see [TUNNEL-CREATION-ECIES]_.
+
* This message was introduced in router version 0.7.12, and may not be sent to
tunnel participants earlier than that version.
@@ -1551,6 +1574,9 @@ References
.. [TUNNEL-CREATION]
{{ spec_url('tunnel-creation') }}
+.. [TUNNEL-CREATION-ECIES]
+ {{ spec_url('tunnel-creation-ecies') }}
+
.. [TUNNEL-MSG]
{{ spec_url('tunnel-message') }}
diff --git a/i2p2www/spec/proposals/152-ecies-tunnels.rst b/i2p2www/spec/proposals/152-ecies-tunnels.rst
index a2e96436..988f6305 100644
--- a/i2p2www/spec/proposals/152-ecies-tunnels.rst
+++ b/i2p2www/spec/proposals/152-ecies-tunnels.rst
@@ -6,9 +6,10 @@ ECIES Tunnels
:author: chisana, zzz, orignal
:created: 2019-07-04
:thread: http://zzz.i2p/topics/2737
- :lastupdated: 2020-11-05
- :status: Open
+ :lastupdated: 2020-11-16
+ :status: Closed
:target: 0.9.48
+ :implementedin: 0.9.48
.. contents::
diff --git a/i2p2www/spec/tunnel-creation-ecies.rst b/i2p2www/spec/tunnel-creation-ecies.rst
new file mode 100644
index 00000000..992b20c1
--- /dev/null
+++ b/i2p2www/spec/tunnel-creation-ecies.rst
@@ -0,0 +1,589 @@
+=============================
+ECIES-X25519 Tunnel Creation
+=============================
+
+.. meta::
+ :category: Protocols
+ :lastupdated: 2020-11
+ :accuratefor: 0.9.48
+
+.. contents::
+
+Overview
+========
+
+This document specifies Tunnel Build message encryption
+using crypto primitives introduced by [ECIES-X25519]_.
+It is a portion of the overall proposal
+[Prop156]_ for converting routers from ElGamal to ECIES-X25519 keys.
+This specification is implemented as of release 0.9.48.
+
+For the purposes of transitioning the network from ElGamal + AES256 to ECIES + ChaCha20,
+tunnels with mixed ElGamal and ECIES routers are necessary.
+Specifications for handling mixed tunnel hops are provided.
+No changes will be made to the format, processing, or encryption of ElGamal hops.
+
+ElGamal tunnel creators will generate ephemeral X25519 keypairs per-hop, and
+follow this spec for creating tunnels containing ECIES hops.
+
+This document specifies ECIES-X25519 Tunnel Building.
+For an overview of all changes required for ECIES routers, see proposal 156 [Prop156]_.
+For additional background on the development of this specification, see proposal 152 [Prop152]_.
+
+This format maintains the same size for tunnel build records,
+as required for compatibility. Smaller build records and messages will be
+implemented later - see [Prop157]_.
+
+
+Cryptographic Primitives
+------------------------
+
+The primitives required to implement this specification are:
+
+- AES-256-CBC as in [Cryptography]_
+- STREAM ChaCha20/Poly1305 functions:
+ ENCRYPT(k, n, plaintext, ad) and DECRYPT(k, n, ciphertext, ad) - as in [NTCP2]_ [ECIES-X25519]_ and [RFC-7539]_
+- X25519 DH functions - as in [NTCP2]_ and [ECIES-X25519]_
+- HKDF(salt, ikm, info, n) - as in [NTCP2]_ and [ECIES-X25519]_
+
+Other Noise functions defined elsewhere:
+
+- MixHash(d) - as in [NTCP2]_ and [ECIES-X25519]_
+- MixKey(d) - as in [NTCP2]_ and [ECIES-X25519]_
+
+
+
+Design
+======
+
+Noise Protocol Framework
+------------------------
+
+This specification provides the requirements based on the Noise Protocol Framework
+[NOISE]_ (Revision 34, 2018-07-11).
+In Noise parlance, Alice is the initiator, and Bob is the responder.
+
+It is based on the Noise protocol Noise_N_25519_ChaChaPoly_SHA256.
+This Noise protocol uses the following primitives:
+
+- One-Way Handshake Pattern: N
+ Alice does not transmit her static key to Bob (N)
+
+- DH Function: X25519
+ X25519 DH with a key length of 32 bytes as specified in [RFC-7748]_.
+
+- Cipher Function: ChaChaPoly
+ AEAD_CHACHA20_POLY1305 as specified in [RFC-7539]_ section 2.8.
+ 12 byte nonce, with the first 4 bytes set to zero.
+ Identical to that in [NTCP2]_.
+
+- Hash Function: SHA256
+ Standard 32-byte hash, already used extensively in I2P.
+
+
+Handshake Patterns
+------------------
+
+Handshakes use [Noise]_ handshake patterns.
+
+The following letter mapping is used:
+
+- e = one-time ephemeral key
+- s = static key
+- p = message payload
+
+The build request is identical to the Noise N pattern.
+This is also identical to the first (Session Request) message in the XK pattern used in [NTCP2]_.
+
+
+.. raw:: html
+
+ {% highlight lang='dataspec' %}
+<- s
+ ...
+ e es p ->
+
+{% endhighlight %}
+
+
+Request encryption
+-----------------------
+
+Build request records are created by the tunnel creator and asymmetrically encrypted to the individual hop.
+This asymmetric encryption of request records is currently ElGamal as defined in [Cryptography]_
+and contains a SHA-256 checksum. This design is not forward-secret.
+
+The ECIES design uses the one-way Noise pattern "N" with ECIES-X25519 ephemeral-static DH, with an HKDF, and
+ChaCha20/Poly1305 AEAD for forward secrecy, integrity, and authentication.
+Alice is the tunnel build requestor. Each hop in the tunnel is a Bob.
+
+
+
+Reply encryption
+-----------------------
+
+Build reply records are created by the hops creator and symmetrically encrypted to the creator.
+This symmetric encryption of ElGamal reply records is AES with a prepended SHA-256 checksum.
+and contains a SHA-256 checksum. This design is not forward-secret.
+
+ECIES replies use ChaCha20/Poly1305 AEAD for integrity, and authentication.
+
+
+
+Specification
+=========================
+
+
+
+Build Request Records
+-------------------------------------
+
+Encrypted BuildRequestRecords are 528 bytes for both ElGamal and ECIES, for compatibility.
+
+
+
+
+Request Record Unencrypted
+```````````````````````````````````````
+
+This is the specification of the tunnel BuildRequestRecord for ECIES-X25519 routers.
+Summary of changes:
+
+- Remove unused 32-byte router hash
+- Change request time from hours to minutes
+- Add expiration field for future variable tunnel time
+- Add more space for flags
+- Add Mapping for additional build options
+- AES-256 reply key and IV are not used for the hop's own reply record
+- Unencrypted record is longer because there is less encryption overhead
+
+
+The request record does not contain any ChaCha reply keys.
+Those keys are derived from a KDF. See below.
+
+All fields are big-endian.
+
+Unencrypted size: 464 bytes
+
+.. raw:: html
+
+ {% highlight lang='dataspec' %}
+
+bytes 0-3: tunnel ID to receive messages as, nonzero
+ bytes 4-7: next tunnel ID, nonzero
+ bytes 8-39: next router identity hash
+ bytes 40-71: AES-256 tunnel layer key
+ bytes 72-103: AES-256 tunnel IV key
+ bytes 104-135: AES-256 reply key
+ bytes 136-151: AES-256 reply IV
+ byte 152: flags
+ bytes 153-155: more flags, unused, set to 0 for compatibility
+ bytes 156-159: request time (in minutes since the epoch, rounded down)
+ bytes 160-163: request expiration (in seconds since creation)
+ bytes 164-167: next message ID
+ bytes 168-x: tunnel build options (Mapping)
+ bytes x-x: other data as implied by flags or options
+ bytes x-463: random padding
+
+{% endhighlight %}
+
+The flags field is the same as defined in [Tunnel-Creation]_ and contains the following::
+
+ Bit order: 76543210 (bit 7 is MSB)
+ bit 7: if set, allow messages from anyone
+ bit 6: if set, allow messages to anyone, and send the reply to the
+ specified next hop in a Tunnel Build Reply Message
+ bits 5-0: Undefined, must set to 0 for compatibility with future options
+
+Bit 7 indicates that the hop will be an inbound gateway (IBGW). Bit 6
+indicates that the hop will be an outbound endpoint (OBEP). If neither bit is
+set, the hop will be an intermediate participant. Both cannot be set at once.
+
+The request exipration is for future variable tunnel duration.
+For now, the only supported value is 600 (10 minutes).
+
+The tunnel build options is a Mapping structure as defined in [Common]_.
+This is for future use. No options are currently defined.
+If the Mapping structure is empty, this is two bytes 0x00 0x00.
+The maximum size of the Mapping (including the length field) is 296 bytes,
+and the maximum value of the Mapping length field is 294.
+
+
+
+Request Record Encrypted
+`````````````````````````````````````
+
+All fields are big-endian except for the ephemeral public key which is little-endian.
+
+Encrypted size: 528 bytes
+
+.. raw:: html
+
+ {% highlight lang='dataspec' %}
+
+bytes 0-15: Hop's truncated identity hash
+ bytes 16-47: Sender's ephemeral X25519 public key
+ bytes 48-511: ChaCha20 encrypted BuildRequestRecord
+ bytes 512-527: Poly1305 MAC
+
+{% endhighlight %}
+
+
+
+Build Reply Records
+-------------------------------------
+
+Encrypted BuildReplyRecords are 528 bytes for both ElGamal and ECIES, for compatibility.
+
+
+Reply Record Unencrypted
+`````````````````````````````````````
+This is the specification of the tunnel BuildRequestRecord for ECIES-X25519 routers.
+Summary of changes:
+
+- Add Mapping for build reply options
+- Unencrypted record is longer because there is less encryption overhead
+
+ECIES replies are encrypted with ChaCha20/Poly1305.
+
+All fields are big-endian.
+
+Unencrypted size: 512 bytes
+
+.. raw:: html
+
+ {% highlight lang='dataspec' %}
+
+bytes 0-x: Tunnel Build Reply Options (Mapping)
+ bytes x-x: other data as implied by options
+ bytes x-510: Random padding
+ byte 511: Reply byte
+
+{% endhighlight %}
+
+The tunnel build reply options is a Mapping structure as defined in [Common]_.
+This is for future use. No options are currently defined.
+If the Mapping structure is empty, this is two bytes 0x00 0x00.
+The maximum size of the Mapping (including the length field) is 511 bytes,
+and the maximum value of the Mapping length field is 509.
+
+The reply byte is one of the following values
+as defined in [Tunnel-Creation]_ to avoid fingerprinting:
+
+- 0x00 (accept)
+- 30 (TUNNEL_REJECT_BANDWIDTH)
+
+
+Reply Record Encrypted
+```````````````````````````````````
+
+Encrypted size: 528 bytes
+
+.. raw:: html
+
+ {% highlight lang='dataspec' %}
+
+bytes 0-511: ChaCha20 encrypted BuildReplyRecord
+ bytes 512-527: Poly1305 MAC
+
+{% endhighlight %}
+
+After full transition to ECIES records, ranged padding rules are the same as for request records.
+
+
+Symmetric Encryption of Records
+--------------------------------------------------------
+
+Mixed tunnels are allowed, and necessary, for the transition from ElGamal to ECIES.
+During the transitionary period, an increasing number of routers will be keyed under ECIES keys.
+
+Symmetric cryptography preprocessing will run in the same way:
+
+- "encryption":
+
+ - cipher run in decryption mode
+ - request records preemptively decrypted in preprocessing (concealing encrypted request records)
+
+- "decryption":
+
+ - cipher run in encryption mode
+ - request records encrypted (revealing next plaintext request record) by participant hops
+
+- ChaCha20 does not have "modes", so it is simply run three times:
+
+ - once in preprocessing
+ - once by the hop
+ - once on final reply processing
+
+When mixed tunnels are used, tunnel creators will need to base the symmetric encryption
+of BuildRequestRecord on the current and previous hop's encryption type.
+
+Each hop will use its own encryption type for encrypting BuildReplyRecords, and the other
+records in the VariableTunnelBuildMessage (VTBM).
+
+On the reply path, the endpoint (sender) will need to undo the [Multiple-Encryption]_, using each hop's reply key.
+
+As a clarifying example, let's look at an outbound tunnel w/ ECIES surrounded by ElGamal:
+
+- Sender (OBGW) -> ElGamal (H1) -> ECIES (H2) -> ElGamal (H3)
+
+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.
+
+Likewise, ChaCha20 will be used to encrypt each record, not streaming across the entire VTBM.
+
+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
+
+Only H2 checks the reply encryption flag, and sees its followed by AES256/CBC.
+
+After being processed by each hop, the records are in a "decrypted" state:
+
+- H3's record is "decrypted" using:
+
+ - H3's reply key (AES256/CBC)
+
+- H2's record is "decrypted" using:
+
+ - H3's reply key (AES256/CBC)
+ - H2's reply key (ChaCha20-Poly1305)
+
+- H1's record is "decrypted" using:
+
+ - H3's reply key (AES256/CBC)
+ - H2's reply key (ChaCha20)
+ - H1's reply key (AES256/CBC)
+
+The tunnel creator, a.k.a. Inbound Endpoint (IBEP), postprocesses the reply:
+
+- H3's record is "encrypted" using:
+
+ - H3's reply key (AES256/CBC)
+
+- H2's record is "encrypted" using:
+
+ - H3's reply key (AES256/CBC)
+ - H2's reply key (ChaCha20-Poly1305)
+
+- H1's record is "encrypted" using:
+
+ - H3's reply key (AES256/CBC)
+ - H2's reply key (ChaCha20)
+ - H1's reply key (AES256/CBC)
+
+
+Request Record Keys
+-----------------------------------------------------------------------
+
+These keys are explicitly included in ElGamal BuildRequestRecords.
+For ECIES BuildRequestRecords, the tunnel keys and AES reply keys are included,
+but the ChaCha reply keys are derived from the DH exchange.
+See [Prop156]_ for details of the router static ECIES keys.
+
+Below is a description of how to derive the keys previously transmitted in request records.
+
+
+KDF for Initial ck and h
+````````````````````````
+
+This is standard [NOISE]_ for pattern "N" with a standard protocol name.
+
+.. raw:: html
+
+ {% highlight lang='text' %}
+This is the "e" message pattern:
+
+ // Define protocol_name.
+ Set protocol_name = "Noise_N_25519_ChaChaPoly_SHA256"
+ (31 bytes, US-ASCII encoded, no NULL termination).
+
+ // Define Hash h = 32 bytes
+ // Pad to 32 bytes. Do NOT hash it, because it is not more than 32 bytes.
+ h = protocol_name || 0
+
+ Define ck = 32 byte chaining key. Copy the h data to ck.
+ Set chainKey = h
+
+ // MixHash(null prologue)
+ h = SHA256(h);
+
+ // up until here, can all be precalculated by all routers.
+
+{% endhighlight %}
+
+
+KDF for Request Record
+````````````````````````
+
+ElGamal tunnel creators 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.
+
+ECIES tunnel creators will need to encrypt to each of the ElGamal hop's public key using the
+scheme defined in [Tunnel-Creation]_. ECIES tunnel creators will use the above scheme for encrypting
+to ECIES hops.
+
+This means that tunnel hops will only see encrypted records from their same encryption type.
+
+For ElGamal and ECIES tunnel creators, they will generate unique ephemeral X25519 keypairs
+per-hop for encrypting to ECIES hops.
+
+**IMPORTANT**:
+Ephemeral keys must be unique per ECIES hop, and per build record.
+Failing to use unique keys opens an attack vector for colluding hops to confirm they are in the same tunnel.
+
+
+.. raw:: html
+
+ {% highlight lang='dataspec' %}
+
+// Each hop's X25519 static keypair (hesk, hepk) from the Router Identity
+ hesk = GENERATE_PRIVATE()
+ hepk = DERIVE_PUBLIC(hesk)
+
+ // MixHash(hepk)
+ // || below means append
+ h = SHA256(h || hepk);
+
+ // up until here, can all be precalculated by each router
+ // for all incoming build requests
+
+ // Sender generates an X25519 ephemeral keypair per ECIES hop in the VTBM (sesk, sepk)
+ sesk = GENERATE_PRIVATE()
+ sepk = DERIVE_PUBLIC(sesk)
+
+ // MixHash(sepk)
+ h = SHA256(h || sepk);
+
+ End of "e" message pattern.
+
+ This is the "es" message pattern:
+
+ // Noise es
+ // Sender performs an X25519 DH with Hop's static public key.
+ // Each Hop, finds the record w/ their truncated identity hash,
+ // and extracts the Sender's ephemeral key preceding the encrypted record.
+ sharedSecret = DH(sesk, hepk) = DH(hesk, sepk)
+
+ // MixKey(DH())
+ //[chainKey, k] = MixKey(sharedSecret)
+ // ChaChaPoly parameters to encrypt/decrypt
+ keydata = HKDF(chainKey, sharedSecret, "", 64)
+ // Save for Reply Record KDF
+ chainKey = keydata[0:31]
+
+ // AEAD parameters
+ k = keydata[32:64]
+ n = 0
+ plaintext = 464 byte build request record
+ ad = h
+ ciphertext = ENCRYPT(k, n, plaintext, ad)
+
+ End of "es" message pattern.
+
+ // MixHash(ciphertext)
+ // Save for Reply Record KDF
+ h = SHA256(h || ciphertext)
+
+{% endhighlight %}
+
+``replyKey``, ``layerKey`` and ``layerIV`` must still be included inside ElGamal records,
+and can be generated randomly.
+
+
+
+Reply Record Encryption
+--------------------------------------
+
+The reply record is ChaCha20/Poly1305 encrypted.
+
+.. raw:: html
+
+ {% highlight lang='dataspec' %}
+
+// AEAD parameters
+ k = chainkey from build request
+ n = 0
+ plaintext = 512 byte build reply record
+ ad = h from build request
+
+ ciphertext = ENCRYPT(k, n, plaintext, ad)
+
+{% endhighlight %}
+
+
+
+Implementation Notes
+=====================
+
+* Older routers do not check the encryption type of the hop and will send ElGamal-encrypted
+ records. Some recent routers are buggy and will send various types of malformed records.
+ Implementers should detect and reject these records prior to the DH operation
+ if possible, to reduce CPU usage.
+
+
+
+References
+==========
+
+.. [Common]
+ {{ spec_url('common-structures') }}
+
+.. [Cryptography]
+ {{ spec_url('cryptography') }}
+
+.. [ECIES-X25519]
+ {{ spec_url('ecies') }}
+
+.. [I2NP]
+ {{ spec_url('i2np') }}
+
+.. [NOISE]
+ https://noiseprotocol.org/noise.html
+
+.. [NTCP2]
+ {{ spec_url('ntcp2') }}
+
+.. [Prop119]
+ {{ proposal_url('119') }}
+
+.. [Prop143]
+ {{ proposal_url('143') }}
+
+.. [Prop152]
+ {{ proposal_url('152') }}
+
+.. [Prop153]
+ {{ proposal_url('153') }}
+
+.. [Prop156]
+ {{ proposal_url('156') }}
+
+.. [Prop157]
+ {{ proposal_url('157') }}
+
+.. [Tunnel-Creation]
+ {{ spec_url('tunnel-creation') }}
+
+.. [Multiple-Encryption]
+ https://en.wikipedia.org/wiki/Multiple_encryption
+
+.. [RFC-7539]
+ https://tools.ietf.org/html/rfc7539
+
+.. [RFC-7748]
+ https://tools.ietf.org/html/rfc7748
+
+
+