rfc9383.original.xml   rfc9383.xml 
<?xml version='1.0' encoding='utf-8'?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc [ <!DOCTYPE rfc [
<!ENTITY nbsp "&#160;"> <!ENTITY nbsp "&#160;">
<!ENTITY zwsp "&#8203;"> <!ENTITY zwsp "&#8203;">
<!ENTITY nbhy "&#8209;"> <!ENTITY nbhy "&#8209;">
<!ENTITY wj "&#8288;"> <!ENTITY wj "&#8288;">
]> ]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc2629 version 1.5.17 --> <rfc xmlns:xi="http://www.w3.org/2001/XInclude"
<?rfc toc="yes"?> ipr="trust200902"
<?rfc sortrefs="yes"?> docName="draft-bar-cfrg-spake2plus-08"
<?rfc symrefs="yes"?> number="9383"
<?rfc docmapping="yes"?> submissionType="independent"
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft category="info"
-bar-cfrg-spake2plus-08" category="info" obsoletes="" updates="" submissionType= obsoletes=""
"IETF" xml:lang="en" tocInclude="true" sortRefs="true" symRefs="true" version="3 updates=""
"> xml:lang="en"
tocInclude="true"
sortRefs="true"
symRefs="true"
version="3">
<!-- xml2rfc v2v3 conversion 3.11.1 --> <!-- xml2rfc v2v3 conversion 3.11.1 -->
<front> <front>
<title abbrev="spake2plus">SPAKE2+, an Augmented PAKE</title> <title abbrev="spake2plus">SPAKE2+, an Augmented Password-Authenticated Key
<seriesInfo name="Internet-Draft" value="draft-bar-cfrg-spake2plus-08"/> Exchange (PAKE) Protocol</title>
<seriesInfo name="RFC" value="9383"/>
<author initials="T." surname="Taubert" fullname="Tim Taubert"> <author initials="T." surname="Taubert" fullname="Tim Taubert">
<organization>Apple Inc.</organization> <organization>Apple Inc.</organization>
<address> <address>
<postal> <postal>
<street>One Apple Park Way</street> <street>One Apple Park Way</street>
<city>Cupertino, California 95014</city> <city>Cupertino</city>
<region>California</region>
<code>95014</code>
<country>United States of America</country> <country>United States of America</country>
</postal> </postal>
<email>ttaubert@apple.com</email> <email>ttaubert@apple.com</email>
</address> </address>
</author> </author>
<author initials="C.A." surname="Wood" fullname="Christopher A. Wood"> <author initials="C. A." surname="Wood" fullname="Christopher A. Wood">
<organization/> <organization/>
<address> <address>
<email>caw@heapingbits.net</email> <email>caw@heapingbits.net</email>
</address> </address>
</author> </author>
<date/> <date year="2023" month="September" />
<keyword>Internet-Draft</keyword>
<abstract> <abstract>
<t>This document describes SPAKE2+, a Password Authenticated Key Exchange (PAKE) protocol <t>This document describes SPAKE2+, a Password-Authenticated Key Exchange (PAKE) protocol
run between two parties for deriving a strong shared key with no risk of disclos ing the password. run between two parties for deriving a strong shared key with no risk of disclos ing the password.
SPAKE2+ is an augmented PAKE protocol, as only one party has knowledge of the pa ssword. SPAKE2+ is an augmented PAKE protocol, as only one party has knowledge of the pa ssword.
This method is simple to implement, compatible with any prime order group and is This method is simple to implement, compatible with any prime-order group, and c
computationally efficient.</t> omputationally efficient.</t>
<t>This document was produced outside of the IETF and IRTF, and represents <t>This document was produced outside of the IETF and IRTF and represents
the opinions of the authors. the opinions of the authors.
Publication of this document as an RFC in the Independent Submissions Stream doe s not imply endorsement Publication of this document as an RFC in the Independent Submissions Stream doe s not imply endorsement
of SPAKE2+ by the IETF or IRTF.</t> of SPAKE2+ by the IETF or IRTF.</t>
</abstract> </abstract>
<note removeInRFC="true">
<name>Discussion Venues</name>
<t>Source for this draft and an issue tracker can be found at
<eref target="https://github.com/chris-wood/draft-bar-cfrg-spake2plus"/>.</t>
</note>
</front> </front>
<middle> <middle>
<section anchor="introduction" numbered="true" toc="default"> <section anchor="introduction" numbered="true" toc="default">
<name>Introduction</name> <name>Introduction</name>
<t>This document describes SPAKE2+, a Password Authenticated Key Exchange (PAKE) protocol <t>This document describes SPAKE2+, a Password-Authenticated Key Exchange (PAKE) protocol
run between two parties for deriving a strong shared key with no risk of disclos ing the password. run between two parties for deriving a strong shared key with no risk of disclos ing the password.
SPAKE2+ is an augmented PAKE protocol, as only one party makes direct use of the password during the execution of the protocol. SPAKE2+ is an augmented PAKE protocol, as only one party makes direct use of the password during the execution of the protocol.
The other party only needs a record corresponding to the other party's registrat ion at the time of the protocol execution instead of the password. The other party only needs a record corresponding to the first party's registrat ion at the time of the protocol execution instead of the password.
This record can be computed once, during an offline registration phase. This record can be computed once, during an offline registration phase.
The party using the password directly would typically be a client, and acts as a The party using the password directly would typically be a client and would act
prover, as a Prover,
while the other party would be a server, and acts as verifier.</t> while the other party would be a server and would act as a Verifier.</t>
<t>The protocol is augmented in the sense that it provides some resilience
to the compromise or extraction of the registration record. <t>The protocol is augmented in the sense that it provides some resilience
against the compromise or extraction of the registration record.
The design of the protocol forces the adversary to recover the password from the record to successfully execute the protocol. The design of the protocol forces the adversary to recover the password from the record to successfully execute the protocol.
Hence this protocol can be advantageously combined with a salted Password Hashin Hence, this protocol can be advantageously combined with a salted Password Hashi
g Function to increase the cost of the recovery and slow down attacks. ng Function to increase the cost of the recovery and slow down attacks.
The record cannot be used directly to successfully run the protocol as a prover, The record cannot be used directly to successfully run the protocol as a Prover,
making this protocol more robust than balanced PAKEs which don't benefit from Pa making this protocol more robust than balanced PAKEs, which don't benefit from P
ssword Hashing Functions to the same extent.</t> assword Hashing Functions to the same extent.</t>
<t>This augmented property is especially valuable in scenarios where the e xecution of the protocol is constrained <t>This augmented property is especially valuable in scenarios where the e xecution of the protocol is constrained
and the adversary cannot query the salt of the password hash function ahead of t and the adversary cannot query the salt of the Password Hashing Function ahead o
he attack. f the attack.
Constraints may consist in being in physical proximity through a local network o For example, a constraint may be when physical proximity through a local network
r is required or when a first authentication factor is required for initiation of
when initiation of the protocol requires a first authentication factor.</t> the protocol.</t>
<t>This document has content split out from a related document specifying
SPAKE2 <xref target="I-D.irtf-cfrg-spake2" format="default"/>, <t>This document has content split out from a related document,
which is a symmetric PAKE protocol, where both parties have knowledge of the pas <xref target="RFC9382" format="default"/>, which specifies SPAKE2.
sword. SPAKE2 is a symmetric PAKE protocol, where both parties have knowledge of the pa
ssword.
SPAKE2+ is the asymmetric or augmented version of SPAKE2, wherein only one party has knowledge of the password. SPAKE2+ is the asymmetric or augmented version of SPAKE2, wherein only one party has knowledge of the password.
SPAKE2+ is specified separately in this document because the use cases for symme tric and augmented PAKEs SPAKE2+ is specified separately in this document because the use cases for symme tric and augmented PAKEs
are different, and therefore warrant different technical specifications. Neither are different and therefore warrant different technical specifications. Neither
SPAKE2 nor SPAKE2+ SPAKE2 nor SPAKE2+
was selected as the result of the CFRG PAKE selection competition. However, this was selected as the result of the Crypto Forum Research Group (CFRG) PAKE select
password-based key exchange ion competition. However, this password-based key exchange
protocol appears in <xref target="TDH" format="default"/> and is proven secure i n <xref target="SPAKE2P-Analysis" format="default"/>. It is compatible with any protocol appears in <xref target="TDH" format="default"/> and is proven secure i n <xref target="SPAKE2P-Analysis" format="default"/>. It is compatible with any
prime-order group and relies only on group operations, making it simple and comp utationally efficient. prime-order group and relies only on group operations, making it simple and comp utationally efficient.
Thus, it was felt that publication was beneficial to make the protocol available for wider consideration.</t> Thus, it was felt that publication was beneficial to make the protocol available for wider consideration.</t>
<t>This document was produced outside of the IETF and IRTF, and represents the opinions of the authors. <t>This document was produced outside of the IETF and IRTF and represents the opinions of the authors.
Publication of this document as an RFC in the Independent Submissions Stream doe s not imply endorsement Publication of this document as an RFC in the Independent Submissions Stream doe s not imply endorsement
of SPAKE2+ by the IETF or IRTF.</t> of SPAKE2+ by the IETF or IRTF.</t>
</section> </section>
<section anchor="requirements-notation" numbered="true" toc="default"> <section anchor="requirements-notation" numbered="true" toc="default">
<name>Requirements Notation</name> <name>Requirements Notation</name>
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>",
"OPTIONAL" in this document are to be interpreted as described in BCP "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>",
14 <xref target="RFC2119" format="default"/> <xref target="RFC8174" format="defa "<bcp14>SHOULD NOT</bcp14>",
ult"/> when, and only when, they appear in all "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
capitals, as shown here.</t> "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document
are to be interpreted as described in BCP&nbsp;14
<xref target="RFC2119"/> <xref target="RFC8174"/> when, and only
when, they appear in all capitals, as shown here.</t>
</section> </section>
<section anchor="definition-of-spake2" numbered="true" toc="default"> <section anchor="definition-of-spake2" numbered="true" toc="default">
<name>Definition of SPAKE2+</name> <name>Definition of SPAKE2+</name>
<t>Let G be a group in which the computational Diffie-Hellman (CDH) <t>Let G be a group in which the computational Diffie-Hellman (CDH)
problem is hard. Suppose G has order p*h where p is a large prime; problem is hard. Suppose G has order p*h where p is a large prime;
h will be called the cofactor. Let I be the unit element in h will be called the cofactor. Let I be the unit element in
G, e.g., the point at infinity if G is an elliptic curve group. We denote the G, e.g., the point at infinity if G is an elliptic curve group. We denote the
operations in the group additively. We assume there is a representation of operations in the group additively. We assume that there is a representation of
elements of G as byte strings: common choices would be SEC1 elements of G as byte strings: common choices would be SEC 1
uncompressed or compressed <xref target="SEC1" format="default"/> for elliptic c uncompressed or compressed <xref target="SEC1"/> for elliptic curve groups or bi
urve groups or big g-endian integers of a fixed (per-group) length for prime field DH.
endian integers of a fixed (per-group) length for prime field DH. We fix a generator P of the (large) prime-order subgroup of G. P is specified
We fix a generate P of (large) prime-order subgroup of G. P is specified
in the document defining the group, and so we do not repeat it here.</t> in the document defining the group, and so we do not repeat it here.</t>
<t>|| denotes concatenation of strings. We also let len(S) denote the <t>|| denotes concatenation of strings. We also let len(S) denote the
length of a string in bytes, represented as an eight-byte little length of a string in bytes, represented as an eight-byte little-endian number.
endian number. Finally, let nil represent an empty string, i.e., Finally, let nil represent an empty string, i.e.,
len(nil) = 0.</t> len(nil) = 0.</t>
<t>KDF is a key-derivation function that takes as input a salt, intermedia te <t>KDF is a key derivation function that takes as input a salt, input
keying material (IKM), info string, and derived key length L to derive a keying material (IKM), info string, and derived key length L to derive a
cryptographic key of length L. cryptographic key of length L.
MAC is a Message Authentication Code algorithm that takes a secret key and MAC is a Message Authentication Code algorithm that takes a secret key and
message as input to produce an output. message as input to produce an output.
Let Hash be a hash function from arbitrary strings to bit strings of a fixed len gth. Common choices Let Hash be a hash function from arbitrary strings to bit strings of a fixed len gth. Common choices
for Hash are SHA256 or SHA512 <xref target="RFC6234" format="default"/>. for Hash are SHA256 or SHA512 <xref target="RFC6234" format="default"/>.
<xref target="Ciphersuites" format="default"/> specifies variants of KDF, MAC, a nd Hash <xref target="Ciphersuites" format="default"/> specifies variants of KDF, MAC, a nd Hash
suitable for use with the protocols contained herein.</t> suitable for use with the protocols contained herein.</t>
<t>Let there be two parties, a prover and a verifier. Their identities, de noted as <t>Let there be two parties, a Prover and a Verifier. Their identities, de noted as
idProver and idVerifier, may also have digital representations such as Media Acc ess Control addresses idProver and idVerifier, may also have digital representations such as Media Acc ess Control addresses
or other names (hostnames, usernames, etc). The parties may share additional dat or other names (hostnames, usernames, etc.). The parties may share additional da
a ta
(the context) separate from their identities which they may want to include in (the context) separate from their identities, which they may want to include in
the protocol transcript. the protocol transcript.
One example of additional data is a list of supported protocol versions if SPAKE 2+ were One example of additional data is a list of supported protocol versions if SPAKE 2+ were
used in a higher-level protocol which negotiates the use of a particular PAKE. A used in a higher-level protocol that negotiates the use of a particular PAKE. An
nother other
example is the inclusion of the application name. Including those would ensure t example is the inclusion of the application name. Including these data points wo
hat uld ensure that
both parties agree upon the same set of supported protocols and therefore preven both parties agree upon the same set of supported protocols and therefore preven
t downgrade and ts downgrade and
cross-protocol attacks. Specification of precise context values is out of scope for this document.</t> cross-protocol attacks. Specification of precise context values is out of scope for this document.</t>
<section anchor="protocol-overview" numbered="true" toc="default"> <section anchor="protocol-overview" numbered="true" toc="default">
<name>Protocol Overview</name> <name>Protocol Overview</name>
<t>SPAKE2+ is a two round protocol that establishes a shared secret with an <t>SPAKE2+ is a two-round protocol that establishes a shared secret with an
additional round for key confirmation. Prior to invocation, both parties are additional round for key confirmation. Prior to invocation, both parties are
provisioned with information such as the input password needed to run the provisioned with information such as the input password needed to run the
protocol. The registration phase may include communicating identities, protocol protocol. The registration phase may include communicating identities, protocol
version and other parameters related to the registration record; see version, and other parameters related to the registration record; see
<xref target="offline-registration" format="default"/> for details.</t> <xref target="offline-registration" format="default"/> for details.</t>
<t>During the first round, the prover sends a public share shareP to the <t>During the first round, the Prover sends a public share, shareP, to t
verifier, which in turn he Verifier, which in turn
responds with its own public share shareV. Both parties then derive a shared sec responds with its own public share, shareV. Both parties then derive a shared se
ret cret
used to produce encryption and authentication keys. The latter are used during t he second used to produce encryption and authentication keys. The latter are used during t he second
round for key confirmation. (<xref target="keys" format="default"/> details the key derivation and confirmation steps.) round for key confirmation. (<xref target="keys" format="default"/> details the key derivation and confirmation steps.)
In particular, the verifier sends a key confirmation message confirmV to the pro In particular, the Verifier sends a key confirmation message, confirmV, to the P
ver, rover,
which in turn responds with its own key confirmation message confirmP. which in turn responds with its own key confirmation message, confirmP.
(Note that shareV and confirmV MAY be sent in the same message.) (Note that shareV and confirmV <bcp14>MAY</bcp14> be sent in the same message.)
Both parties MUST NOT consider the protocol complete prior to receipt and Both parties <bcp14>MUST NOT</bcp14> consider the protocol complete prior to rec
eipt and
validation of these key confirmation messages.</t> validation of these key confirmation messages.</t>
<t>A sample trace is shown below.</t> <t>A sample trace is shown below.</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <artwork name="" type="" align="left" alt=""><![CDATA[
Prover Verifier Prover Verifier
| (registration) | | (registration) |
|<- - - - - - - - - - - - ->| |<- - - - - - - - - - - - ->|
| | | |
| (setup protocol) | | (set up the protocol) |
(compute shareP) | shareP | (compute shareP) | shareP |
|-------------------------->| |-------------------------->|
| shareV | (compute shareV) | shareV | (compute shareV)
|<--------------------------| |<--------------------------|
| | | |
| (derive secrets) | (compute confirmV) | (derive secrets) | (compute confirmV)
| confirmV | | confirmV |
|<--------------------------| |<--------------------------|
(compute confirmP) | confirmP | (compute confirmP) | confirmP |
|-------------------------->| |-------------------------->|
skipping to change at line 163 skipping to change at line 176
(compute shareP) | shareP | (compute shareP) | shareP |
|-------------------------->| |-------------------------->|
| shareV | (compute shareV) | shareV | (compute shareV)
|<--------------------------| |<--------------------------|
| | | |
| (derive secrets) | (compute confirmV) | (derive secrets) | (compute confirmV)
| confirmV | | confirmV |
|<--------------------------| |<--------------------------|
(compute confirmP) | confirmP | (compute confirmP) | confirmP |
|-------------------------->| |-------------------------->|
]]></artwork> ]]></artwork>
</section> </section>
<section anchor="offline-registration" numbered="true" toc="default"> <section anchor="offline-registration" numbered="true" toc="default">
<name>Offline Registration</name> <name>Offline Registration</name>
<t>The registration phase computes the values w0 and w1, as well as the registration <t>The registration phase computes the values w0 and w1, as well as the registration
record L=w1*P. w0 and w1 are derived by hashing the password pw with the identit record L=w1*P. &nbsp;w0 and w1 are derived by hashing the password pw with the i
ies dentities
of the two participants. w0 and the record L are then shared with the verifier a of the two participants. &nbsp;w0 and the record L are then shared with the Veri
nd fier and
stored as part of the registration record associated with the prover. The prover stored as part of the registration record associated with the Prover. The Prover
SHOULD derive w0 and w1 from the password before the protocol begins. Both w0 an <bcp14>SHOULD</bcp14> derive w0 and w1 from the password before the protocol beg
d ins. Both w0 and
w1 are derived using a function with range [0, p-1], which is modeled as a rando m w1 are derived using a function with range [0, p-1], which is modeled as a rando m
oracle in <xref target="SPAKE2P-Analysis" format="default"/>.</t> oracle in <xref target="SPAKE2P-Analysis" format="default"/>.</t>
<t>The registration phase also produces two random elements M and N in t he prime-order <t>The registration phase also produces two random elements, M and N, in the prime-order
subgroup of G. The algorithm for selecting M and N is defined in <xref target="p ointgen" format="default"/>. subgroup of G. The algorithm for selecting M and N is defined in <xref target="p ointgen" format="default"/>.
Importantly, this algorithm chooses M and N such that their discrete logs are no t Importantly, this algorithm chooses M and N such that their discrete logs are no t
known. Pre-computed values for M and N are listed in <xref target="Ciphersuites" known. Precomputed values for M and N are listed in <xref target="Ciphersuites"
format="default"/> for each format="default"/> for each
group. Applications MAY use different M and N values provided they are computed, group. Applications <bcp14>MAY</bcp14> use different M and N values, provided th
ey are computed,
e.g., using different input seeds to the algorithm in <xref target="pointgen" fo rmat="default"/>, as random elements e.g., using different input seeds to the algorithm in <xref target="pointgen" fo rmat="default"/>, as random elements
for which the discrete log is unknown.</t> for which the discrete log is unknown.</t>
<t>Applications using this specification MUST define the method used to compute w0 and w1. <t>Applications using this specification <bcp14>MUST</bcp14> define the method used to compute w0 and w1.
For example, it may be necessary to carry out various forms of normalization of the For example, it may be necessary to carry out various forms of normalization of the
password before hashing <xref target="RFC8265" format="default"/>. This section contains requirements and default password before hashing <xref target="RFC8265" format="default"/>. This section contains requirements and default
recommendations for computing w0 and w1.</t> recommendations for computing w0 and w1.</t>
<t>The RECOMMENDED method for generating w0 and w1 is via a Password-Bas ed Key <t>The <bcp14>RECOMMENDED</bcp14> method for generating w0 and w1 is via a Password-Based Key
Derivation Function (PBKDF), which is a function designed to slow down brute-for ce Derivation Function (PBKDF), which is a function designed to slow down brute-for ce
attackers. Brute-force resistance may be obtained through various computation ha rdness attackers. Brute-force resistance may be obtained through various computation ha rdness
parameters such as memory or CPU cycles, and are typically configurable. parameters such as memory or CPU cycles and are typically configurable.
Scrypt <xref target="RFC7914" format="default"/> and Argon2id <xref target="RFC9 The scrypt <xref target="RFC7914" format="default"/> function and the Argon2id <
106" format="default"/> are common examples of PBKDFs. xref target="RFC9106" format="default"/> function are common examples of PBKDFs.
Absent an application-specific profile, RECOMMENDED parameters (N, r, p) Absent an application-specific profile, <bcp14>RECOMMENDED</bcp14> parameters (N
for Scrypt are (32768,8,1), and RECOMMENDED parameters for Argon2id , r, p)
are in Section 4 of <xref target="RFC9106" format="default"/>.</t> for scrypt are (32768,8,1), and <bcp14>RECOMMENDED</bcp14> parameters for Argon2
id
are in <xref target="RFC9106" sectionFormat="of" section="4"/>.</t>
<t>Each half of the output of the PBKDF will be interpreted as an intege r and reduced <t>Each half of the output of the PBKDF will be interpreted as an intege r and reduced
modulo p. To control bias, each half must be of length at least ceil(log2(p)) + k modulo p. To control bias, each half must be of length at least ceil(log2(p)) + k
bits, with k &gt;= 64. Reducing such integers mod p gives bias at most 2^-k for any bits, with k &gt;= 64. Reducing such integers mod p gives bias at most 2^-k for any
p; this bias is negligible for any k &gt;= 64.</t> p; this bias is negligible for any k &gt;= 64.</t>
<t>The minimum total output length of the PBKDF then is 2 * (ceil(log2(p )) + k) bits. <t>The minimum total output length of the PBKDF then is 2 * (ceil(log2(p )) + k) bits.
For example, given the prime order of the P-256 curve, the output of the PBKDF For example, given the prime order of the P-256 curve, the output of the PBKDF
SHOULD be at least 640 bits or 80 bytes.</t> <bcp14>SHOULD</bcp14> be at least 640 bits or 80 bytes.</t>
<t>Given a PBKDF, password pw, and identities idProver and idVerifier, t <t>Given a PBKDF, password pw, and identities idProver and idVerifier, t
he RECOMMENDED he <bcp14>RECOMMENDED</bcp14>
method for computing w0 and w1 is as follows:</t> method for computing w0 and w1 is as follows:</t>
<artwork name="" type="" align="left" alt=""><![CDATA[
<sourcecode type="pseudocode"><![CDATA[
w0s || w1s = PBKDF(len(pw) || pw || w0s || w1s = PBKDF(len(pw) || pw ||
len(idProver) || idProver || len(idProver) || idProver ||
len(idVerifier) || idVerifier) len(idVerifier) || idVerifier)
w0 = w0s mod p w0 = w0s mod p
w1 = w1s mod p w1 = w1s mod p
]]></artwork> ]]></sourcecode>
<t>If an identity is unknown at the time of computing w0s or w1s, its le ngth is given <t>If an identity is unknown at the time of computing w0s or w1s, its le ngth is given
as zero and the identity itself is represented as the empty octet string. If bot h as zero and the identity itself is represented as an empty octet string. If both
idProver and idVerifier are unknown, then their lengths are given as zero and bo th idProver and idVerifier are unknown, then their lengths are given as zero and bo th
identities will be represented as empty octet strings. idProver and idVerifier a re identities will be represented as empty octet strings. &nbsp;idProver and idVeri fier are
included in the transcript TT as part of the protocol flow.</t> included in the transcript TT as part of the protocol flow.</t>
</section> </section>
<section anchor="online-authentication" numbered="true" toc="default"> <section anchor="online-authentication" numbered="true" toc="default">
<name>Online Authentication</name> <name>Online Authentication</name>
<t>The online SPAKE2+ protocol runs between the prover and verifier to p <t>The online SPAKE2+ protocol runs between the Prover and Verifier to p
roduce a roduce a
single shared secret upon completion. To begin, the prover selects x uniformly single shared secret upon completion. To begin, the Prover selects x uniformly
at random from the integers in [0, p-1], computes the public share shareP=X, at random from the integers in [0, p-1], computes the public share shareP=X,
and transmits it to the verifier.</t> and transmits it to the Verifier.</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode type="pseudocode"><![CDATA[
x <- [0, p-1] x <- [0, p-1]
X = x*P + w0*M X = x*P + w0*M
]]></artwork> ]]></sourcecode>
<t>Upon receipt of X, the verifier checks the received element for group <t>Upon receipt of X, the Verifier checks the received element for group
membership membership
and aborts if X is not in the large prime-order subgroup of G; see <xref target= "security" format="default"/> and aborts if X is not in the large prime-order subgroup of G; see <xref target= "security" format="default"/>
for details. The verifier then selects y uniformly at random from the integers for details. The Verifier then selects y uniformly at random from the integers
in [0, p-1], computes the public share shareV=Y and transmits it to the prover. in [0, p-1], computes the public share shareV=Y, and transmits it to the Prover.
Upon receipt of Y, the prover checks the received element for group membership Upon receipt of Y, the Prover checks the received element for group membership
and aborts if Y is not in the large prime-order subgroup of G.</t> and aborts if Y is not in the large prime-order subgroup of G.</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode type="pseudocode"><![CDATA[
y <- [0, p-1] y <- [0, p-1]
Y = y*P + w0*N Y = y*P + w0*N
]]></artwork> ]]></sourcecode>
<t>Both participants compute Z and V that are now shared as common value <t>Both participants compute Z and V; Z and V are then shared as common
s. values.
The prover computes:</t> The Prover computes:</t>
<artwork name="" type="" align="left" alt=""><![CDATA[
<sourcecode type="pseudocode"><![CDATA[
Z = h*x*(Y - w0*N) Z = h*x*(Y - w0*N)
V = h*w1*(Y - w0*N) V = h*w1*(Y - w0*N)
]]></artwork> ]]></sourcecode>
<t>The verifier computes:</t> <t>The Verifier computes:</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode type="pseudocode"><![CDATA[
Z = h*y*(X - w0*M) Z = h*y*(X - w0*M)
V = h*y*L V = h*y*L
]]></artwork> ]]></sourcecode>
<t>The multiplication by the cofactor h prevents small subgroup confinem ent attacks. <t>The multiplication by the cofactor h prevents small subgroup confinem ent attacks.
All proofs of security hold even if the discrete log of the fixed group element All proofs of security hold even if the discrete log of the fixed group element
N is known to the adversary. In particular, one MAY set N=I, i.e. set N to the N is known to the adversary. In particular, one <bcp14>MAY</bcp14> set N=I, i.e. , set N to the
unit element in G.</t> unit element in G.</t>
<t>It is essential that both Z and V be used in combination with the tra nscript to <t>It is essential that both Z and V be used in combination with the tra nscript to
derive the keying material. The protocol transcript encoding is shown below.</t> derive the keying material. The protocol transcript encoding is shown below.</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode type="pseudocode"><![CDATA[
TT = len(Context) || Context TT = len(Context) || Context
|| len(idProver) || idProver || len(idProver) || idProver
|| len(idVerifier) || idVerifier || len(idVerifier) || idVerifier
|| len(M) || M || len(M) || M
|| len(N) || N || len(N) || N
|| len(shareP) || shareP || len(shareP) || shareP
|| len(shareV) || shareV || len(shareV) || shareV
|| len(Z) || Z || len(Z) || Z
|| len(V) || V || len(V) || V
|| len(w0) || w0 || len(w0) || w0
]]></artwork> ]]></sourcecode>
<t>Context is an application-specific customization string shared betwee n both <t>Context is an application-specific customization string shared betwee n both
parties and MUST precede the remaining transcript. It might contain the parties and <bcp14>MUST</bcp14> precede the remaining transcript. It might conta in the
name and version number of the higher-level protocol, or simply the name and ver sion name and version number of the higher-level protocol, or simply the name and ver sion
number of the application. The context MAY include additional data such as the number of the application. The context <bcp14>MAY</bcp14> include additional dat a such as the
chosen ciphersuite and PBKDF parameters like the iteration count or salt. chosen ciphersuite and PBKDF parameters like the iteration count or salt.
The context and its length prefix MAY be omitted.</t> The context and its length prefix <bcp14>MAY</bcp14> be omitted.</t>
<t>If an identity is absent, its length is given as zero and the identit y itself <t>If an identity is absent, its length is given as zero and the identit y itself
is represented as the empty octet string. If both identities are absent, then is represented as an empty octet string. If both identities are absent, then
their lengths are given as zero and both are represented as empty octet strings. their lengths are given as zero and both are represented as empty octet strings.
In applications where identities are not implicit, idProver and idVerifier SHOUL In applications where identities are not implicit, idProver and idVerifier <bcp1
D always be 4>SHOULD</bcp14> always be
non-empty. Otherwise, the protocol risks Unknown Key Share attacks (discussion non-empty. Otherwise, the protocol risks unknown key-share attacks (discussion
of Unknown Key Share attacks in a specific protocol is given in <xref target="RF of unknown key-share attacks in a specific protocol is given in <xref target="RF
C8844" format="default"/>).</t> C8844" format="default"/>).</t>
<t>Upon completion of this protocol, both parties compute shared secrets K_main, <t>Upon completion of this protocol, both parties compute shared secrets K_main,
K_shared, K_confirmP, and K_confirmV as specified in <xref target="keys" format= K_shared, K_confirmP, and K_confirmV as specified in <xref target="keys" format=
"default"/>. The verifier MUST send a key "default"/>. The Verifier <bcp14>MUST</bcp14> send a key
confirmation message confirmV to the prover so both parties can confirm that the confirmation message, confirmV, to the Prover so both parties can confirm that t
y hey
agree upon these shared secrets. After receipt and verification of the verifier' agree upon these shared secrets. After receipt and verification of the Verifier'
s s
confirmation message, the prover MUST respond with its confirmation message. confirmation message, the Prover <bcp14>MUST</bcp14> respond with its confirmati
The verifier MUST NOT send application data to the prover until it has received on message.
The Verifier <bcp14>MUST NOT</bcp14> send application data to the Prover until i
t has received
and verified the confirmation message. Key confirmation verification requires and verified the confirmation message. Key confirmation verification requires
recomputation of confirmP or confirmV and checking for equality against that whi ch was recomputation of confirmP or confirmV and checking for equality against the data that was
received.</t> received.</t>
</section> </section>
<section anchor="keys" numbered="true" toc="default"> <section anchor="keys" numbered="true" toc="default">
<name>Key Schedule and Key Confirmation</name> <name>Key Schedule and Key Confirmation</name>
<t>The protocol transcript TT, as defined in <xref target="online-authen tication" format="default"/>, is unique and secret to <t>The protocol transcript TT, as defined in <xref target="online-authen tication" format="default"/>, is unique and secret to
the participants. Both parties use TT to derive the shared symmetric secret K_ma in from the the participants. Both parties use TT to derive the shared symmetric secret K_ma in from the
protocol. The length of K_main is equal to the length of the digest output, e.g. , 256 bits protocol. The length of K_main is equal to the length of the digest output, e.g. , 256 bits
for Hash() = SHA-256. The confirmation keys K_confirmP and K_confirmV, as well a s the shared for Hash() = SHA-256. The confirmation keys K_confirmP and K_confirmV, as well a s the shared
key K_shared are derived from K_main.</t> key K_shared, are derived from K_main.</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode type="pseudocode"><![CDATA[
K_main = Hash(TT) K_main = Hash(TT)
K_confirmP || K_confirmV = KDF(nil, K_main, "ConfirmationKeys") K_confirmP || K_confirmV = KDF(nil, K_main, "ConfirmationKeys")
K_shared = KDF(nil, K_main, "SharedKey") K_shared = KDF(nil, K_main, "SharedKey")
]]></artwork> ]]></sourcecode>
<t>Neither K_main nor its derived confirmation keys are used for anythin g except key <t>Neither K_main nor its derived confirmation keys are used for anythin g except key
derivation and confirmation and MUST be discarded after the protocol execution. derivation and confirmation and <bcp14>MUST</bcp14> be discarded after the proto
Applications MAY derive additional keys from K_shared as needed.</t> col execution.
Applications <bcp14>MAY</bcp14> derive additional keys from K_shared as needed.<
/t>
<t>The length of each confirmation key is dependent on the MAC function of the chosen <t>The length of each confirmation key is dependent on the MAC function of the chosen
ciphersuite. For HMAC, the RECOMMENDED key length is equal to the output length of ciphersuite. For HMAC, the <bcp14>RECOMMENDED</bcp14> key length is equal to the output length of
the digest output, e.g., 256 bits for Hash() = SHA-256. For CMAC-AES, each the digest output, e.g., 256 bits for Hash() = SHA-256. For CMAC-AES, each
confirmation key MUST be of length k, where k is the chosen AES key size, confirmation key <bcp14>MUST</bcp14> be of length k, where k is the chosen AES k ey size,
e.g., 128 bits for CMAC-AES-128.</t> e.g., 128 bits for CMAC-AES-128.</t>
<t>Both endpoints MUST employ a MAC that produces pseudorandom tags for key confirmation. <t>Both endpoints <bcp14>MUST</bcp14> employ a MAC that produces pseudor andom tags for key confirmation.
K_confirmP and K_confirmV are symmetric keys used to compute tags confirmP and K_confirmP and K_confirmV are symmetric keys used to compute tags confirmP and
confirmV over the public key shares received from the other peer earlier.</t> confirmV over the public key shares received from the other peer earlier.</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode type="pseudocode"><![CDATA[
confirmP = MAC(K_confirmP, shareV) confirmP = MAC(K_confirmP, shareV)
confirmV = MAC(K_confirmV, shareP) confirmV = MAC(K_confirmV, shareP)
]]></artwork> ]]></sourcecode>
<t>Once key confirmation is complete, applications MAY use K_shared as a <t>Once key confirmation is complete, applications <bcp14>MAY</bcp14> us
n authenticated e K_shared as an authenticated
shared secret as needed. For example, applications MAY derive one or more AEAD shared secret as needed. For example, applications <bcp14>MAY</bcp14> derive one
keys and nonces from K_shared for subsequent application data encryption.</t> or more keys and nonces from K_shared, for use with Authenticated Encryption wi
th Associated Data (AEAD) and subsequent application data encryption.</t>
</section> </section>
</section> </section>
<section anchor="Ciphersuites" numbered="true" toc="default"> <section anchor="Ciphersuites" numbered="true" toc="default">
<name>Ciphersuites</name> <name>Ciphersuites</name>
<t>This section documents SPAKE2+ ciphersuite configurations. A ciphersuit e <t>This section documents SPAKE2+ ciphersuite configurations. A ciphersuit e
indicates a group, cryptographic hash algorithm, and pair of KDF and MAC functio ns, e.g., indicates a group, cryptographic hash algorithm, and pair of KDF and MAC functio ns, e.g.,
P256-SHA256-HKDF-HMAC-SHA256. This ciphersuite indicates a SPAKE2+ protocol inst ance over P256-SHA256-HKDF-HMAC-SHA256. This ciphersuite indicates a SPAKE2+ protocol inst ance over
P-256 that uses SHA256 along with HKDF <xref target="RFC5869" format="default"/> and HMAC <xref target="RFC2104" format="default"/> P-256 that uses SHA256 along with HKDF <xref target="RFC5869" format="default"/> and HMAC <xref target="RFC2104" format="default"/>
for G, Hash, KDF, and MAC functions, respectively. Since the choice of PBKDF for G, Hash, KDF, and MAC functions, respectively. Since the choice of PBKDF,
and its parameters for computing w0 and w1 and distributing does not affect its parameters for computing w0 and w1, and the distribution of w0 and w1 do not
affect
interoperability, the PBKDF is not included as part of the ciphersuite.</t> interoperability, the PBKDF is not included as part of the ciphersuite.</t>
<t>If no MAC algorithm is used in the key confirmation phase, its respecti ve column <t>If no MAC algorithm is used in the key confirmation phase, its respecti ve column
in Table 1 can be ignored and the ciphersuite name will contain no MAC in <xref target="tab-1"/> can be ignored and the ciphersuite name will contain n o MAC
identifier.</t> identifier.</t>
<table align="center"> <table anchor="tab-1" align="center">
<thead> <thead>
<tr> <tr>
<th align="left">G</th> <th align="left">G</th>
<th align="center">Hash</th> <th align="center">Hash</th>
<th align="center">KDF</th> <th align="center">KDF</th>
<th align="center">MAC</th> <th align="center">MAC</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
skipping to change at line 397 skipping to change at line 413
<td align="center">CMAC-AES-128 <xref target="RFC4493" format="defau lt"/></td> <td align="center">CMAC-AES-128 <xref target="RFC4493" format="defau lt"/></td>
</tr> </tr>
<tr> <tr>
<td align="left">P-256</td> <td align="left">P-256</td>
<td align="center">SHA512 <xref target="RFC6234" format="default"/>< /td> <td align="center">SHA512 <xref target="RFC6234" format="default"/>< /td>
<td align="center">HKDF-SHA512 <xref target="RFC5869" format="defaul t"/></td> <td align="center">HKDF-SHA512 <xref target="RFC5869" format="defaul t"/></td>
<td align="center">CMAC-AES-128 <xref target="RFC4493" format="defau lt"/></td> <td align="center">CMAC-AES-128 <xref target="RFC4493" format="defau lt"/></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<t>The following points represent permissible point generation seeds for t he groups listed <t>The following points represent permissible point generation seeds for t he groups listed
in Table 1, using the algorithm presented in <xref target="pointgen" format="def ault"/>. These bytestrings are in <xref target="tab-1"/>, using the algorithm presented in <xref target="pointg en" format="default"/>. These byte strings are
compressed points as in <xref target="SEC1" format="default"/> for curves from < xref target="SEC1" format="default"/> and <xref target="RFC8032" format="default "/>. Note that compressed points as in <xref target="SEC1" format="default"/> for curves from < xref target="SEC1" format="default"/> and <xref target="RFC8032" format="default "/>. Note that
these values are identical to those used in the companion SPAKE2 specification < these values are identical to those used in the companion SPAKE2 specification <
xref target="I-D.irtf-cfrg-spake2" format="default"/>.</t> xref target="RFC9382" format="default"/>.</t>
<t>For P256:</t> <t>For P-256:</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <artwork name="" type="" align="left" alt=""><![CDATA[
M = M =
02886e2f97ace46e55ba9dd7242579f2993b64e16ef3dcab95afd497333d8fa12f 02886e2f97ace46e55ba9dd7242579f2993b64e16ef3dcab95afd497333d8fa12f
seed: 1.2.840.10045.3.1.7 point generation seed (M) seed: 1.2.840.10045.3.1.7 point generation seed (M)
N = N =
03d8bbd6c639c62937b04d997f38c3770719c629d7014d49a24b4f98baa1292b49 03d8bbd6c639c62937b04d997f38c3770719c629d7014d49a24b4f98baa1292b49
seed: 1.2.840.10045.3.1.7 point generation seed (N) seed: 1.2.840.10045.3.1.7 point generation seed (N)
]]></artwork> ]]></artwork>
<t>For P384:</t> <t>For P-384:</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <artwork name="" type="" align="left" alt=""><![CDATA[
M = M =
030ff0895ae5ebf6187080a82d82b42e2765e3b2f8749c7e05eba366434b363d3dc 030ff0895ae5ebf6187080a82d82b42e2765e3b2f8749c7e05eba366434b363d3dc
36f15314739074d2eb8613fceec2853 36f15314739074d2eb8613fceec2853
seed: 1.3.132.0.34 point generation seed (M) seed: 1.3.132.0.34 point generation seed (M)
N = N =
02c72cf2e390853a1c1c4ad816a62fd15824f56078918f43f922ca21518f9c543bb 02c72cf2e390853a1c1c4ad816a62fd15824f56078918f43f922ca21518f9c543bb
252c5490214cf9aa3f0baab4b665c10 252c5490214cf9aa3f0baab4b665c10
seed: 1.3.132.0.34 point generation seed (N) seed: 1.3.132.0.34 point generation seed (N)
]]></artwork> ]]></artwork>
<t>For P521:</t> <t>For P-521:</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <artwork name="" type="" align="left" alt=""><![CDATA[
M = M =
02003f06f38131b2ba2600791e82488e8d20ab889af753a41806c5db18d37d85608 02003f06f38131b2ba2600791e82488e8d20ab889af753a41806c5db18d37d85608
cfae06b82e4a72cd744c719193562a653ea1f119eef9356907edc9b56979962d7aa cfae06b82e4a72cd744c719193562a653ea1f119eef9356907edc9b56979962d7aa
seed: 1.3.132.0.35 point generation seed (M) seed: 1.3.132.0.35 point generation seed (M)
N = N =
0200c7924b9ec017f3094562894336a53c50167ba8c5963876880542bc669e494b25 0200c7924b9ec017f3094562894336a53c50167ba8c5963876880542bc669e494b25
32d76c5b53dfb349fdf69154b9e0048c58a42e8ed04cef052a3bc349d95575cd25 32d76c5b53dfb349fdf69154b9e0048c58a42e8ed04cef052a3bc349d95575cd25
seed: 1.3.132.0.35 point generation seed (N) seed: 1.3.132.0.35 point generation seed (N)
skipping to change at line 460 skipping to change at line 477
seed: edwards448 point generation seed (M) seed: edwards448 point generation seed (M)
N = N =
6034c65b66e4cd7a49b0edec3e3c9ccc4588afd8cf324e29f0a84a072531c4db 6034c65b66e4cd7a49b0edec3e3c9ccc4588afd8cf324e29f0a84a072531c4db
f97ff9af195ed714a689251f08f8e06e2d1f24a0ffc0146600 f97ff9af195ed714a689251f08f8e06e2d1f24a0ffc0146600
seed: edwards448 point generation seed (N) seed: edwards448 point generation seed (N)
]]></artwork> ]]></artwork>
</section> </section>
<section anchor="iana-considerations" numbered="true" toc="default"> <section anchor="iana-considerations" numbered="true" toc="default">
<name>IANA Considerations</name> <name>IANA Considerations</name>
<t>No IANA action is required.</t> <t>This document has no IANA actions.</t>
</section> </section>
<section anchor="security" numbered="true" toc="default"> <section anchor="security" numbered="true" toc="default">
<name>Security Considerations</name> <name>Security Considerations</name>
<t>SPAKE2+ appears in <xref target="TDH" format="default"/> and is proven secure in <xref target="SPAKE2P-Analysis" format="default"/>.</t> <t>SPAKE2+ appears in <xref target="TDH" format="default"/> and is proven secure in <xref target="SPAKE2P-Analysis" format="default"/>.</t>
<t>The ephemeral randomness used by the prover and verifier MUST be <t>The ephemeral randomness used by the Prover and Verifier <bcp14>MUST</b
generated using a cryptographically secure PRNG.</t> cp14> be
<t>Elements received from a peer MUST be checked for group membership: fai generated using a cryptographically secure Pseudorandom Number Generator (PRNG).
lure to </t>
<t>Elements received from a peer <bcp14>MUST</bcp14> be checked for group
membership: failure to
properly deserialize and validate group elements can lead to attacks. An endpoin t properly deserialize and validate group elements can lead to attacks. An endpoin t
MUST abort the protocol if any received public value is not a member of the <bcp14>MUST</bcp14> abort the protocol if any received public value is not a mem ber of the
large prime-order subgroup of G. Multiplication of a public value V by the large prime-order subgroup of G. Multiplication of a public value V by the
cofactor h will yield the identity element I whenever V is an element of a cofactor h will yield the identity element I whenever V is an element of a
small-order subgroup. Consequently, prover and verifier MUST abort the protocol small-order subgroup. Consequently, the Prover and Verifier <bcp14>MUST</bcp14>
upon of any received value V such that V*h = I. Failure to do so may lead to sub abort the protocol
group upon receiving any value V such that V*h = I. Failure to do so may lead to subgr
oup
confinement attacks.</t> confinement attacks.</t>
</section> </section>
<section anchor="acknowledgements" numbered="true" toc="default">
<name>Acknowledgements</name>
<t>Thanks to Ben Kaduk and Watson Ladd, from which this specification orig
inally emanated.</t>
</section>
</middle> </middle>
<back> <back>
<references> <references>
<name>References</name> <name>References</name>
<references> <references>
<name>Normative References</name> <name>Normative References</name>
<reference anchor="TDH"> <reference anchor="TDH">
<front> <front>
<title>The Twin-Diffie Hellman Problem and Applications</title> <title>The Twin-Diffie Hellman Problem and Applications</title>
<author> <author initials="D" surname="Cash" fullname="David Cash">
<organization/> <organization/>
</author> </author>
<date year="2008"/> <author initials="E" surname="Kiltz" fullname="Eike Kiltz">
</front>
<seriesInfo name="EUROCRYPT 2008, Volume 4965 of Lecture notes in Comp
uter Science, pages 127-145, Springer-Verlag, Berlin, Germany" value=""/>
</reference>
<reference anchor="SPAKE2P-Analysis" target="https://eprint.iacr.org/202
0/313.pdf">
<front>
<title>Security analysis of SPAKE2+</title>
<author>
<organization/> <organization/>
</author> </author>
<date year="2020"/> <author initials="V" surname="Shoup" fullname="Victor Shoup">
</front>
</reference>
<reference anchor="SEC1" target="https://secg.org/sec1-v2.pdf">
<front>
<title>Elliptic Curve Cryptography, Standards for Efficient Cryptogr
aphy Group, ver. 2</title>
<author>
<organization/> <organization/>
</author> </author>
<date year="2009"/> <date month="April" year="2008"/>
</front> </front>
<refcontent>EUROCRYPT 2008, Lecture Notes in Computer Science, Volume
4965, pages 127-145, Springer-Verlag, Berlin, Germany</refcontent>
<seriesInfo name="DOI" value="10.1007/978-3-540-78967-3_8"/>
</reference> </reference>
<reference anchor="I-D.irtf-cfrg-spake2">
<front>
<title>SPAKE2, a PAKE</title>
<author fullname="Watson Ladd">
<organization>Sealance</organization>
</author>
<author fullname="Benjamin Kaduk">
<organization>Akamai Technologies</organization>
</author>
<date day="8" month="February" year="2022"/>
<abstract>
<t> This document describes SPAKE2 which is a protocol for two p
arties
that share a password to derive a strong shared key without
disclosing the password. This method is compatible with any group,
is computationally efficient, and SPAKE2 has a security proof. This
document predated the CFRG PAKE competition and it was not selected,
however, given existing use of variants in Kerberos and other
applications it was felt publication was beneficial. Applications
that need a symmetric PAKE (password authenticated key exchange) and
where hashing onto an elliptic curve at execution time is not
possible can use SPAKE2. This document is a product of the Crypto
Forum Research Group (CFRG) in the IRTF.
</t> <reference anchor="SPAKE2P-Analysis" target="https://eprint.iacr.org/202
</abstract> 0/313.pdf">
</front>
<seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-spake2-26"/>
</reference>
<reference anchor="RFC2119">
<front>
<title>Key words for use in RFCs to Indicate Requirement Levels</tit
le>
<author fullname="S. Bradner" initials="S." surname="Bradner">
<organization/>
</author>
<date month="March" year="1997"/>
<abstract>
<t>In many standards track documents several words are used to sig
nify the requirements in the specification. These words are often capitalized.
This document defines these words as they should be interpreted in IETF document
s. This document specifies an Internet Best Current Practices for the Internet
Community, and requests discussion and suggestions for improvements.</t>
</abstract>
</front>
<seriesInfo name="BCP" value="14"/>
<seriesInfo name="RFC" value="2119"/>
<seriesInfo name="DOI" value="10.17487/RFC2119"/>
</reference>
<reference anchor="RFC8174">
<front>
<title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</ti
tle>
<author fullname="B. Leiba" initials="B." surname="Leiba">
<organization/>
</author>
<date month="May" year="2017"/>
<abstract>
<t>RFC 2119 specifies common key words that may be used in protoco
l specifications. This document aims to reduce the ambiguity by clarifying tha
t only UPPERCASE usage of the key words have the defined special meanings.</t>
</abstract>
</front>
<seriesInfo name="BCP" value="14"/>
<seriesInfo name="RFC" value="8174"/>
<seriesInfo name="DOI" value="10.17487/RFC8174"/>
</reference>
<reference anchor="RFC6234">
<front>
<title>US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)</
title>
<author fullname="D. Eastlake 3rd" initials="D." surname="Eastlake 3
rd">
<organization/>
</author>
<author fullname="T. Hansen" initials="T." surname="Hansen">
<organization/>
</author>
<date month="May" year="2011"/>
<abstract>
<t>Federal Information Processing Standard, FIPS</t>
</abstract>
</front>
<seriesInfo name="RFC" value="6234"/>
<seriesInfo name="DOI" value="10.17487/RFC6234"/>
</reference>
<reference anchor="RFC8265">
<front>
<title>Preparation, Enforcement, and Comparison of Internationalized
Strings Representing Usernames and Passwords</title>
<author fullname="P. Saint-Andre" initials="P." surname="Saint-Andre
">
<organization/>
</author>
<author fullname="A. Melnikov" initials="A." surname="Melnikov">
<organization/>
</author>
<date month="October" year="2017"/>
<abstract>
<t>This document describes updated methods for handling Unicode st
rings representing usernames and passwords. The previous approach was known as
SASLprep (RFC 4013) and was based on Stringprep (RFC 3454). The methods specifie
d in this document provide a more sustainable approach to the handling of intern
ationalized usernames and passwords. This document obsoletes RFC 7613.</t>
</abstract>
</front>
<seriesInfo name="RFC" value="8265"/>
<seriesInfo name="DOI" value="10.17487/RFC8265"/>
</reference>
<reference anchor="RFC5869">
<front>
<title>HMAC-based Extract-and-Expand Key Derivation Function (HKDF)<
/title>
<author fullname="H. Krawczyk" initials="H." surname="Krawczyk">
<organization/>
</author>
<author fullname="P. Eronen" initials="P." surname="Eronen">
<organization/>
</author>
<date month="May" year="2010"/>
<abstract>
<t>This document specifies a simple Hashed Message Authentication
Code (HMAC)-based key derivation function (HKDF), which can be used as a buildin
g block in various protocols and applications. The key derivation function (KDF
) is intended to support a wide range of applications and requirements, and is c
onservative in its use of cryptographic hash functions. This document is not an
Internet Standards Track specification; it is published for informational pur
poses.</t>
</abstract>
</front>
<seriesInfo name="RFC" value="5869"/>
<seriesInfo name="DOI" value="10.17487/RFC5869"/>
</reference>
<reference anchor="RFC2104">
<front>
<title>HMAC: Keyed-Hashing for Message Authentication</title>
<author fullname="H. Krawczyk" initials="H." surname="Krawczyk">
<organization/>
</author>
<author fullname="M. Bellare" initials="M." surname="Bellare">
<organization/>
</author>
<author fullname="R. Canetti" initials="R." surname="Canetti">
<organization/>
</author>
<date month="February" year="1997"/>
<abstract>
<t>This document describes HMAC, a mechanism for message authentic
ation using cryptographic hash functions. HMAC can be used with any iterative cr
yptographic hash function, e.g., MD5, SHA-1, in combination with a secret shared
key. The cryptographic strength of HMAC depends on the properties of the under
lying hash function. This memo provides information for the Internet community.
This memo does not specify an Internet standard of any kind</t>
</abstract>
</front>
<seriesInfo name="RFC" value="2104"/>
<seriesInfo name="DOI" value="10.17487/RFC2104"/>
</reference>
<reference anchor="RFC4493">
<front>
<title>The AES-CMAC Algorithm</title>
<author fullname="JH. Song" initials="JH." surname="Song">
<organization/>
</author>
<author fullname="R. Poovendran" initials="R." surname="Poovendran">
<organization/>
</author>
<author fullname="J. Lee" initials="J." surname="Lee">
<organization/>
</author>
<author fullname="T. Iwata" initials="T." surname="Iwata">
<organization/>
</author>
<date month="June" year="2006"/>
<abstract>
<t>The National Institute of Standards and Technology (NIST) has r
ecently specified the Cipher-based Message Authentication Code (CMAC), which is
equivalent to the One-Key CBC MAC1 (OMAC1) submitted by Iwata and Kurosawa. Thi
s memo specifies an authentication algorithm based on CMAC with the 128-bit Adva
nced Encryption Standard (AES). This new authentication algorithm is named AES-C
MAC. The purpose of this document is to make the AES-CMAC algorithm conveniently
available to the Internet Community. This memo provides information for the In
ternet community.</t>
</abstract>
</front>
<seriesInfo name="RFC" value="4493"/>
<seriesInfo name="DOI" value="10.17487/RFC4493"/>
</reference>
<reference anchor="RFC8032">
<front> <front>
<title>Edwards-Curve Digital Signature Algorithm (EdDSA)</title> <title>Security analysis of SPAKE2+</title>
<author fullname="S. Josefsson" initials="S." surname="Josefsson"> <author initials="V." surname="Shoup" fullname="Victor Shoup">
<organization/>
</author>
<author fullname="I. Liusvaara" initials="I." surname="Liusvaara">
<organization/> <organization/>
</author> </author>
<date month="January" year="2017"/> <date month="March" year="2020"/>
<abstract>
<t>This document describes elliptic curve signature scheme Edwards
-curve Digital Signature Algorithm (EdDSA). The algorithm is instantiated with
recommended parameters for the edwards25519 and edwards448 curves. An example i
mplementation and test vectors are provided.</t>
</abstract>
</front> </front>
<seriesInfo name="RFC" value="8032"/>
<seriesInfo name="DOI" value="10.17487/RFC8032"/>
</reference> </reference>
<reference anchor="RFC5480">
<reference anchor="SEC1" target="https://secg.org/sec1-v2.pdf">
<front> <front>
<title>Elliptic Curve Cryptography Subject Public Key Information</t <title>SEC 1: Elliptic Curve Cryptography</title>
itle> <author>
<author fullname="S. Turner" initials="S." surname="Turner"> <organization>Standards for Efficient Cryptography Group</organiza
<organization/> tion>
</author>
<author fullname="D. Brown" initials="D." surname="Brown">
<organization/>
</author>
<author fullname="K. Yiu" initials="K." surname="Yiu">
<organization/>
</author>
<author fullname="R. Housley" initials="R." surname="Housley">
<organization/>
</author>
<author fullname="T. Polk" initials="T." surname="Polk">
<organization/>
</author> </author>
<date month="March" year="2009"/> <date month="May" year="2009"/>
<abstract>
<t>This document specifies the syntax and semantics for the Subjec
t Public Key Information field in certificates that support Elliptic Curve Crypt
ography. This document updates Sections 2.3.5 and 5, and the ASN.1 module of "A
lgorithms and Identifiers for the Internet X.509 Public Key Infrastructure Certi
ficate and Certificate Revocation List (CRL) Profile", RFC 3279. [STANDARDS-TRA
CK]</t>
</abstract>
</front> </front>
<seriesInfo name="RFC" value="5480"/> <refcontent>version 2.0</refcontent>
<seriesInfo name="DOI" value="10.17487/RFC5480"/>
</reference> </reference>
<!-- draft-irtf-cfrg-spake2 (RFC 9382) -->
<reference anchor='RFC9382' target='https://www.rfc-editor.org/info/rfc9382'>
<front>
<title>SPAKE2, a Password-Authenticated Key Exchange</title>
<author initials='W' surname='Ladd' fullname='Watson Ladd'>
<organization />
</author>
<date year='2023' month='September' />
</front>
<seriesInfo name="RFC" value="9382"/>
<seriesInfo name="DOI" value="10.17487/RFC9382"/>
</reference>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"
/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"
/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6234.xml"
/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8265.xml"
/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5869.xml"
/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2104.xml"
/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4493.xml"
/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8032.xml"
/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5480.xml"
/>
</references> </references>
<references> <references>
<name>Informative References</name> <name>Informative References</name>
<reference anchor="RFC7914">
<front> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7914.xml"
<title>The scrypt Password-Based Key Derivation Function</title> />
<author fullname="C. Percival" initials="C." surname="Percival"> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9106.xml"
<organization/> />
</author> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8844.xml"
<author fullname="S. Josefsson" initials="S." surname="Josefsson"> />
<organization/>
</author>
<date month="August" year="2016"/>
<abstract>
<t>This document specifies the password-based key derivation funct
ion scrypt. The function derives one or more secret keys from a secret string.
It is based on memory-hard functions, which offer added protection against atta
cks using custom hardware. The document also provides an ASN.1 schema.</t>
</abstract>
</front>
<seriesInfo name="RFC" value="7914"/>
<seriesInfo name="DOI" value="10.17487/RFC7914"/>
</reference>
<reference anchor="RFC9106">
<front>
<title>Argon2 Memory-Hard Function for Password Hashing and Proof-of
-Work Applications</title>
<author fullname="A. Biryukov" initials="A." surname="Biryukov">
<organization/>
</author>
<author fullname="D. Dinu" initials="D." surname="Dinu">
<organization/>
</author>
<author fullname="D. Khovratovich" initials="D." surname="Khovratovi
ch">
<organization/>
</author>
<author fullname="S. Josefsson" initials="S." surname="Josefsson">
<organization/>
</author>
<date month="September" year="2021"/>
<abstract>
<t>This document describes the Argon2 memory-hard function for pas
sword hashing and proof-of-work applications. We provide an implementer-oriente
d description with test vectors. The purpose is to simplify adoption of Argon2
for Internet protocols. This document is a product of the Crypto Forum Research
Group (CFRG) in the IRTF.</t>
</abstract>
</front>
<seriesInfo name="RFC" value="9106"/>
<seriesInfo name="DOI" value="10.17487/RFC9106"/>
</reference>
<reference anchor="RFC8844">
<front>
<title>Unknown Key-Share Attacks on Uses of TLS with the Session Des
cription Protocol (SDP)</title>
<author fullname="M. Thomson" initials="M." surname="Thomson">
<organization/>
</author>
<author fullname="E. Rescorla" initials="E." surname="Rescorla">
<organization/>
</author>
<date month="January" year="2021"/>
<abstract>
<t>This document describes unknown key-share attacks on the use of
Datagram Transport Layer Security for the Secure Real-Time Transport Protocol (
DTLS-SRTP). Similar attacks are described on the use of DTLS-SRTP with the ident
ity bindings used in Web Real-Time Communications (WebRTC) and SIP identity. Th
ese attacks are difficult to mount, but they cause a victim to be misled about t
he identity of a communicating peer. This document defines mitigation technique
s that implementations of RFC 8122 are encouraged to deploy.</t>
</abstract>
</front>
<seriesInfo name="RFC" value="8844"/>
<seriesInfo name="DOI" value="10.17487/RFC8844"/>
</reference>
</references> </references>
</references> </references>
<section anchor="flow" numbered="true" toc="default"> <section anchor="flow" numbered="true" toc="default">
<name>Protocol Flow</name> <name>Protocol Flow</name>
<t>This section describes the flow of the SPAKE2+ protocol, including comp utations <t>This section describes the flow of the SPAKE2+ protocol, including comp utations
and mandatory checks performed by the prover and verifier. The constants M, N, and mandatory checks performed by the Prover and Verifier. The constants M, N,
P, p, and h are defined by the chosen ciphersuite.</t> P, p, and h are defined by the chosen ciphersuite.</t>
<section anchor="prover" numbered="true" toc="default"> <section anchor="prover" numbered="true" toc="default">
<name>Prover</name> <name>Prover</name>
<t>The Prover's behavior consists of two functions, ProverInit and Prove rFinish, which <t>The Prover implements two functions, ProverInit and ProverFinish, whi ch
are described below.</t> are described below.</t>
<artwork name="" type="" align="left" alt=""><![CDATA[
<sourcecode type="pseudocode"><![CDATA[
def ProverInit(w0): def ProverInit(w0):
// Compute prover key share // Compute Prover key share
x <- [0, p-1] x <- [0, p-1]
X = x*P + w0*M X = x*P + w0*M
return (x, X) return (x, X)
def ProverFinish(w0, w1, x, Y): def ProverFinish(w0, w1, x, Y):
if not_in_subgroup(Y): if not_in_subgroup(Y):
raise "invalid input" raise "invalid input"
// Compute shared values // Compute shared values
Z = h*x*(Y - w0*N) Z = h*x*(Y - w0*N)
V = h*w1*(Y - w0*N) V = h*w1*(Y - w0*N)
return (Y, Z, V) return (Y, Z, V)
]]></artwork> ]]></sourcecode>
</section> </section>
<section anchor="verifier" numbered="true" toc="default"> <section anchor="verifier" numbered="true" toc="default">
<name>Verifier</name> <name>Verifier</name>
<t>The Verifier's behavior consists of a single function, VerifierFinish , which <t>The Verifier implements a single function, VerifierFinish, which
is described below.</t> is described below.</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode type="pseudocode"><![CDATA[
def VerifierFinish(w0, L, X): def VerifierFinish(w0, L, X):
if not_in_subgroup(X): if not_in_subgroup(X):
raise "invalid input" raise "invalid input"
// Compute verifier key share // Compute Verifier key share
y <- [0, p-1] y <- [0, p-1]
Y = y*P + w0*N Y = y*P + w0*N
// Compute shared values // Compute shared values
Z = h*y*(X - w0*M) Z = h*y*(X - w0*M)
V = h*y*L V = h*y*L
return (Z, V) return (Z, V)
]]></artwork> ]]></sourcecode>
</section> </section>
<section anchor="transcript-computation" numbered="true" toc="default"> <section anchor="transcript-computation" numbered="true" toc="default">
<name>Transcript Computation</name> <name>Transcript Computation</name>
<t>Both Prover and Verifier share the same function to compute the proto
col <t>Both the Prover and the Verifier share the same function to compute t
he protocol
transcript, ComputeTranscript, which is described below.</t> transcript, ComputeTranscript, which is described below.</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode type="pseudocode"><![CDATA[
def ComputeTranscript(Context, idProver, idVerifier, shareP, shareV, Z, V, w0): def ComputeTranscript(Context, idProver, idVerifier,
shareP, shareV, Z, V, w0):
TT = len(Context) || Context TT = len(Context) || Context
|| len(idProver) || idProver || len(idProver) || idProver
|| len(idVerifier) || idVerifier || len(idVerifier) || idVerifier
|| len(M) || M || len(M) || M
|| len(N) || N || len(N) || N
|| len(shareP) || shareP || len(shareP) || shareP
|| len(shareV) || shareV || len(shareV) || shareV
|| len(Z) || Z || len(Z) || Z
|| len(V) || V || len(V) || V
|| len(w0) || w0 || len(w0) || w0
]]></artwork> ]]></sourcecode>
</section> </section>
<section anchor="key-schedule-computation" numbered="true" toc="default"> <section anchor="key-schedule-computation" numbered="true" toc="default">
<name>Key Schedule Computation</name> <name>Key Schedule Computation</name>
<t>Both Prover and Verifier share the same function to compute <t>Both the Prover and the Verifier share the same function to compute
the key schedule, ComputeKeySchedule, which is described below.</t> the key schedule, ComputeKeySchedule, which is described below.</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode type="pseudocode"><![CDATA[
def ComputeKeySchedule(TT): def ComputeKeySchedule(TT):
K_main = Hash(TT) K_main = Hash(TT)
K_confirmP || K_confirmV = KDF(nil, K_main, "ConfirmationKeys") K_confirmP || K_confirmV = KDF(nil, K_main, "ConfirmationKeys")
K_shared = KDF(nil, K_main, "SharedKey") K_shared = KDF(nil, K_main, "SharedKey")
return K_confirmP, K_confirmV, K_shared return K_confirmP, K_confirmV, K_shared
]]></artwork> ]]></sourcecode>
</section> </section>
<section anchor="protocol-run" numbered="true" toc="default"> <section anchor="protocol-run" numbered="true" toc="default">
<name>Protocol Run</name> <name>Protocol Run</name>
<t>A full SPAKE2+ protocol run initiated by the prover will look as foll ows, <t>A full SPAKE2+ protocol run initiated by the Prover will look as foll ows,
where Transmit and Receive are shorthand for sending and receiving where Transmit and Receive are shorthand for sending and receiving
a message to the peer:</t> a message to the peer:</t>
<artwork name="" type="" align="left" alt=""><![CDATA[
<sourcecode type="pseudocode"><![CDATA[
Prover(Context, idProver, idVerifier, w0, w1): Prover(Context, idProver, idVerifier, w0, w1):
(x, X) = ProverInit(w0) (x, X) = ProverInit(w0)
Transmit(X) Transmit(X)
Y = Receive() Y = Receive()
(Z, V) = ProverFinish(w0, w1, x, Y) (Z, V) = ProverFinish(w0, w1, x, Y)
TT = ComputeTranscript(Context, idProver, idVerifier, X, Y, Z, V, w0) TT = ComputeTranscript(Context, idProver, idVerifier, X, Y,
Z, V, w0)
(K_confirmP, K_confirmV, K_shared) = ComputeKeySchedule(TT) (K_confirmP, K_confirmV, K_shared) = ComputeKeySchedule(TT)
expected_confirmV = MAC(K_confirmV, X) expected_confirmV = MAC(K_confirmV, X)
confirmV = Receive() confirmV = Receive()
if not_equal_constant_time(expected_confirmV, confirmV): if not_equal_constant_time(expected_confirmV, confirmV):
raise "invalid confirmation message" raise "invalid confirmation message"
confirmP = MAC(K_confirmP, Y) confirmP = MAC(K_confirmP, Y)
Transmit(confirmP) Transmit(confirmP)
return K_shared return K_shared
Verifier(Context, idProver, idVerifier, w0, L): Verifier(Context, idProver, idVerifier, w0, L):
X = Receive() X = Receive()
(Y, Z, V) = VerifierFinish(w0, L, X) (Y, Z, V) = VerifierFinish(w0, L, X)
Transmit(Y) Transmit(Y)
TT = ComputeTranscript(Context, idProver, idVerifier, X, Y, Z, V, w0) TT = ComputeTranscript(Context, idProver, idVerifier, X, Y,
Z, V, w0)
(K_confirmP, K_confirmV, K_shared) = ComputeKeySchedule(TT) (K_confirmP, K_confirmV, K_shared) = ComputeKeySchedule(TT)
confirmV = MAC(K_confirmV, X) confirmV = MAC(K_confirmV, X)
Transmit(confirmV) Transmit(confirmV)
expected_confirmP = MAC(K_confirmP, Y) expected_confirmP = MAC(K_confirmP, Y)
confirmP = Receive() confirmP = Receive()
if not_equal_constant_time(expected_confirmP, confirmP): if not_equal_constant_time(expected_confirmP, confirmP):
raise "invalid confirmation message" raise "invalid confirmation message"
return K_shared return K_shared
]]></artwork> ]]></sourcecode>
</section> </section>
</section> </section>
<section anchor="pointgen" numbered="true" toc="default"> <section anchor="pointgen" numbered="true" toc="default">
<name>Algorithm used for Point Generation</name> <name>Algorithm Used for Point Generation</name>
<t>This section describes the algorithm that was used to generate <t>This section describes the algorithm that was used to generate
the points M and N in the table in <xref target="Ciphersuites" format="default"/ >. This algorithm the points M and N in <xref target="tab-1"/> (<xref target="Ciphersuites"/>). Th is algorithm
produces M and N such that they are indistinguishable from two random produces M and N such that they are indistinguishable from two random
points in the prime-order subgroup of G, where the discrete log points in the prime-order subgroup of G, where the discrete log
of these points is unknown. See <xref target="SPAKE2P-Analysis" format="default" /> for additional of these points is unknown. See <xref target="SPAKE2P-Analysis" format="default" /> for additional
details on this requirement.</t> details on this requirement.</t>
<t>For each curve in the table below, we construct a string <t>For each curve in <xref target="tab-1"/>, we construct a string
using the curve OID from <xref target="RFC5480" format="default"/> (as an ASCII using the curve OID from <xref target="RFC5480" format="default"/> (as an ASCII
string) or its name, string) or its name,
combined with the needed constant, for instance "1.3.132.0.35 combined with the needed constant -- for instance, "1.3.132.0.35
point generation seed (M)" for P-512. This string is turned point generation seed (M)" for P-521. This string is turned
into a series of blocks by hashing with SHA256, and hashing that into a series of blocks by hashing with SHA256, and hashing that
output again to generate the next 32 bytes, and so on. This output again to generate the next 32 bytes, and so on. This
pattern is repeated for each group and value, with the string pattern is repeated for each group and value, with the string
modified appropriately.</t> modified appropriately.</t>
<t>A byte string of length equal to that of an encoded group <t>A byte string of length equal to that of an encoded group
element is constructed by concatenating as many blocks as are element is constructed by concatenating as many blocks as are
required, starting from the first block, and truncating to the required, starting from the first block, and truncating to the
desired length. The byte string is then formatted as required desired length. The byte string is then formatted as required
for the group. In the case of Weierstrass curves, we take the for the group. In the case of Weierstrass curves, we take the
desired length as the length for representing a compressed point desired length as the length for representing a compressed point
(section 2.3.4 of <xref target="SEC1" format="default"/>), (<xref target="SEC1" sectionFormat="of" section="2.3.4" relative="#subsubsection .2.3.4"/>)
and use the low-order bit of the first byte as the sign bit. and use the low-order bit of the first byte as the sign bit.
In order to obtain the correct format, the value of the first In order to obtain the correct format, the value of the first
byte is set to 0x02 or 0x03 (clearing the first six bits byte is set to 0x02 or 0x03 (clearing the first six bits
and setting the seventh bit), leaving the sign bit as it was and setting the seventh bit), leaving the sign bit as it was
in the byte string constructed by concatenating hash blocks. in the byte string constructed by concatenating hash blocks.
For the <xref target="RFC8032" format="default"/> curves a different procedure i For the curves described in <xref target="RFC8032" format="default"/>, a differe
s used. nt procedure is used.
For edwards448 the 57-byte input has the least-significant 7 bits of the For edwards448, the 57-byte input has the least-significant 7 bits of the
last byte set to zero, and for edwards25519 the 32-byte input is last byte set to zero, and for edwards25519, the 32-byte input is
not modified. For both the <xref target="RFC8032" format="default"/> curves the not modified. For both of the curves described in <xref target="RFC8032" format
="default"/>, the
(modified) input is then interpreted (modified) input is then interpreted
as the representation of the group element. as the representation of the group element.
If this interpretation yields a valid group element with the If this interpretation yields a valid group element with the
correct order (p), the (modified) byte string is the output. Otherwise, correct order (p), the (modified) byte string is the output. Otherwise,
the initial hash block is discarded and a new byte string constructed the initial hash block is discarded and a new byte string constructed
from the remaining hash blocks. The procedure of constructing a from the remaining hash blocks. The procedure for constructing a
byte string of the appropriate length, formatting it as byte string of the appropriate length, formatting it as
required for the curve, and checking if it is a valid point of the correct required for the curve, and checking to see if it is a valid point of the correc
order, is repeated t
order is repeated
until a valid element is found.</t> until a valid element is found.</t>
<t>The following python snippet generates the above points, <t>The following Python snippet generates the above points,
assuming an elliptic curve implementation following the assuming an elliptic curve implementation following the
interface of Edwards25519Point.stdbase() and interface of Edwards25519Point.stdbase() and
Edwards448Point.stdbase() in Appendix A of <xref target="RFC8032" format="defaul Edwards448Point.stdbase() in <xref target="RFC8032" sectionFormat="of" section="
t"/>:</t> A"/>:</t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode type="python"><![CDATA[
def iterated_hash(seed, n): def iterated_hash(seed, n):
h = seed h = seed
for i in range(n): for i in range(n):
h = hashlib.sha256(h).digest() h = hashlib.sha256(h).digest()
return h return h
def bighash(seed, start, sz): def bighash(seed, start, sz):
n = -(-sz // 32) n = -(-sz // 32)
hashes = [iterated_hash(seed, i) for i in range(start, start + n)] hashes = [iterated_hash(seed, i) for i in range(start, start + n)]
return b''.join(hashes)[:sz] return b''.join(hashes)[:sz]
skipping to change at line 966 skipping to change at line 774
def gen_point(seed, ecname, ec): def gen_point(seed, ecname, ec):
for i in range(1, 1000): for i in range(1, 1000):
hval = bighash(seed, i, len(ec.encode())) hval = bighash(seed, i, len(ec.encode()))
pointstr = canon_pointstr(ecname, hval) pointstr = canon_pointstr(ecname, hval)
try: try:
p = ec.decode(pointstr) p = ec.decode(pointstr)
if p != ec.zero_elem() and p * p.l() == ec.zero_elem(): if p != ec.zero_elem() and p * p.l() == ec.zero_elem():
return pointstr, i return pointstr, i
except Exception: except Exception:
pass pass
]]></artwork> ]]></sourcecode>
</section> </section>
<section anchor="testvectors" numbered="true" toc="default"> <section anchor="testvectors" numbered="true" toc="default">
<name>Test Vectors</name> <name>Test Vectors</name>
<t>This section contains various test vectors for SPAKE2+. <t>This section contains various test vectors for SPAKE2+.
(Choice of PBKDF is omitted and values for w0 and w1 are provided directly.) (The choice of PBKDF is omitted, and values for w0 and w1 are provided directly. )
All points are encoded using the uncompressed format, i.e., with a 0x04 octet All points are encoded using the uncompressed format, i.e., with a 0x04 octet
prefix, specified in <xref target="SEC1" format="default"/>. idProver and idVeri fier identity strings prefix, specified in <xref target="SEC1" format="default"/>. &nbsp;idProver and idVerifier identity strings
are provided in the protocol invocation.</t> are provided in the protocol invocation.</t>
<artwork name="" type="" align="left" alt=""><![CDATA[
<sourcecode type="test-vectors"><![CDATA[
[Context=b'SPAKE2+-P256-SHA256-HKDF-SHA256-HMAC-SHA256 Test Vectors [Context=b'SPAKE2+-P256-SHA256-HKDF-SHA256-HMAC-SHA256 Test Vectors
'] ']
[idProver=b'client'] [idProver=b'client']
[idVerifier=b'server'] [idVerifier=b'server']
w0 = 0xbb8e1bbcf3c48f62c08db243652ae55d3e5586053fca77102994f23ad9549 w0 = 0xbb8e1bbcf3c48f62c08db243652ae55d3e5586053fca77102994f23ad9549
1b3 1b3
w1 = 0x7e945f34d78785b8a3ef44d0df5a1a97d6b3b460409a345ca7830387a74b1 w1 = 0x7e945f34d78785b8a3ef44d0df5a1a97d6b3b460409a345ca7830387a74b1
dba dba
L = 0x04eb7c9db3d9a9eb1f8adab81b5794c1f13ae3e225efbe91ea487425854c7f L = 0x04eb7c9db3d9a9eb1f8adab81b5794c1f13ae3e225efbe91ea487425854c7f
c00f00bfedcbd09b2400142d40a14f2064ef31dfaa903b91d1faea7093d835966efd c00f00bfedcbd09b2400142d40a14f2064ef31dfaa903b91d1faea7093d835966efd
skipping to change at line 1029 skipping to change at line 838
K_confirmP = 0x871ae3f7b78445e34438fb284504240239031c39d80ac23eb5ab9 K_confirmP = 0x871ae3f7b78445e34438fb284504240239031c39d80ac23eb5ab9
be5ad6db58a be5ad6db58a
K_confirmV = 0xccd53c7c1fa37b64a462b40db8be101cedcf838950162902054e6 K_confirmV = 0xccd53c7c1fa37b64a462b40db8be101cedcf838950162902054e6
44b400f1680 44b400f1680
HMAC(K_confirmP, shareV) = 0x926cc713504b9b4d76c9162ded04b5493e89109 HMAC(K_confirmP, shareV) = 0x926cc713504b9b4d76c9162ded04b5493e89109
f6d89462cd33adc46fda27527 f6d89462cd33adc46fda27527
HMAC(K_confirmV, shareP) = 0x9747bcc4f8fe9f63defee53ac9b07876d907d55 HMAC(K_confirmV, shareP) = 0x9747bcc4f8fe9f63defee53ac9b07876d907d55
047e6ff2def2e7529089d3e68 047e6ff2def2e7529089d3e68
K_shared = 0x0c5f8ccd1413423a54f6c1fb26ff01534a87f893779c6e68666d772 K_shared = 0x0c5f8ccd1413423a54f6c1fb26ff01534a87f893779c6e68666d772
bfd91f3e7 bfd91f3e7
]]></sourcecode>
<sourcecode type="test-vectors"><![CDATA[
[Context=b'SPAKE2+-P256-SHA512-HKDF-SHA512-HMAC-SHA512 Test Vectors [Context=b'SPAKE2+-P256-SHA512-HKDF-SHA512-HMAC-SHA512 Test Vectors
'] ']
[idProver=b'client'] [idProver=b'client']
[idVerifier=b'server'] [idVerifier=b'server']
w0 = 0x1cc5207d6e34b8f7828206fb64b86aa9c712bc952abf251bb9f5856b24d8c w0 = 0x1cc5207d6e34b8f7828206fb64b86aa9c712bc952abf251bb9f5856b24d8c
8cc 8cc
w1 = 0x4279649e62532b01dc27d2ed39100ba350518fb969672061a01edce752d0e w1 = 0x4279649e62532b01dc27d2ed39100ba350518fb969672061a01edce752d0e
672 672
L = 0x043a348ad475d2200d46df876f1eb2e136056da31dafff52cc7762bf3be84d L = 0x043a348ad475d2200d46df876f1eb2e136056da31dafff52cc7762bf3be84d
e0097c4e69b0b9321326af1f0af4a14561a9c7b640cb5afd6822d14cb34830fc4511 e0097c4e69b0b9321326af1f0af4a14561a9c7b640cb5afd6822d14cb34830fc4511
skipping to change at line 1089 skipping to change at line 899
aa58f61 aa58f61
HMAC(K_confirmP, shareV) = 0x6b2469b56cf8ac3f94a8d0b533380ea6b3d0f46 HMAC(K_confirmP, shareV) = 0x6b2469b56cf8ac3f94a8d0b533380ea6b3d0f46
b3e12ee82550d49e129c2412728c9437a64ee5f80c8cdc5e8a30faa0a6deb8a52513 b3e12ee82550d49e129c2412728c9437a64ee5f80c8cdc5e8a30faa0a6deb8a52513
46ba81bb6fc955b2304fc 46ba81bb6fc955b2304fc
HMAC(K_confirmV, shareP) = 0x154174fc278a935e290b3352ba877e179fa9281 HMAC(K_confirmV, shareP) = 0x154174fc278a935e290b3352ba877e179fa9281
c0a76928faea703c72d383b267511a5cf084cb07147efece94e3cfd91944e7baab85 c0a76928faea703c72d383b267511a5cf084cb07147efece94e3cfd91944e7baab85
6858fbebc087167b0f409 6858fbebc087167b0f409
K_shared = 0x11887659d9e002f34fa6cc270d33570f001b2a3fc0522b643c07327 K_shared = 0x11887659d9e002f34fa6cc270d33570f001b2a3fc0522b643c07327
d09a4a9f47aab85813d13c585b53adf5ac9de5707114848f3dc31a4045f69a2cc197 d09a4a9f47aab85813d13c585b53adf5ac9de5707114848f3dc31a4045f69a2cc197
2b098 2b098
]]></sourcecode>
<sourcecode type="test-vectors"><![CDATA[
[Context=b'SPAKE2+-P384-SHA256-HKDF-SHA256-HMAC-SHA256 Test Vectors [Context=b'SPAKE2+-P384-SHA256-HKDF-SHA256-HMAC-SHA256 Test Vectors
'] ']
[idProver=b'client'] [idProver=b'client']
[idVerifier=b'server'] [idVerifier=b'server']
w0 = 0x097a61cbb1cee72bb654be96d80f46e0e3531151003903b572fc193f23377 w0 = 0x097a61cbb1cee72bb654be96d80f46e0e3531151003903b572fc193f23377
2c23c22228884a0d5447d0ab49a656ce1d2 2c23c22228884a0d5447d0ab49a656ce1d2
w1 = 0x18772816140e6c3c3938a693c600b2191118a34c7956e1f1cd5b0d519b56e w1 = 0x18772816140e6c3c3938a693c600b2191118a34c7956e1f1cd5b0d519b56e
a5858060966cfaf27679c9182129949e74f a5858060966cfaf27679c9182129949e74f
L = 0x04f27dd5384d6b9beb4c5022c94b1978d632779e1d3abe458611e734a529d0 L = 0x04f27dd5384d6b9beb4c5022c94b1978d632779e1d3abe458611e734a529d0
04e25053398e5dc9eeaa4ffa59743ca7ddbc0e7ce69155295cb2b846da83ee6a4449 04e25053398e5dc9eeaa4ffa59743ca7ddbc0e7ce69155295cb2b846da83ee6a4449
skipping to change at line 1154 skipping to change at line 965
K_confirmP = 0x2c8940419d94e53d5d240801e702c4658531aa7a9f14ec75f0d67 K_confirmP = 0x2c8940419d94e53d5d240801e702c4658531aa7a9f14ec75f0d67
f12fa84196c f12fa84196c
K_confirmV = 0x8e74afe16c53a44590ad6bf43aa89324978b8f20014336675f618 K_confirmV = 0x8e74afe16c53a44590ad6bf43aa89324978b8f20014336675f618
387f99f3fdc 387f99f3fdc
HMAC(K_confirmP, shareV) = 0x7ae825e242a5a1f86ad7db172c2c12fcb458b6a HMAC(K_confirmP, shareV) = 0x7ae825e242a5a1f86ad7db172c2c12fcb458b6a
2b1ddfc96b2b7cfd2eed5f7ab 2b1ddfc96b2b7cfd2eed5f7ab
HMAC(K_confirmV, shareP) = 0x1581062167d6a3d14493447cd170d408f6fdc58 HMAC(K_confirmV, shareP) = 0x1581062167d6a3d14493447cd170d408f6fdc58
e31225438db86214167426a7a e31225438db86214167426a7a
K_shared = 0x99758e838ae1a856589689fb55b6befe4e2382e6ebbeca1a6232a68 K_shared = 0x99758e838ae1a856589689fb55b6befe4e2382e6ebbeca1a6232a68
f9dc04c1a f9dc04c1a
]]></sourcecode>
<sourcecode type="test-vectors"><![CDATA[
[Context=b'SPAKE2+-P384-SHA512-HKDF-SHA512-HMAC-SHA512 Test Vectors [Context=b'SPAKE2+-P384-SHA512-HKDF-SHA512-HMAC-SHA512 Test Vectors
'] ']
[idProver=b'client'] [idProver=b'client']
[idVerifier=b'server'] [idVerifier=b'server']
w0 = 0xb8d44a0982b88abe19b724d4bdafba8c90dc93130e0bf4f8062810992326d w0 = 0xb8d44a0982b88abe19b724d4bdafba8c90dc93130e0bf4f8062810992326d
a126fd01db53e40250ca33a3ff302044cb0 a126fd01db53e40250ca33a3ff302044cb0
w1 = 0x2373e2071c3bb2a6d53ece57830d56f8080189816803c22375d6a4a514f9d w1 = 0x2373e2071c3bb2a6d53ece57830d56f8080189816803c22375d6a4a514f9d
161b64d0f05b97735b98b348f9b33cc2e30 161b64d0f05b97735b98b348f9b33cc2e30
L = 0x049ca7217ff6456bb2e2bcf71b31d9b1e5ed6e0c9700936ae617e990cee87e L = 0x049ca7217ff6456bb2e2bcf71b31d9b1e5ed6e0c9700936ae617e990cee87e
e1ce3a03629dd5532948c39b89f38b39f13c7f513c5b1ada00f6533a4a8b02b9cd04 e1ce3a03629dd5532948c39b89f38b39f13c7f513c5b1ada00f6533a4a8b02b9cd04
skipping to change at line 1225 skipping to change at line 1037
3fbc731 3fbc731
HMAC(K_confirmP, shareV) = 0x7f806ae56ea3e49a8b16ffee528086489418913 HMAC(K_confirmP, shareV) = 0x7f806ae56ea3e49a8b16ffee528086489418913
641f529d50ff92aa456ad4648e522f9540b403bff6bd94ee1adc95c7d1b2666f7ba6 641f529d50ff92aa456ad4648e522f9540b403bff6bd94ee1adc95c7d1b2666f7ba6
f9c10748bc7bfb4181d27 f9c10748bc7bfb4181d27
HMAC(K_confirmV, shareP) = 0x8daa262decb79cceda4421f4f8dacf22ec027c0 HMAC(K_confirmV, shareP) = 0x8daa262decb79cceda4421f4f8dacf22ec027c0
8e036f071beea563c8e00813a29807963ff9d7d6bbff48dd5bdcdd9ca9fd7ffc272b 8e036f071beea563c8e00813a29807963ff9d7d6bbff48dd5bdcdd9ca9fd7ffc272b
162258d981913f7253dcb 162258d981913f7253dcb
K_shared = 0x31e0075a823b9269af5769d71ef3b2f5001cbfe044584fe8551124a K_shared = 0x31e0075a823b9269af5769d71ef3b2f5001cbfe044584fe8551124a
217dad078415630bf3eda16b5a38341d418a6d72b3960f818a0926f0de88784b59d6 217dad078415630bf3eda16b5a38341d418a6d72b3960f818a0926f0de88784b59d6
a694b a694b
]]></sourcecode>
<sourcecode type="test-vectors"><![CDATA[
[Context=b'SPAKE2+-P521-SHA512-HKDF-SHA512-HMAC-SHA512 Test Vectors [Context=b'SPAKE2+-P521-SHA512-HKDF-SHA512-HMAC-SHA512 Test Vectors
'] ']
[idProver=b'client'] [idProver=b'client']
[idVerifier=b'server'] [idVerifier=b'server']
w0 = 0x009c79bcd7656716314fca5a6e2c5cda7ef86131399438e012a043051e863 w0 = 0x009c79bcd7656716314fca5a6e2c5cda7ef86131399438e012a043051e863
f60b5aeb3c101731e1505e721580f48535a9b0456b231b9266ae6fff49ee90d25f72 f60b5aeb3c101731e1505e721580f48535a9b0456b231b9266ae6fff49ee90d25f72
f5f f5f
w1 = 0x01632c15f51fcd916cd79e19075f8a69b72b0099922ad62ff8d540b469569 w1 = 0x01632c15f51fcd916cd79e19075f8a69b72b0099922ad62ff8d540b469569
f0aa027047aed2b3f242ea0ac4288b4e4db6a4e5946d8ad32b42192c5aa66d9ef8e1 f0aa027047aed2b3f242ea0ac4288b4e4db6a4e5946d8ad32b42192c5aa66d9ef8e1
b33 b33
skipping to change at line 1312 skipping to change at line 1125
d18f0c6 d18f0c6
HMAC(K_confirmP, shareV) = 0xf0f5c903dfa42fe367659656a26058cd984b76a HMAC(K_confirmP, shareV) = 0xf0f5c903dfa42fe367659656a26058cd984b76a
8e91ae4d0fa4c13db149008e2ae57713fb230a627761174fefd263b9c10e9a4b6a37 8e91ae4d0fa4c13db149008e2ae57713fb230a627761174fefd263b9c10e9a4b6a37
46cde59c5943040c17133 46cde59c5943040c17133
HMAC(K_confirmV, shareP) = 0xa8f7ab43f3a800171d3a3fb26d742e1ed236c2d HMAC(K_confirmV, shareP) = 0xa8f7ab43f3a800171d3a3fb26d742e1ed236c2d
5804ecd328f220a7d245cd2e3bfb6c0526983bff9229c94f70fe64ba9bb5a4d0dc10 5804ecd328f220a7d245cd2e3bfb6c0526983bff9229c94f70fe64ba9bb5a4d0dc10
afcda64a4c96d4c3d81ad afcda64a4c96d4c3d81ad
K_shared = 0xd1c170e4e55efacb9db8abad286293ebd1dcf24f13973427b9632bb K_shared = 0xd1c170e4e55efacb9db8abad286293ebd1dcf24f13973427b9632bb
c323e42e447afca2aa7f74f2af3fb5f51684ec543db854b7002cde6799c330b032ba c323e42e447afca2aa7f74f2af3fb5f51684ec543db854b7002cde6799c330b032ba
8820a 8820a
]]></sourcecode>
<sourcecode type="test-vectors"><![CDATA[
[Context=b'SPAKE2+-P256-SHA256-HKDF-SHA256-CMAC-AES-128 Test Vector [Context=b'SPAKE2+-P256-SHA256-HKDF-SHA256-CMAC-AES-128 Test Vector
s'] s']
[idProver=b'client'] [idProver=b'client']
[idVerifier=b'server'] [idVerifier=b'server']
w0 = 0x9aad90c603cf16cec4ee40d81acd7a865130b28cc6d0664ae2e0f406aa47e w0 = 0x9aad90c603cf16cec4ee40d81acd7a865130b28cc6d0664ae2e0f406aa47e
d61 d61
w1 = 0x872be859cec1e78d191882bd9c2f032af018a25016813788fe8954bfffc58 w1 = 0x872be859cec1e78d191882bd9c2f032af018a25016813788fe8954bfffc58
c8e c8e
L = 0x04d79a53698c5dd79e14b426e73b4a7f1b42469815fe24e8f53ce01579e902 L = 0x04d79a53698c5dd79e14b426e73b4a7f1b42469815fe24e8f53ce01579e902
eb198d59f05bc451c41826b88e3db5476a69e197fdf474c75b387f6d40361c3fda35 eb198d59f05bc451c41826b88e3db5476a69e197fdf474c75b387f6d40361c3fda35
skipping to change at line 1362 skipping to change at line 1176
55706f0b062aa880617bd219d09391ad8576d3a73e9233f5720000000000000009aa 55706f0b062aa880617bd219d09391ad8576d3a73e9233f5720000000000000009aa
d90c603cf16cec4ee40d81acd7a865130b28cc6d0664ae2e0f406aa47ed61 d90c603cf16cec4ee40d81acd7a865130b28cc6d0664ae2e0f406aa47ed61
K_main = 0x6002da6b2740056f2836ac0316ae9e02e2b24c5c109883136e90ed868 K_main = 0x6002da6b2740056f2836ac0316ae9e02e2b24c5c109883136e90ed868
b2fcf62 b2fcf62
K_confirmP = 0x857d0db7f5e06385853bf4b8abd43b5a K_confirmP = 0x857d0db7f5e06385853bf4b8abd43b5a
K_confirmV = 0x268c75933332157118063550c6bfe846 K_confirmV = 0x268c75933332157118063550c6bfe846
CMAC(K_confirmP, shareV) = 0xd340bc94a03feafd14491e316514ca5f CMAC(K_confirmP, shareV) = 0xd340bc94a03feafd14491e316514ca5f
CMAC(K_confirmV, shareP) = 0x2b42d0fe76bcf9ccc208d06d60082f96 CMAC(K_confirmV, shareP) = 0x2b42d0fe76bcf9ccc208d06d60082f96
K_shared = 0xe832094adfc028bf288e49ab902fc208b7eeff084f259da7613c047 K_shared = 0xe832094adfc028bf288e49ab902fc208b7eeff084f259da7613c047
9869d4fc9 9869d4fc9
]]></sourcecode>
<sourcecode type="test-vectors"><![CDATA[
[Context=b'SPAKE2+-P256-SHA512-HKDF-SHA512-CMAC-AES-128 Test Vector [Context=b'SPAKE2+-P256-SHA512-HKDF-SHA512-CMAC-AES-128 Test Vector
s'] s']
[idProver=b'client'] [idProver=b'client']
[idVerifier=b'server'] [idVerifier=b'server']
w0 = 0x56e0299ac95739b616a973276c1338e3651285345dde2f7faf74c25c0b50e w0 = 0x56e0299ac95739b616a973276c1338e3651285345dde2f7faf74c25c0b50e
b90 b90
w1 = 0x462fe5b522a17d3d35b27323113bdd252de9cbfdd6f264b35721bf59a9a74 w1 = 0x462fe5b522a17d3d35b27323113bdd252de9cbfdd6f264b35721bf59a9a74
f0b f0b
L = 0x040540332ffec8a2faa8d17ae6da5973c11e078b8c10c89fd6af996726b802 L = 0x040540332ffec8a2faa8d17ae6da5973c11e078b8c10c89fd6af996726b802
3513eff2914c3ced64fbedd4e261438fb0ea6ef9fc1faef4ba1ead780636faac1bc1 3513eff2914c3ced64fbedd4e261438fb0ea6ef9fc1faef4ba1ead780636faac1bc1
skipping to change at line 1414 skipping to change at line 1229
K_main = 0x111790ae23de3fc5bb43bdc1f63106461dbd8d86360adf056bf117164 K_main = 0x111790ae23de3fc5bb43bdc1f63106461dbd8d86360adf056bf117164
8bfb231503853db2625275b7136b5a823dd5a94482514fce7f791c4daca2b21c7bde 8bfb231503853db2625275b7136b5a823dd5a94482514fce7f791c4daca2b21c7bde
756 756
K_confirmP = 0xb234d2e152a03168b76c6474d5322070 K_confirmP = 0xb234d2e152a03168b76c6474d5322070
K_confirmV = 0x683d62024626fe0c5126ef4df58b88ee K_confirmV = 0x683d62024626fe0c5126ef4df58b88ee
CMAC(K_confirmP, shareV) = 0x0dc514d262e37470eb43e058e0d615f4 CMAC(K_confirmP, shareV) = 0x0dc514d262e37470eb43e058e0d615f4
CMAC(K_confirmV, shareP) = 0xde076589efcd5d96c2ea6061d96772d9 CMAC(K_confirmV, shareP) = 0xde076589efcd5d96c2ea6061d96772d9
K_shared = 0x488a34663d6be5e02590bb8e9ad9ad3e0f580dec41e8b99ed4ae4b7 K_shared = 0x488a34663d6be5e02590bb8e9ad9ad3e0f580dec41e8b99ed4ae4b7
34da49287638cac4c9f17fe3c3ae18dda0d6d7f14c17e4640d5a2aaab959efa0cbea 34da49287638cac4c9f17fe3c3ae18dda0d6d7f14c17e4640d5a2aaab959efa0cbea
4e546 4e546
]]></artwork> ]]></sourcecode>
</section>
<section anchor="acknowledgements" numbered="false" toc="default">
<name>Acknowledgements</name>
<t>Thanks to <contact fullname="Ben Kaduk"/> and <contact fullname="Watson
Ladd"/>, from whom this specification originally emanated.</t>
</section> </section>
</back> </back>
<!-- ##markdown-source:
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
j9nkaWAKE3D4mCrIqFbwZACV6oPphEMB1h8cj0Bz8PoEih5XflB49VD7X/pB
tf9kdkOHbwtjrFAoea9NSlyHNy5cpUI+dl/FwchNbGbGZkXxvUlYsoP7456c
M3ZrgWKovNjyg9SxItttHJJLYUo+bqsbKaW4P668lDPUrJe6JqpsHNPWRasy
82AT5nFWUXLu81TYt5fpmtZU7ivrfkqQvVVnq8M6S09/gqefPn76IidM2a3R
DTLfJk9/HPbS/DiUiRVOhVbSLevZ38OwpsOF2vZgeNYpPj0rYSLkllZxSoUF
nPp8eUMloZBg3vgwLMpdrcO1X5bIe2PO14crWtidNpcUcIscaer3V29Su9P7
2Xj3doNfjuTTUElltt5gmxAo5U0h0JLZar5NmYxtf0xDPJp69KF2YGK2O5e8
OhkqHrIBfkPrGbfKSMruFSpGOdklYMMS3VTT08bazXbPL9tNR21todrJI99q
t1gWxZe4Lm3je/z08ScsGz6mYUHbU/dNLa2NXoOFwjlQiLzvgLclUGnjwXQ9
Ej5qZ3my7GYZ1ryG2r1xm/MO4x8XZco2psfTb9ls4ZMw1sNOhpNqt5A51Q2P
S5GZil2Z2aqU6masmiDAutgjew6zO80lwaef48pTsv3yQVm0m3Zz2pFbCUfy
82lFK8WwOXefDOaa1odL3TGdNXKeKRE9r6wStqrTZeGJOjBuF6mbkhD77CSh
xUkuPD4wnFXaJDlsY3gxy1tWQ6mBHhep2BAX7a0aHcrdp/VIWpaf2fzVuNfH
xIhnsbQilHZV2BmRnZPJUsiYxyp5370U7xRzUxS2WKYRTZaT12P+Yqh/27Gq
VCWQw7Tt2HHJ/PpyQUm/l6kWmw87dWfni1x8UUK36aymCDdluofYOfemJMJL
evWX6rP9wpxUVE4vaMTpBY0hVc388mi/8qZ88OjAC7Sd1eWXQU2mRen0IFLN
na+KxvxSTRR2R22qvVb3S90nrW6/utXq9qudVqVq/h36Orb6D+1rK/g/vNXg
X9ORJqJtuf6HC6I03jTq30Ea76llU6JQvmsaLX+rmt3XbKJ6eeWQwKdwku0e
HOBO2oxIZp73hg31DpRbSzUquXB83DuVK2km4HAyOWxhizzbRMp+IRDFFHDX
aT217D6hxa3JDq7SS1P2u062c6VV3OJuxy8IjUqdSC0FPWEskWU5Vi+1OmZM
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
HmsQy3Xp2Pj/AySLEbKFzgAA
</rfc> </rfc>
 End of changes. 143 change blocks. 
1013 lines changed or deleted 355 lines changed or added

This html diff was produced by rfcdiff 1.48.