summaryrefslogtreecommitdiff
path: root/doc/rfc/rfc9383.txt
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-11-27 20:54:24 +0100
committerThomas Voss <mail@thomasvoss.com> 2024-11-27 20:54:24 +0100
commit4bfd864f10b68b71482b35c818559068ef8d5797 (patch)
treee3989f47a7994642eb325063d46e8f08ffa681dc /doc/rfc/rfc9383.txt
parentea76e11061bda059ae9f9ad130a9895cc85607db (diff)
doc: Add RFC documents
Diffstat (limited to 'doc/rfc/rfc9383.txt')
-rw-r--r--doc/rfc/rfc9383.txt1283
1 files changed, 1283 insertions, 0 deletions
diff --git a/doc/rfc/rfc9383.txt b/doc/rfc/rfc9383.txt
new file mode 100644
index 0000000..cbe97d1
--- /dev/null
+++ b/doc/rfc/rfc9383.txt
@@ -0,0 +1,1283 @@
+
+
+
+
+Independent Submission T. Taubert
+Request for Comments: 9383 Apple Inc.
+Category: Informational C. A. Wood
+ISSN: 2070-1721 September 2023
+
+
+ SPAKE2+, an Augmented Password-Authenticated Key Exchange (PAKE)
+ Protocol
+
+Abstract
+
+ 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 disclosing the password. SPAKE2+
+ is an augmented PAKE protocol, as only one party has knowledge of the
+ password. This method is simple to implement, compatible with any
+ prime-order group, and computationally efficient.
+
+ 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 does not imply
+ endorsement of SPAKE2+ by the IETF or IRTF.
+
+Status of This Memo
+
+ This document is not an Internet Standards Track specification; it is
+ published for informational purposes.
+
+ This is a contribution to the RFC Series, independently of any other
+ RFC stream. The RFC Editor has chosen to publish this document at
+ its discretion and makes no statement about its value for
+ implementation or deployment. Documents approved for publication by
+ the RFC Editor are not candidates for any level of Internet Standard;
+ see Section 2 of RFC 7841.
+
+ Information about the current status of this document, any errata,
+ and how to provide feedback on it may be obtained at
+ https://www.rfc-editor.org/info/rfc9383.
+
+Copyright Notice
+
+ Copyright (c) 2023 IETF Trust and the persons identified as the
+ document authors. All rights reserved.
+
+ This document is subject to BCP 78 and the IETF Trust's Legal
+ Provisions Relating to IETF Documents
+ (https://trustee.ietf.org/license-info) in effect on the date of
+ publication of this document. Please review these documents
+ carefully, as they describe your rights and restrictions with respect
+ to this document.
+
+Table of Contents
+
+ 1. Introduction
+ 2. Requirements Notation
+ 3. Definition of SPAKE2+
+ 3.1. Protocol Overview
+ 3.2. Offline Registration
+ 3.3. Online Authentication
+ 3.4. Key Schedule and Key Confirmation
+ 4. Ciphersuites
+ 5. IANA Considerations
+ 6. Security Considerations
+ 7. References
+ 7.1. Normative References
+ 7.2. Informative References
+ Appendix A. Protocol Flow
+ A.1. Prover
+ A.2. Verifier
+ A.3. Transcript Computation
+ A.4. Key Schedule Computation
+ A.5. Protocol Run
+ Appendix B. Algorithm Used for Point Generation
+ Appendix C. Test Vectors
+ Acknowledgements
+ Authors' Addresses
+
+1. Introduction
+
+ 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 disclosing the password. 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 first party's registration
+ at the time of the protocol execution instead of the password. This
+ record can be computed once, during an offline registration phase.
+ The party using the password directly would typically be a client and
+ would act as a Prover, while the other party would be a server and
+ would act as a Verifier.
+
+ 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.
+ Hence, this protocol can be advantageously combined with a salted
+ Password Hashing 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, making this protocol more
+ robust than balanced PAKEs, which don't benefit from Password Hashing
+ Functions to the same extent.
+
+ This augmented property is especially valuable in scenarios where the
+ execution of the protocol is constrained and the adversary cannot
+ query the salt of the Password Hashing Function ahead of the attack.
+ For example, a constraint may be when physical proximity through a
+ local network is required or when a first authentication factor is
+ required for initiation of the protocol.
+
+ This document has content split out from a related document,
+ [RFC9382], which specifies SPAKE2. SPAKE2 is a symmetric PAKE
+ protocol, where both parties have 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 symmetric and augmented
+ PAKEs are different and therefore warrant different technical
+ specifications. Neither SPAKE2 nor SPAKE2+ was selected as the
+ result of the Crypto Forum Research Group (CFRG) PAKE selection
+ competition. However, this password-based key exchange protocol
+ appears in [TDH] and is proven secure in [SPAKE2P-Analysis]. It is
+ compatible with any prime-order group and relies only on group
+ operations, making it simple and computationally efficient. Thus, it
+ was felt that publication was beneficial to make the protocol
+ available for wider consideration.
+
+ 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 does not imply
+ endorsement of SPAKE2+ by the IETF or IRTF.
+
+2. Requirements Notation
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
+ "OPTIONAL" in this document are to be interpreted as described in
+ BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
+ capitals, as shown here.
+
+3. Definition of SPAKE2+
+
+ 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; 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
+ operations in the group additively. We assume that there is a
+ representation of elements of G as byte strings: common choices would
+ be SEC 1 uncompressed or compressed [SEC1] for elliptic curve groups
+ or big-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 in the document defining the group, and so we do not
+ repeat it here.
+
+ || denotes concatenation of strings. We also let len(S) denote the
+ length of a string in bytes, represented as an eight-byte little-
+ endian number. Finally, let nil represent an empty string, i.e.,
+ len(nil) = 0.
+
+ 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 cryptographic key of length L. MAC is a Message
+ Authentication Code algorithm that takes a secret key and message as
+ input to produce an output. Let Hash be a hash function from
+ arbitrary strings to bit strings of a fixed length. Common choices
+ for Hash are SHA256 or SHA512 [RFC6234]. Section 4 specifies
+ variants of KDF, MAC, and Hash suitable for use with the protocols
+ contained herein.
+
+ Let there be two parties, a Prover and a Verifier. Their identities,
+ denoted as idProver and idVerifier, may also have digital
+ representations such as Media Access Control addresses or other names
+ (hostnames, usernames, etc.). The parties may share additional data
+ (the context) separate from their identities, which they may want to
+ include in the protocol transcript. One example of additional data
+ is a list of supported protocol versions if SPAKE2+ were used in a
+ higher-level protocol that negotiates the use of a particular PAKE.
+ Another example is the inclusion of the application name. Including
+ these data points would ensure that both parties agree upon the same
+ set of supported protocols and therefore prevents downgrade and
+ cross-protocol attacks. Specification of precise context values is
+ out of scope for this document.
+
+3.1. Protocol Overview
+
+ SPAKE2+ is a two-round protocol that establishes a shared secret with
+ an additional round for key confirmation. Prior to invocation, both
+ parties are provisioned with information such as the input password
+ needed to run the protocol. The registration phase may include
+ communicating identities, protocol version, and other parameters
+ related to the registration record; see Section 3.2 for details.
+
+ During the first round, the Prover sends a public share, shareP, to
+ the Verifier, which in turn responds with its own public share,
+ shareV. Both parties then derive a shared secret used to produce
+ encryption and authentication keys. The latter are used during the
+ second round for key confirmation. (Section 3.4 details the key
+ derivation and confirmation steps.) In particular, the Verifier
+ sends a key confirmation message, confirmV, to the Prover, which in
+ turn responds with its own key confirmation message, confirmP. (Note
+ that shareV and confirmV MAY be sent in the same message.) Both
+ parties MUST NOT consider the protocol complete prior to receipt and
+ validation of these key confirmation messages.
+
+ A sample trace is shown below.
+
+ Prover Verifier
+
+ | (registration) |
+ |<- - - - - - - - - - - - ->|
+ | |
+ | (set up the protocol) |
+ (compute shareP) | shareP |
+ |-------------------------->|
+ | shareV | (compute shareV)
+ |<--------------------------|
+ | |
+ | (derive secrets) | (compute confirmV)
+ | confirmV |
+ |<--------------------------|
+ (compute confirmP) | confirmP |
+ |-------------------------->|
+
+3.2. Offline Registration
+
+ 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 identities of the two participants. w0 and the
+ record L are then shared with the Verifier and 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 and w1 are derived using a function with range [0, p-1], which is
+ modeled as a random oracle in [SPAKE2P-Analysis].
+
+ 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 Appendix B. Importantly, this algorithm chooses M and
+ N such that their discrete logs are not known. Precomputed values
+ for M and N are listed in Section 4 for each group. Applications MAY
+ use different M and N values, provided they are computed, e.g., using
+ different input seeds to the algorithm in Appendix B, as random
+ elements for which the discrete log is unknown.
+
+ Applications using this specification MUST define the method used to
+ compute w0 and w1. For example, it may be necessary to carry out
+ various forms of normalization of the password before hashing
+ [RFC8265]. This section contains requirements and default
+ recommendations for computing w0 and w1.
+
+ The RECOMMENDED method for generating w0 and w1 is via a Password-
+ Based Key Derivation Function (PBKDF), which is a function designed
+ to slow down brute-force attackers. Brute-force resistance may be
+ obtained through various computation hardness parameters such as
+ memory or CPU cycles and are typically configurable. The scrypt
+ [RFC7914] function and the Argon2id [RFC9106] function are common
+ examples of PBKDFs. Absent an application-specific profile,
+ RECOMMENDED parameters (N, r, p) for scrypt are (32768,8,1), and
+ RECOMMENDED parameters for Argon2id are in Section 4 of [RFC9106].
+
+ Each half of the output of the PBKDF will be interpreted as an
+ integer and reduced modulo p. To control bias, each half must be of
+ length at least ceil(log2(p)) + k bits, with k >= 64. Reducing such
+ integers mod p gives bias at most 2^-k for any p; this bias is
+ negligible for any k >= 64.
+
+ 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 SHOULD be at least 640 bits or
+ 80 bytes.
+
+ Given a PBKDF, password pw, and identities idProver and idVerifier,
+ the RECOMMENDED method for computing w0 and w1 is as follows:
+
+ w0s || w1s = PBKDF(len(pw) || pw ||
+ len(idProver) || idProver ||
+ len(idVerifier) || idVerifier)
+ w0 = w0s mod p
+ w1 = w1s mod p
+
+ If an identity is unknown at the time of computing w0s or w1s, its
+ length is given 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 both identities will be
+ represented as empty octet strings. idProver and idVerifier are
+ included in the transcript TT as part of the protocol flow.
+
+3.3. Online Authentication
+
+ The online SPAKE2+ protocol runs between the Prover and Verifier to
+ produce a 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, and transmits it to the Verifier.
+
+ x <- [0, p-1]
+ X = x*P + w0*M
+
+ Upon receipt of X, the Verifier checks the received element for group
+ membership and aborts if X is not in the large prime-order subgroup
+ of G; see Section 6 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. 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.
+
+ y <- [0, p-1]
+ Y = y*P + w0*N
+
+ Both participants compute Z and V; Z and V are then shared as common
+ values. The Prover computes:
+
+ Z = h*x*(Y - w0*N)
+ V = h*w1*(Y - w0*N)
+
+ The Verifier computes:
+
+ Z = h*y*(X - w0*M)
+ V = h*y*L
+
+ The multiplication by the cofactor h prevents small subgroup
+ confinement attacks. 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 unit element in G.
+
+ It is essential that both Z and V be used in combination with the
+ transcript to derive the keying material. The protocol transcript
+ encoding is shown below.
+
+ TT = len(Context) || Context
+ || len(idProver) || idProver
+ || len(idVerifier) || idVerifier
+ || len(M) || M
+ || len(N) || N
+ || len(shareP) || shareP
+ || len(shareV) || shareV
+ || len(Z) || Z
+ || len(V) || V
+ || len(w0) || w0
+
+ Context is an application-specific customization string shared
+ between both parties and MUST precede the remaining transcript. It
+ might contain the name and version number of the higher-level
+ protocol, or simply the name and version number of the application.
+ The context MAY include additional data such as the chosen
+ ciphersuite and PBKDF parameters like the iteration count or salt.
+ The context and its length prefix MAY be omitted.
+
+ If an identity is absent, its length is given as zero and the
+ identity itself 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. In applications where
+ identities are not implicit, idProver and idVerifier SHOULD always be
+ non-empty. Otherwise, the protocol risks unknown key-share attacks
+ (discussion of unknown key-share attacks in a specific protocol is
+ given in [RFC8844]).
+
+ Upon completion of this protocol, both parties compute shared secrets
+ K_main, K_shared, K_confirmP, and K_confirmV as specified in
+ Section 3.4. The Verifier MUST send a key confirmation message,
+ confirmV, to the Prover so both parties can confirm that they agree
+ upon these shared secrets. After receipt and verification of the
+ Verifier's confirmation message, the Prover MUST respond with its
+ confirmation message. The Verifier MUST NOT send application data to
+ the Prover until it has received and verified the confirmation
+ message. Key confirmation verification requires recomputation of
+ confirmP or confirmV and checking for equality against the data that
+ was received.
+
+3.4. Key Schedule and Key Confirmation
+
+ The protocol transcript TT, as defined in Section 3.3, is unique and
+ secret to the participants. Both parties use TT to derive the shared
+ symmetric secret K_main from the 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 as
+ the shared key K_shared, are derived from K_main.
+
+ K_main = Hash(TT)
+ K_confirmP || K_confirmV = KDF(nil, K_main, "ConfirmationKeys")
+ K_shared = KDF(nil, K_main, "SharedKey")
+
+ Neither K_main nor its derived confirmation keys are used for
+ anything except key derivation and confirmation and MUST be discarded
+ after the protocol execution. Applications MAY derive additional
+ keys from K_shared as needed.
+
+ 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 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, e.g., 128 bits for
+ CMAC-AES-128.
+
+ Both endpoints MUST employ a MAC that produces pseudorandom tags for
+ key confirmation. 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.
+
+ confirmP = MAC(K_confirmP, shareV)
+ confirmV = MAC(K_confirmV, shareP)
+
+ Once key confirmation is complete, applications MAY use K_shared as
+ an authenticated shared secret as needed. For example, applications
+ MAY derive one or more keys and nonces from K_shared, for use with
+ Authenticated Encryption with Associated Data (AEAD) and subsequent
+ application data encryption.
+
+4. Ciphersuites
+
+ This section documents SPAKE2+ ciphersuite configurations. A
+ ciphersuite indicates a group, cryptographic hash algorithm, and pair
+ of KDF and MAC functions, e.g., P256-SHA256-HKDF-HMAC-SHA256. This
+ ciphersuite indicates a SPAKE2+ protocol instance over P-256 that
+ uses SHA256 along with HKDF [RFC5869] and HMAC [RFC2104] for G, Hash,
+ KDF, and MAC functions, respectively. Since the choice of PBKDF, 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.
+
+ If no MAC algorithm is used in the key confirmation phase, its
+ respective column in Table 1 can be ignored and the ciphersuite name
+ will contain no MAC identifier.
+
+ +==============+==================+=============+==============+
+ | G | Hash | KDF | MAC |
+ +==============+==================+=============+==============+
+ | P-256 | SHA256 [RFC6234] | HKDF-SHA256 | HMAC-SHA256 |
+ | | | [RFC5869] | [RFC2104] |
+ +--------------+------------------+-------------+--------------+
+ | P-256 | SHA512 [RFC6234] | HKDF-SHA512 | HMAC-SHA512 |
+ | | | [RFC5869] | [RFC2104] |
+ +--------------+------------------+-------------+--------------+
+ | P-384 | SHA256 [RFC6234] | HKDF-SHA256 | HMAC-SHA256 |
+ | | | [RFC5869] | [RFC2104] |
+ +--------------+------------------+-------------+--------------+
+ | P-384 | SHA512 [RFC6234] | HKDF-SHA512 | HMAC-SHA512 |
+ | | | [RFC5869] | [RFC2104] |
+ +--------------+------------------+-------------+--------------+
+ | P-521 | SHA512 [RFC6234] | HKDF-SHA512 | HMAC-SHA512 |
+ | | | [RFC5869] | [RFC2104] |
+ +--------------+------------------+-------------+--------------+
+ | edwards25519 | SHA256 [RFC6234] | HKDF-SHA256 | HMAC-SHA256 |
+ | | | [RFC5869] | [RFC2104] |
+ +--------------+------------------+-------------+--------------+
+ | edwards448 | SHA512 [RFC6234] | HKDF-SHA512 | HMAC-SHA512 |
+ | | | [RFC5869] | [RFC2104] |
+ +--------------+------------------+-------------+--------------+
+ | P-256 | SHA256 [RFC6234] | HKDF-SHA256 | CMAC-AES-128 |
+ | | | [RFC5869] | [RFC4493] |
+ +--------------+------------------+-------------+--------------+
+ | P-256 | SHA512 [RFC6234] | HKDF-SHA512 | CMAC-AES-128 |
+ | | | [RFC5869] | [RFC4493] |
+ +--------------+------------------+-------------+--------------+
+
+ Table 1
+
+ The following points represent permissible point generation seeds for
+ the groups listed in Table 1, using the algorithm presented in
+ Appendix B. These byte strings are compressed points as in [SEC1]
+ for curves from [SEC1] and [RFC8032]. Note that these values are
+ identical to those used in the companion SPAKE2 specification
+ [RFC9382].
+
+ For P-256:
+
+ M =
+ 02886e2f97ace46e55ba9dd7242579f2993b64e16ef3dcab95afd497333d8fa12f
+ seed: 1.2.840.10045.3.1.7 point generation seed (M)
+
+ N =
+ 03d8bbd6c639c62937b04d997f38c3770719c629d7014d49a24b4f98baa1292b49
+ seed: 1.2.840.10045.3.1.7 point generation seed (N)
+
+ For P-384:
+
+ M =
+ 030ff0895ae5ebf6187080a82d82b42e2765e3b2f8749c7e05eba366434b363d3dc
+ 36f15314739074d2eb8613fceec2853
+ seed: 1.3.132.0.34 point generation seed (M)
+
+ N =
+ 02c72cf2e390853a1c1c4ad816a62fd15824f56078918f43f922ca21518f9c543bb
+ 252c5490214cf9aa3f0baab4b665c10
+ seed: 1.3.132.0.34 point generation seed (N)
+
+ For P-521:
+
+ M =
+ 02003f06f38131b2ba2600791e82488e8d20ab889af753a41806c5db18d37d85608
+ cfae06b82e4a72cd744c719193562a653ea1f119eef9356907edc9b56979962d7aa
+ seed: 1.3.132.0.35 point generation seed (M)
+
+ N =
+ 0200c7924b9ec017f3094562894336a53c50167ba8c5963876880542bc669e494b25
+ 32d76c5b53dfb349fdf69154b9e0048c58a42e8ed04cef052a3bc349d95575cd25
+ seed: 1.3.132.0.35 point generation seed (N)
+
+ For edwards25519:
+
+ M =
+ d048032c6ea0b6d697ddc2e86bda85a33adac920f1bf18e1b0c6d166a5cecdaf
+ seed: edwards25519 point generation seed (M)
+
+ N =
+ d3bfb518f44f3430f29d0c92af503865a1ed3281dc69b35dd868ba85f886c4ab
+ seed: edwards25519 point generation seed (N)
+
+ For edwards448:
+
+ M =
+ b6221038a775ecd007a4e4dde39fd76ae91d3cf0cc92be8f0c2fa6d6b66f9a12
+ 942f5a92646109152292464f3e63d354701c7848d9fc3b8880
+ seed: edwards448 point generation seed (M)
+
+ N =
+ 6034c65b66e4cd7a49b0edec3e3c9ccc4588afd8cf324e29f0a84a072531c4db
+ f97ff9af195ed714a689251f08f8e06e2d1f24a0ffc0146600
+ seed: edwards448 point generation seed (N)
+
+5. IANA Considerations
+
+ This document has no IANA actions.
+
+6. Security Considerations
+
+ SPAKE2+ appears in [TDH] and is proven secure in [SPAKE2P-Analysis].
+
+ The ephemeral randomness used by the Prover and Verifier MUST be
+ generated using a cryptographically secure Pseudorandom Number
+ Generator (PRNG).
+
+ Elements received from a peer MUST be checked for group membership:
+ failure to properly deserialize and validate group elements can lead
+ to attacks. An endpoint MUST abort the protocol if any received
+ public value is not a member of 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 small-order
+ subgroup. Consequently, the Prover and Verifier MUST abort the
+ protocol upon receiving any value V such that V*h = I. Failure to do
+ so may lead to subgroup confinement attacks.
+
+7. References
+
+7.1. Normative References
+
+ [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
+ Hashing for Message Authentication", RFC 2104,
+ DOI 10.17487/RFC2104, February 1997,
+ <https://www.rfc-editor.org/info/rfc2104>.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119,
+ DOI 10.17487/RFC2119, March 1997,
+ <https://www.rfc-editor.org/info/rfc2119>.
+
+ [RFC4493] Song, JH., Poovendran, R., Lee, J., and T. Iwata, "The
+ AES-CMAC Algorithm", RFC 4493, DOI 10.17487/RFC4493, June
+ 2006, <https://www.rfc-editor.org/info/rfc4493>.
+
+ [RFC5480] Turner, S., Brown, D., Yiu, K., Housley, R., and T. Polk,
+ "Elliptic Curve Cryptography Subject Public Key
+ Information", RFC 5480, DOI 10.17487/RFC5480, March 2009,
+ <https://www.rfc-editor.org/info/rfc5480>.
+
+ [RFC5869] Krawczyk, H. and P. Eronen, "HMAC-based Extract-and-Expand
+ Key Derivation Function (HKDF)", RFC 5869,
+ DOI 10.17487/RFC5869, May 2010,
+ <https://www.rfc-editor.org/info/rfc5869>.
+
+ [RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms
+ (SHA and SHA-based HMAC and HKDF)", RFC 6234,
+ DOI 10.17487/RFC6234, May 2011,
+ <https://www.rfc-editor.org/info/rfc6234>.
+
+ [RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital
+ Signature Algorithm (EdDSA)", RFC 8032,
+ DOI 10.17487/RFC8032, January 2017,
+ <https://www.rfc-editor.org/info/rfc8032>.
+
+ [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
+ 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
+ May 2017, <https://www.rfc-editor.org/info/rfc8174>.
+
+ [RFC8265] Saint-Andre, P. and A. Melnikov, "Preparation,
+ Enforcement, and Comparison of Internationalized Strings
+ Representing Usernames and Passwords", RFC 8265,
+ DOI 10.17487/RFC8265, October 2017,
+ <https://www.rfc-editor.org/info/rfc8265>.
+
+ [RFC9382] Ladd, W., "SPAKE2, a Password-Authenticated Key Exchange",
+ RFC 9382, DOI 10.17487/RFC9382, September 2023,
+ <https://www.rfc-editor.org/info/rfc9382>.
+
+ [SEC1] Standards for Efficient Cryptography Group, "SEC 1:
+ Elliptic Curve Cryptography", version 2.0, May 2009,
+ <https://secg.org/sec1-v2.pdf>.
+
+ [SPAKE2P-Analysis]
+ Shoup, V., "Security analysis of SPAKE2+", March 2020,
+ <https://eprint.iacr.org/2020/313.pdf>.
+
+ [TDH] Cash, D., Kiltz, E., and V. Shoup, "The Twin-Diffie
+ Hellman Problem and Applications", EUROCRYPT 2008, Lecture
+ Notes in Computer Science, Volume 4965, pages 127-145,
+ Springer-Verlag, Berlin, Germany,
+ DOI 10.1007/978-3-540-78967-3_8, April 2008,
+ <https://doi.org/10.1007/978-3-540-78967-3_8>.
+
+7.2. Informative References
+
+ [RFC7914] Percival, C. and S. Josefsson, "The scrypt Password-Based
+ Key Derivation Function", RFC 7914, DOI 10.17487/RFC7914,
+ August 2016, <https://www.rfc-editor.org/info/rfc7914>.
+
+ [RFC8844] Thomson, M. and E. Rescorla, "Unknown Key-Share Attacks on
+ Uses of TLS with the Session Description Protocol (SDP)",
+ RFC 8844, DOI 10.17487/RFC8844, January 2021,
+ <https://www.rfc-editor.org/info/rfc8844>.
+
+ [RFC9106] Biryukov, A., Dinu, D., Khovratovich, D., and S.
+ Josefsson, "Argon2 Memory-Hard Function for Password
+ Hashing and Proof-of-Work Applications", RFC 9106,
+ DOI 10.17487/RFC9106, September 2021,
+ <https://www.rfc-editor.org/info/rfc9106>.
+
+Appendix A. Protocol Flow
+
+ This section describes the flow of the SPAKE2+ protocol, including
+ computations and mandatory checks performed by the Prover and
+ Verifier. The constants M, N, P, p, and h are defined by the chosen
+ ciphersuite.
+
+A.1. Prover
+
+ The Prover implements two functions, ProverInit and ProverFinish,
+ which are described below.
+
+ def ProverInit(w0):
+ // Compute Prover key share
+ x <- [0, p-1]
+ X = x*P + w0*M
+ return (x, X)
+
+ def ProverFinish(w0, w1, x, Y):
+ if not_in_subgroup(Y):
+ raise "invalid input"
+
+ // Compute shared values
+ Z = h*x*(Y - w0*N)
+ V = h*w1*(Y - w0*N)
+
+ return (Y, Z, V)
+
+A.2. Verifier
+
+ The Verifier implements a single function, VerifierFinish, which is
+ described below.
+
+ def VerifierFinish(w0, L, X):
+ if not_in_subgroup(X):
+ raise "invalid input"
+
+ // Compute Verifier key share
+ y <- [0, p-1]
+ Y = y*P + w0*N
+
+ // Compute shared values
+ Z = h*y*(X - w0*M)
+ V = h*y*L
+
+ return (Z, V)
+
+A.3. Transcript Computation
+
+ Both the Prover and the Verifier share the same function to compute
+ the protocol transcript, ComputeTranscript, which is described below.
+
+ def ComputeTranscript(Context, idProver, idVerifier,
+ shareP, shareV, Z, V, w0):
+ TT = len(Context) || Context
+ || len(idProver) || idProver
+ || len(idVerifier) || idVerifier
+ || len(M) || M
+ || len(N) || N
+ || len(shareP) || shareP
+ || len(shareV) || shareV
+ || len(Z) || Z
+ || len(V) || V
+ || len(w0) || w0
+
+A.4. Key Schedule Computation
+
+ Both the Prover and the Verifier share the same function to compute
+ the key schedule, ComputeKeySchedule, which is described below.
+
+ def ComputeKeySchedule(TT):
+ K_main = Hash(TT)
+ K_confirmP || K_confirmV = KDF(nil, K_main, "ConfirmationKeys")
+ K_shared = KDF(nil, K_main, "SharedKey")
+ return K_confirmP, K_confirmV, K_shared
+
+A.5. Protocol Run
+
+ A full SPAKE2+ protocol run initiated by the Prover will look as
+ follows, where Transmit and Receive are shorthand for sending and
+ receiving a message to the peer:
+
+ Prover(Context, idProver, idVerifier, w0, w1):
+ (x, X) = ProverInit(w0)
+ Transmit(X)
+ Y = Receive()
+ (Z, V) = ProverFinish(w0, w1, x, Y)
+ TT = ComputeTranscript(Context, idProver, idVerifier, X, Y,
+ Z, V, w0)
+ (K_confirmP, K_confirmV, K_shared) = ComputeKeySchedule(TT)
+ expected_confirmV = MAC(K_confirmV, X)
+ confirmV = Receive()
+ if not_equal_constant_time(expected_confirmV, confirmV):
+ raise "invalid confirmation message"
+
+ confirmP = MAC(K_confirmP, Y)
+ Transmit(confirmP)
+
+ return K_shared
+
+ Verifier(Context, idProver, idVerifier, w0, L):
+ X = Receive()
+ (Y, Z, V) = VerifierFinish(w0, L, X)
+ Transmit(Y)
+ TT = ComputeTranscript(Context, idProver, idVerifier, X, Y,
+ Z, V, w0)
+ (K_confirmP, K_confirmV, K_shared) = ComputeKeySchedule(TT)
+ confirmV = MAC(K_confirmV, X)
+ Transmit(confirmV)
+
+ expected_confirmP = MAC(K_confirmP, Y)
+ confirmP = Receive()
+ if not_equal_constant_time(expected_confirmP, confirmP):
+ raise "invalid confirmation message"
+
+ return K_shared
+
+Appendix B. Algorithm Used for Point Generation
+
+ This section describes the algorithm that was used to generate the
+ points M and N in Table 1 (Section 4). This algorithm produces M and
+ N such that they are indistinguishable from two random points in the
+ prime-order subgroup of G, where the discrete log of these points is
+ unknown. See [SPAKE2P-Analysis] for additional details on this
+ requirement.
+
+ For each curve in Table 1, we construct a string using the curve OID
+ from [RFC5480] (as an ASCII string) or its name, combined with the
+ needed constant -- for instance, "1.3.132.0.35 point generation seed
+ (M)" for P-521. This string is turned into a series of blocks by
+ hashing with SHA256, and hashing that output again to generate the
+ next 32 bytes, and so on. This pattern is repeated for each group
+ and value, with the string modified appropriately.
+
+ A byte string of length equal to that of an encoded group element is
+ constructed by concatenating as many blocks as are required, starting
+ from the first block, and truncating to the desired length. The byte
+ string is then formatted as required for the group. In the case of
+ Weierstrass curves, we take the desired length as the length for
+ representing a compressed point (Section 2.3.4 of [SEC1]) 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 byte is set to 0x02 or
+ 0x03 (clearing the first six bits and setting the seventh bit),
+ leaving the sign bit as it was in the byte string constructed by
+ concatenating hash blocks. For the curves described in [RFC8032], a
+ different procedure is used. 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 not modified. For both of the
+ curves described in [RFC8032], the (modified) input is then
+ interpreted as the representation of the group element. If this
+ interpretation yields a valid group element with the correct order
+ (p), the (modified) byte string is the output. Otherwise, the
+ initial hash block is discarded and a new byte string constructed
+ from the remaining hash blocks. The procedure for constructing a
+ byte string of the appropriate length, formatting it as required for
+ the curve, and checking to see if it is a valid point of the correct
+ order is repeated until a valid element is found.
+
+ The following Python snippet generates the above points, assuming an
+ elliptic curve implementation following the interface of
+ Edwards25519Point.stdbase() and Edwards448Point.stdbase() in
+ Appendix A of [RFC8032]:
+
+ def iterated_hash(seed, n):
+ h = seed
+ for i in range(n):
+ h = hashlib.sha256(h).digest()
+ return h
+
+ def bighash(seed, start, sz):
+ n = -(-sz // 32)
+ hashes = [iterated_hash(seed, i) for i in range(start, start + n)]
+ return b''.join(hashes)[:sz]
+
+ def canon_pointstr(ecname, s):
+ if ecname == 'edwards25519':
+ return s
+ elif ecname == 'edwards448':
+ return s[:-1] + bytes([s[-1] & 0x80])
+ else:
+ return bytes([(s[0] & 1) | 2]) + s[1:]
+
+ def gen_point(seed, ecname, ec):
+ for i in range(1, 1000):
+ hval = bighash(seed, i, len(ec.encode()))
+ pointstr = canon_pointstr(ecname, hval)
+ try:
+ p = ec.decode(pointstr)
+ if p != ec.zero_elem() and p * p.l() == ec.zero_elem():
+ return pointstr, i
+ except Exception:
+ pass
+
+Appendix C. Test Vectors
+
+ This section contains various test vectors for SPAKE2+. (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 prefix, specified in [SEC1]. idProver and idVerifier
+ identity strings are provided in the protocol invocation.
+
+ [Context=b'SPAKE2+-P256-SHA256-HKDF-SHA256-HMAC-SHA256 Test Vectors
+ ']
+ [idProver=b'client']
+ [idVerifier=b'server']
+ w0 = 0xbb8e1bbcf3c48f62c08db243652ae55d3e5586053fca77102994f23ad9549
+ 1b3
+ w1 = 0x7e945f34d78785b8a3ef44d0df5a1a97d6b3b460409a345ca7830387a74b1
+ dba
+ L = 0x04eb7c9db3d9a9eb1f8adab81b5794c1f13ae3e225efbe91ea487425854c7f
+ c00f00bfedcbd09b2400142d40a14f2064ef31dfaa903b91d1faea7093d835966efd
+ x = 0xd1232c8e8693d02368976c174e2088851b8365d0d79a9eee709c6a05a2fad5
+ 39
+ shareP = 0x04ef3bd051bf78a2234ec0df197f7828060fe9856503579bb17330090
+ 42c15c0c1de127727f418b5966afadfdd95a6e4591d171056b333dab97a79c7193e3
+ 41727
+ y = 0x717a72348a182085109c8d3917d6c43d59b224dc6a7fc4f0483232fa6516d8
+ b3
+ shareV = 0x04c0f65da0d11927bdf5d560c69e1d7d939a05b0e88291887d679fcad
+ ea75810fb5cc1ca7494db39e82ff2f50665255d76173e09986ab46742c798a9a6843
+ 7b048
+ Z = 0x04bbfce7dd7f277819c8da21544afb7964705569bdf12fb92aa388059408d5
+ 0091a0c5f1d3127f56813b5337f9e4e67e2ca633117a4fbd559946ab474356c41839
+ V = 0x0458bf27c6bca011c9ce1930e8984a797a3419797b936629a5a937cf2f11c8
+ b9514b82b993da8a46e664f23db7c01edc87faa530db01c2ee405230b18997f16b68
+ TT = 0x38000000000000005350414b45322b2d503235362d5348413235362d484b4
+ 4462d5348413235362d484d41432d534841323536205465737420566563746f72730
+ 600000000000000636c69656e7406000000000000007365727665724100000000000
+ 00004886e2f97ace46e55ba9dd7242579f2993b64e16ef3dcab95afd497333d8fa12
+ f5ff355163e43ce224e0b0e65ff02ac8e5c7be09419c785e0ca547d55a12e2d20410
+ 000000000000004d8bbd6c639c62937b04d997f38c3770719c629d7014d49a24b4f9
+ 8baa1292b4907d60aa6bfade45008a636337f5168c64d9bd36034808cd564490b1e6
+ 56edbe7410000000000000004ef3bd051bf78a2234ec0df197f7828060fe98565035
+ 79bb1733009042c15c0c1de127727f418b5966afadfdd95a6e4591d171056b333dab
+ 97a79c7193e341727410000000000000004c0f65da0d11927bdf5d560c69e1d7d939
+ a05b0e88291887d679fcadea75810fb5cc1ca7494db39e82ff2f50665255d76173e0
+ 9986ab46742c798a9a68437b048410000000000000004bbfce7dd7f277819c8da215
+ 44afb7964705569bdf12fb92aa388059408d50091a0c5f1d3127f56813b5337f9e4e
+ 67e2ca633117a4fbd559946ab474356c4183941000000000000000458bf27c6bca01
+ 1c9ce1930e8984a797a3419797b936629a5a937cf2f11c8b9514b82b993da8a46e66
+ 4f23db7c01edc87faa530db01c2ee405230b18997f16b682000000000000000bb8e1
+ bbcf3c48f62c08db243652ae55d3e5586053fca77102994f23ad95491b3
+ K_main = 0x4c59e1ccf2cfb961aa31bd9434478a1089b56cd11542f53d3576fb6c2
+ a438a29
+ K_confirmP = 0x871ae3f7b78445e34438fb284504240239031c39d80ac23eb5ab9
+ be5ad6db58a
+ K_confirmV = 0xccd53c7c1fa37b64a462b40db8be101cedcf838950162902054e6
+ 44b400f1680
+ HMAC(K_confirmP, shareV) = 0x926cc713504b9b4d76c9162ded04b5493e89109
+ f6d89462cd33adc46fda27527
+ HMAC(K_confirmV, shareP) = 0x9747bcc4f8fe9f63defee53ac9b07876d907d55
+ 047e6ff2def2e7529089d3e68
+ K_shared = 0x0c5f8ccd1413423a54f6c1fb26ff01534a87f893779c6e68666d772
+ bfd91f3e7
+
+ [Context=b'SPAKE2+-P256-SHA512-HKDF-SHA512-HMAC-SHA512 Test Vectors
+ ']
+ [idProver=b'client']
+ [idVerifier=b'server']
+ w0 = 0x1cc5207d6e34b8f7828206fb64b86aa9c712bc952abf251bb9f5856b24d8c
+ 8cc
+ w1 = 0x4279649e62532b01dc27d2ed39100ba350518fb969672061a01edce752d0e
+ 672
+ L = 0x043a348ad475d2200d46df876f1eb2e136056da31dafff52cc7762bf3be84d
+ e0097c4e69b0b9321326af1f0af4a14561a9c7b640cb5afd6822d14cb34830fc4511
+ x = 0xb586ab83f175c1a2b56b6a1b6a283523f88a9befcf11e22efb48e2ee1fe69a
+ 23
+ shareP = 0x04a7928c4b47f6b8657a5b8ebcb6f1bd266192e152fb9745a4180c946
+ 57a2f323b4d50d536c0325cdb0ec42c9bd8db8d7af3ff6dc85edb4b5365375c62e09
+ def4a
+ y = 0xac1fb828f041782d452ea9cc00c3fa34a55fa8f7f98c04be45a3d607b092d4
+ 41
+ shareV = 0x04498c29e37dbd53ebf8db76679901d90c6be3af57f46ac3025b32420
+ 839f0489c6c3b6bf5ddc8ecbc3d7c83d0891ad814a00ad23eba13197c9d96a5b1027
+ 5e35d
+ Z = 0x04a81e31be54283cee81bf7bdc877764b6b2ac6a399f1176380aac8a82172c
+ 18051aa17dfcf438896ad253f53b52cd45ec2c7399488a919bcfcfecc0261cbf5284
+ V = 0x04de0a53f96cbe4abcd31c1e0a23ea6f169c162dc5a007393c8fcddd2abd5d
+ 518bb2d9734b1d2dfce3fd916e991ab9dc3a2760d439c083eb39b65408857d2bb4aa
+ TT = 0x38000000000000005350414b45322b2d503235362d5348413531322d484b4
+ 4462d5348413531322d484d41432d534841353132205465737420566563746f72730
+ 600000000000000636c69656e7406000000000000007365727665724100000000000
+ 00004886e2f97ace46e55ba9dd7242579f2993b64e16ef3dcab95afd497333d8fa12
+ f5ff355163e43ce224e0b0e65ff02ac8e5c7be09419c785e0ca547d55a12e2d20410
+ 000000000000004d8bbd6c639c62937b04d997f38c3770719c629d7014d49a24b4f9
+ 8baa1292b4907d60aa6bfade45008a636337f5168c64d9bd36034808cd564490b1e6
+ 56edbe7410000000000000004a7928c4b47f6b8657a5b8ebcb6f1bd266192e152fb9
+ 745a4180c94657a2f323b4d50d536c0325cdb0ec42c9bd8db8d7af3ff6dc85edb4b5
+ 365375c62e09def4a410000000000000004498c29e37dbd53ebf8db76679901d90c6
+ be3af57f46ac3025b32420839f0489c6c3b6bf5ddc8ecbc3d7c83d0891ad814a00ad
+ 23eba13197c9d96a5b10275e35d410000000000000004a81e31be54283cee81bf7bd
+ c877764b6b2ac6a399f1176380aac8a82172c18051aa17dfcf438896ad253f53b52c
+ d45ec2c7399488a919bcfcfecc0261cbf5284410000000000000004de0a53f96cbe4
+ abcd31c1e0a23ea6f169c162dc5a007393c8fcddd2abd5d518bb2d9734b1d2dfce3f
+ d916e991ab9dc3a2760d439c083eb39b65408857d2bb4aa20000000000000001cc52
+ 07d6e34b8f7828206fb64b86aa9c712bc952abf251bb9f5856b24d8c8cc
+ K_main = 0x527613439c279a375c116342a4216a8d92441d2fe1921dd1e60f140b2
+ 855916ccac7db4dbf22bd56e344a8cd506d08949bde1e9d83c24d68ff4246458dc14
+ 288
+ K_confirmP = 0x0aa129d7b82067c2a9607677c9c4fdedc1cd7cfed9ff72c54c0ae
+ bb2b1a8aa915b96834b2986725c6040852ceaafbb17d638a715198f795654eac89bf
+ 0739878
+ K_confirmV = 0xa1f1038de30a8c12d43d06c27d362daa9699249e941faa2d5cbc5
+ 9a9683bf42aed9537818245677fdb54b5274506542994f4a83455f6d7b3af5ec017f
+ aa58f61
+ HMAC(K_confirmP, shareV) = 0x6b2469b56cf8ac3f94a8d0b533380ea6b3d0f46
+ b3e12ee82550d49e129c2412728c9437a64ee5f80c8cdc5e8a30faa0a6deb8a52513
+ 46ba81bb6fc955b2304fc
+ HMAC(K_confirmV, shareP) = 0x154174fc278a935e290b3352ba877e179fa9281
+ c0a76928faea703c72d383b267511a5cf084cb07147efece94e3cfd91944e7baab85
+ 6858fbebc087167b0f409
+ K_shared = 0x11887659d9e002f34fa6cc270d33570f001b2a3fc0522b643c07327
+ d09a4a9f47aab85813d13c585b53adf5ac9de5707114848f3dc31a4045f69a2cc197
+ 2b098
+
+ [Context=b'SPAKE2+-P384-SHA256-HKDF-SHA256-HMAC-SHA256 Test Vectors
+ ']
+ [idProver=b'client']
+ [idVerifier=b'server']
+ w0 = 0x097a61cbb1cee72bb654be96d80f46e0e3531151003903b572fc193f23377
+ 2c23c22228884a0d5447d0ab49a656ce1d2
+ w1 = 0x18772816140e6c3c3938a693c600b2191118a34c7956e1f1cd5b0d519b56e
+ a5858060966cfaf27679c9182129949e74f
+ L = 0x04f27dd5384d6b9beb4c5022c94b1978d632779e1d3abe458611e734a529d0
+ 04e25053398e5dc9eeaa4ffa59743ca7ddbc0e7ce69155295cb2b846da83ee6a4449
+ 0dd8e96bb0b0f6645281bfd978dd5f6836561ea0d8b2c045ff04cef2e5873d2c
+ x = 0x2f1bdbeda162ff2beba0293d3cd3ae95f663c53663378c7e18ee8f56a4a48b
+ 00d31ce0ef43606548da485058f12e8e73
+ shareP = 0x049fb0404ca7ce71fb85d3aaa8fd05fa054affac996135bc245149be0
+ 9571e43e2bf76e00d6d52ac452b8224f6b9da31420a4f5e214b377546daad4d61da5
+ ca0cfdea59a5a92ebdb6b42da5d14663b8d1f9eb97050139ab89788e0ada27b048fc
+ f
+ y = 0xbbcaf02404a16ed4fa73b183f703a8d969386f3d34f5e98b3a904e760512f1
+ 1757f07dfcf87a2ada8fc6d028445bd53e
+ shareV = 0x0493b1c1f6a30eac4ac4a15711e44640bae3576787627ee2541104298
+ 1e94b2e9604b9374f66bb247bc431759212ef3fa0a20c087863b89efb32219e1337c
+ e94be2175f8cb9fd50cf0b84772717fd063c52b69de1229a01ab840b55993287f32e
+ d
+ Z = 0x048cd880e5147e49b42b5754c1bc6d2091ad414789bc3b030f2d787ea480f3
+ e35d0fa0d02d0dd06fee7f242b702a2d984efd79c76d99ab35b99e359a205cea56bb
+ a8dd8f995c101a69a5157686d1cf6a7288d7cff2f2a9748db99b24f646ea7b37
+ V = 0x041c3c9cc38b03a06a49cf17cc5e7754cf1ccbbc6fffc0ddf1a6e23f57294a
+ 25d96f7da5ce4ac0a617c78502f2f235a5fcf2f76a62385434ed2b6e95521b41eff3
+ c4ce93ecf8fb32005dd76335d0a7c78153257288d7fde1a22d404f5d73d068e2
+ TT = 0x38000000000000005350414b45322b2d503338342d5348413235362d484b4
+ 4462d5348413235362d484d41432d534841323536205465737420566563746f72730
+ 600000000000000636c69656e7406000000000000007365727665726100000000000
+ 000040ff0895ae5ebf6187080a82d82b42e2765e3b2f8749c7e05eba366434b363d3
+ dc36f15314739074d2eb8613fceec285397592c55797cdd77c0715cb7df2150220a0
+ 119866486af4234f390aad1f6addde5930909adc67a1fc0c99ba3d52dc5dd6100000
+ 00000000004c72cf2e390853a1c1c4ad816a62fd15824f56078918f43f922ca21518
+ f9c543bb252c5490214cf9aa3f0baab4b665c10c38b7d7f4e7f320317cd717315a79
+ 7c7e02933aef68b364cbf84ebc619bedbe21ff5c69ea0f1fed5d7e3200418073f406
+ 100000000000000049fb0404ca7ce71fb85d3aaa8fd05fa054affac996135bc24514
+ 9be09571e43e2bf76e00d6d52ac452b8224f6b9da31420a4f5e214b377546daad4d6
+ 1da5ca0cfdea59a5a92ebdb6b42da5d14663b8d1f9eb97050139ab89788e0ada27b0
+ 48fcf61000000000000000493b1c1f6a30eac4ac4a15711e44640bae3576787627ee
+ 25411042981e94b2e9604b9374f66bb247bc431759212ef3fa0a20c087863b89efb3
+ 2219e1337ce94be2175f8cb9fd50cf0b84772717fd063c52b69de1229a01ab840b55
+ 993287f32ed6100000000000000048cd880e5147e49b42b5754c1bc6d2091ad41478
+ 9bc3b030f2d787ea480f3e35d0fa0d02d0dd06fee7f242b702a2d984efd79c76d99a
+ b35b99e359a205cea56bba8dd8f995c101a69a5157686d1cf6a7288d7cff2f2a9748
+ db99b24f646ea7b376100000000000000041c3c9cc38b03a06a49cf17cc5e7754cf1
+ ccbbc6fffc0ddf1a6e23f57294a25d96f7da5ce4ac0a617c78502f2f235a5fcf2f76
+ a62385434ed2b6e95521b41eff3c4ce93ecf8fb32005dd76335d0a7c78153257288d
+ 7fde1a22d404f5d73d068e23000000000000000097a61cbb1cee72bb654be96d80f4
+ 6e0e3531151003903b572fc193f233772c23c22228884a0d5447d0ab49a656ce1d2
+ K_main = 0x61370f8bf65e0df7e9a7b2c2289be1ee4b5dd6c21f4b85165730700c4
+ 4ce30af
+ K_confirmP = 0x2c8940419d94e53d5d240801e702c4658531aa7a9f14ec75f0d67
+ f12fa84196c
+ K_confirmV = 0x8e74afe16c53a44590ad6bf43aa89324978b8f20014336675f618
+ 387f99f3fdc
+ HMAC(K_confirmP, shareV) = 0x7ae825e242a5a1f86ad7db172c2c12fcb458b6a
+ 2b1ddfc96b2b7cfd2eed5f7ab
+ HMAC(K_confirmV, shareP) = 0x1581062167d6a3d14493447cd170d408f6fdc58
+ e31225438db86214167426a7a
+ K_shared = 0x99758e838ae1a856589689fb55b6befe4e2382e6ebbeca1a6232a68
+ f9dc04c1a
+
+ [Context=b'SPAKE2+-P384-SHA512-HKDF-SHA512-HMAC-SHA512 Test Vectors
+ ']
+ [idProver=b'client']
+ [idVerifier=b'server']
+ w0 = 0xb8d44a0982b88abe19b724d4bdafba8c90dc93130e0bf4f8062810992326d
+ a126fd01db53e40250ca33a3ff302044cb0
+ w1 = 0x2373e2071c3bb2a6d53ece57830d56f8080189816803c22375d6a4a514f9d
+ 161b64d0f05b97735b98b348f9b33cc2e30
+ L = 0x049ca7217ff6456bb2e2bcf71b31d9b1e5ed6e0c9700936ae617e990cee87e
+ e1ce3a03629dd5532948c39b89f38b39f13c7f513c5b1ada00f6533a4a8b02b9cd04
+ e1b2a5db1f24ec5fe959198a19666037e04b768cc02e75ac9da0048736db6e5b
+ x = 0x5a835d52714f30d2ef539268b89df9558628400063dfa0e41eb979066f4caf
+ 409bbf7aab3ddddea13f1b070a1827d3d4
+ shareP = 0x042f382eef464a2c9aecfdf4b81d25c4de2de113ba67405ce336c762c
+ 69217ae7e27bda875144140d7536c4cc08b9b4dace5f872a6a2ed57f34042688ad3c
+ 5d446c187dc0caf9cea812df3a4dd6fdbc64b9d7d7d7ff4bf6965abb06eeb108d55e
+ e
+ y = 0xc883ee5b08cf7ba122038c279459ab1a730f85f2d624a02732d519faab56a4
+ 98e773a8dec6c447ed02d5c00303a18bc4
+ shareV = 0x04d72e11eee332305062454c0a058b8103a3304785d445510cd8d101e
+ 9cb44cfb159cb7b72123abaf719ab1c42e0558c84c14b0886e8b446e4c880bff2f4b
+ 291fafafc748cb4115824e66732bdeba7fae176388e228ab9d7546255994ca3fb5a5
+ 2
+ Z = 0x043cb63f5fcb573cf3e2ee40bca5fbc1f00ff2554caab3790329184c45ed69
+ c39b2e1323bc13c8f821b844feb5921b1470e7b3f70bd10508e5de6db157305badf8
+ 20fa28d68742d8287fb201383a8deec70d5bcf2a61498a481290ed8cc94ab3a0
+ V = 0x0468604d188f4da560ddaaece126abe40f5de255f8af093c7c3aff71f95d90
+ 92804426127d73d46a817085e9095de6bcf30733a5124a98f567148efe92a7134994
+ 0c7244623247d33a8b78cbc9a53cd45bb22430f318a635084d1840c905f236c8
+ TT = 0x38000000000000005350414b45322b2d503338342d5348413531322d484b4
+ 4462d5348413531322d484d41432d534841353132205465737420566563746f72730
+ 600000000000000636c69656e7406000000000000007365727665726100000000000
+ 000040ff0895ae5ebf6187080a82d82b42e2765e3b2f8749c7e05eba366434b363d3
+ dc36f15314739074d2eb8613fceec285397592c55797cdd77c0715cb7df2150220a0
+ 119866486af4234f390aad1f6addde5930909adc67a1fc0c99ba3d52dc5dd6100000
+ 00000000004c72cf2e390853a1c1c4ad816a62fd15824f56078918f43f922ca21518
+ f9c543bb252c5490214cf9aa3f0baab4b665c10c38b7d7f4e7f320317cd717315a79
+ 7c7e02933aef68b364cbf84ebc619bedbe21ff5c69ea0f1fed5d7e3200418073f406
+ 100000000000000042f382eef464a2c9aecfdf4b81d25c4de2de113ba67405ce336c
+ 762c69217ae7e27bda875144140d7536c4cc08b9b4dace5f872a6a2ed57f34042688
+ ad3c5d446c187dc0caf9cea812df3a4dd6fdbc64b9d7d7d7ff4bf6965abb06eeb108
+ d55ee610000000000000004d72e11eee332305062454c0a058b8103a3304785d4455
+ 10cd8d101e9cb44cfb159cb7b72123abaf719ab1c42e0558c84c14b0886e8b446e4c
+ 880bff2f4b291fafafc748cb4115824e66732bdeba7fae176388e228ab9d75462559
+ 94ca3fb5a526100000000000000043cb63f5fcb573cf3e2ee40bca5fbc1f00ff2554
+ caab3790329184c45ed69c39b2e1323bc13c8f821b844feb5921b1470e7b3f70bd10
+ 508e5de6db157305badf820fa28d68742d8287fb201383a8deec70d5bcf2a61498a4
+ 81290ed8cc94ab3a061000000000000000468604d188f4da560ddaaece126abe40f5
+ de255f8af093c7c3aff71f95d9092804426127d73d46a817085e9095de6bcf30733a
+ 5124a98f567148efe92a71349940c7244623247d33a8b78cbc9a53cd45bb22430f31
+ 8a635084d1840c905f236c83000000000000000b8d44a0982b88abe19b724d4bdafb
+ a8c90dc93130e0bf4f8062810992326da126fd01db53e40250ca33a3ff302044cb0
+ K_main = 0x571af2e9a0bf4b354cca18d713f8a84315a46c999ceb92ca6a88b8a6d
+ 615795140862dbccd6fdc0abecc5956c43f8ab40343a22fc1b91752cb7c2737dab90
+ 41e
+ K_confirmP = 0x6c8c7fc6becf3bc07f081b4f7f867bec76fd8eeddbd7968356723
+ bae701e04f35f800e647dfa013b2876958efe0ce68e7595ba46f1de0b17adfc02dfe
+ 3f18a18
+ K_confirmV = 0x2d0c9702a0f5536bacddd596eb6ea365d17f176db30081b97b83e
+ 05bb87e9a36c0565b7616251c93bc76c76fc5c3531a28db40779d986d4e7b71a24c4
+ 3fbc731
+ HMAC(K_confirmP, shareV) = 0x7f806ae56ea3e49a8b16ffee528086489418913
+ 641f529d50ff92aa456ad4648e522f9540b403bff6bd94ee1adc95c7d1b2666f7ba6
+ f9c10748bc7bfb4181d27
+ HMAC(K_confirmV, shareP) = 0x8daa262decb79cceda4421f4f8dacf22ec027c0
+ 8e036f071beea563c8e00813a29807963ff9d7d6bbff48dd5bdcdd9ca9fd7ffc272b
+ 162258d981913f7253dcb
+ K_shared = 0x31e0075a823b9269af5769d71ef3b2f5001cbfe044584fe8551124a
+ 217dad078415630bf3eda16b5a38341d418a6d72b3960f818a0926f0de88784b59d6
+ a694b
+
+ [Context=b'SPAKE2+-P521-SHA512-HKDF-SHA512-HMAC-SHA512 Test Vectors
+ ']
+ [idProver=b'client']
+ [idVerifier=b'server']
+ w0 = 0x009c79bcd7656716314fca5a6e2c5cda7ef86131399438e012a043051e863
+ f60b5aeb3c101731e1505e721580f48535a9b0456b231b9266ae6fff49ee90d25f72
+ f5f
+ w1 = 0x01632c15f51fcd916cd79e19075f8a69b72b0099922ad62ff8d540b469569
+ f0aa027047aed2b3f242ea0ac4288b4e4db6a4e5946d8ad32b42192c5aa66d9ef8e1
+ b33
+ L = 0x040135072d0fa36f9e80031294cef5c3c35b882a0efa2c66570d64a49f8bec
+ 6c66435bf65bb7c7b2a3e7dece491e02b4d567e7087dbc32fe0fae8af417dcb50be6
+ d704012a194588b690e6d3db492656f72ddea01fc1c7fcec0f5d34a5af0102939f6f
+ deae39c20cff74fcdb7f09855f0fc9520d20b0520b0b096b8d42c7c3d68b4a66f751
+ x = 0x00b69e3bb15df82c9fa0057461334e2c66ab92fc9b8d3662eec81216ef5ddc
+ 4a43f19e90dedaa2d72502f69673a115984ffcf88e03a9364b07102114c5602cd93c
+ 69
+ shareP = 0x0400a14431edf6852ff5fe868f8683e16e9e0a45d9e27f9a96442285a
+ c6b161fc0bf267362a5ffb06f9cbd14b7a37e492146d77cae4c77812df00a91dbae0
+ 9e27e1fac00ae019317ef9768548325bca35ce258e6206fe03c6338b2eb889d09d9f
+ 11400a36cf6328a7e1f81c6c7a2af7ff1d9b5210768318f27e57b75b39b9fbfc7b37
+ a60ab
+ y = 0x0056d01c5246fbde964c0493934b7ece89eafd943eb27d357880a2a2202249
+ 9e249528c5707b1afe8794c8a1d60ceedaeed96dd0dd904ea075f096c9fec5da7de4
+ 96
+ shareV = 0x0401aa5af0f3027f63b7170572db5ff06dd1f3d6ea8ea771b26b434fb
+ bc6c9de7d80975131c9c2e94d30c0ed2d62449c4c1b7e95037a85ed7598e415a2591
+ 26365e89500d0f2156b551b70416d719944736990f346f6f9ba4fbaf2f63e0987369
+ 0bcf730582e0a7b03ffede50f5787b631d5021a94287f0a29a081b62b9f5a3bf393b
+ 001b3
+ Z = 0x0401e3015bf2811891a518d342c63541294dc80e0ee210e8220a5b9cab010d
+ 77945724ef1185d739a62847fdada9da9b1bca6b9fa173fa551185c6084c3db26d3a
+ f0ac01f9356d01beebebd5ff026ca19f9df5d614355f3498816ac20b63bc936eed82
+ 8a7039d1e17dba740471d9afc0e0b4427d65b2d27a57a87e42300004e2b4620c23c9
+ V = 0x0401058b21ca71e4439281579d6df3b86ae874d70742fe8eae2de60e77e07e
+ 6e1c31b9c277de36b38531f5b769e9e4030ba09258f510c83c5c21957610355ce920
+ 1fe600672db35efd1d0903bc285d4e27e9fb4472c30f17118dfa028f182bc9361c6a
+ 749f560e31b9c404624d24e68010f064101d4a1154e77be8f2105dbeb8b0349adb0e
+ TT = 0x38000000000000005350414b45322b2d503532312d5348413531322d484b4
+ 4462d5348413531322d484d41432d534841353132205465737420566563746f72730
+ 600000000000000636c69656e7406000000000000007365727665728500000000000
+ 00004003f06f38131b2ba2600791e82488e8d20ab889af753a41806c5db18d37d856
+ 08cfae06b82e4a72cd744c719193562a653ea1f119eef9356907edc9b56979962d7a
+ a01bdd179a3d547610892e9b96dea1eab10bdd7ac5ae0cf75aa0f853bfd185cf782f
+ 894301998b11d1898ede2701dca37a2bb50b4f519c3d89a7d054b51fb84912192850
+ 00000000000000400c7924b9ec017f3094562894336a53c50167ba8c596387688054
+ 2bc669e494b2532d76c5b53dfb349fdf69154b9e0048c58a42e8ed04cef052a3bc34
+ 9d95575cd2501c62bee650c9287a651bb75c7f39a2006873347b769840d261d17760
+ b107e29f091d556a82a2e4cde0c40b84b95b878db2489ef760206424b3fe7968aa8e
+ 0b1f33485000000000000000400a14431edf6852ff5fe868f8683e16e9e0a45d9e27
+ f9a96442285ac6b161fc0bf267362a5ffb06f9cbd14b7a37e492146d77cae4c77812
+ df00a91dbae09e27e1fac00ae019317ef9768548325bca35ce258e6206fe03c6338b
+ 2eb889d09d9f11400a36cf6328a7e1f81c6c7a2af7ff1d9b5210768318f27e57b75b
+ 39b9fbfc7b37a60ab85000000000000000401aa5af0f3027f63b7170572db5ff06dd
+ 1f3d6ea8ea771b26b434fbbc6c9de7d80975131c9c2e94d30c0ed2d62449c4c1b7e9
+ 5037a85ed7598e415a259126365e89500d0f2156b551b70416d719944736990f346f
+ 6f9ba4fbaf2f63e09873690bcf730582e0a7b03ffede50f5787b631d5021a94287f0
+ a29a081b62b9f5a3bf393b001b385000000000000000401e3015bf2811891a518d34
+ 2c63541294dc80e0ee210e8220a5b9cab010d77945724ef1185d739a62847fdada9d
+ a9b1bca6b9fa173fa551185c6084c3db26d3af0ac01f9356d01beebebd5ff026ca19
+ f9df5d614355f3498816ac20b63bc936eed828a7039d1e17dba740471d9afc0e0b44
+ 27d65b2d27a57a87e42300004e2b4620c23c985000000000000000401058b21ca71e
+ 4439281579d6df3b86ae874d70742fe8eae2de60e77e07e6e1c31b9c277de36b3853
+ 1f5b769e9e4030ba09258f510c83c5c21957610355ce9201fe600672db35efd1d090
+ 3bc285d4e27e9fb4472c30f17118dfa028f182bc9361c6a749f560e31b9c404624d2
+ 4e68010f064101d4a1154e77be8f2105dbeb8b0349adb0e4200000000000000009c7
+ 9bcd7656716314fca5a6e2c5cda7ef86131399438e012a043051e863f60b5aeb3c10
+ 1731e1505e721580f48535a9b0456b231b9266ae6fff49ee90d25f72f5f
+ K_main = 0xf672a73216568d20cc3433247bc43a3b875a421cbdba76cf1db8bfe57
+ 2b658bf3f7a4ef8cc9ff1f6a2827ff7b19860454b775a4097009040f3b36b7420407
+ 16e
+ K_confirmP = 0xa211c60ea8d4b3b294bd6ca9515663b77f3caac28af3658b34fe1
+ 512f25077f2f64b8de426caa662b4cbbdc9c2f8f12347993c8d57fdf68c177732d7d
+ da7277b
+ K_confirmV = 0x0e9bf6b9a37339144cb32a78a872f50b10839f81eda6c09a827dd
+ bb158c47162bec274af920cdf809f162b98fa701efebada26cdfbeac408b5a35b052
+ d18f0c6
+ HMAC(K_confirmP, shareV) = 0xf0f5c903dfa42fe367659656a26058cd984b76a
+ 8e91ae4d0fa4c13db149008e2ae57713fb230a627761174fefd263b9c10e9a4b6a37
+ 46cde59c5943040c17133
+ HMAC(K_confirmV, shareP) = 0xa8f7ab43f3a800171d3a3fb26d742e1ed236c2d
+ 5804ecd328f220a7d245cd2e3bfb6c0526983bff9229c94f70fe64ba9bb5a4d0dc10
+ afcda64a4c96d4c3d81ad
+ K_shared = 0xd1c170e4e55efacb9db8abad286293ebd1dcf24f13973427b9632bb
+ c323e42e447afca2aa7f74f2af3fb5f51684ec543db854b7002cde6799c330b032ba
+ 8820a
+
+ [Context=b'SPAKE2+-P256-SHA256-HKDF-SHA256-CMAC-AES-128 Test Vector
+ s']
+ [idProver=b'client']
+ [idVerifier=b'server']
+ w0 = 0x9aad90c603cf16cec4ee40d81acd7a865130b28cc6d0664ae2e0f406aa47e
+ d61
+ w1 = 0x872be859cec1e78d191882bd9c2f032af018a25016813788fe8954bfffc58
+ c8e
+ L = 0x04d79a53698c5dd79e14b426e73b4a7f1b42469815fe24e8f53ce01579e902
+ eb198d59f05bc451c41826b88e3db5476a69e197fdf474c75b387f6d40361c3fda35
+ x = 0x9d39a3511a007a7d3fe6af5555cf60301bcda503f2bf6634b2caf9e4fd0743
+ a1
+ shareP = 0x04788218027ba4b17f7279ef0aef47a8733cf88b5bf65d6127ecadc78
+ b8a0f65b9001f7e54719fb63c072ddd1e1a4adfb376dde37ba1aa2082362b6c2ca14
+ a8e53
+ y = 0x9c3219841626325c68d89c22fb6c55611e3136442daa8b9b784db7242afff3
+ ed
+ shareV = 0x04c05953ea9d1cd6248b8c61becd7d55e46237526d8b1e23495ea7566
+ b7f6bc24b3da1cfb2e88a975fcfb5dc4e72b5cbea509b1cfdd1ef8f8195fa8bf2bd5
+ ca1e5
+ Z = 0x049444a17ad5909548a084fa182275a89a496ec6669bd08892aa9c64a512d4
+ 0212147e6005bf1d510e3bbcfee8efc38243acaf4c5f2decffa009341b1e330b0442
+ V = 0x0457a8919af393e2da1de209a01fdda275eab0a682d8931b0e6ee1b9339794
+ 63a25ccbcda1956a6a555706f0b062aa880617bd219d09391ad8576d3a73e9233f57
+ TT = 0x39000000000000005350414b45322b2d503235362d5348413235362d484b4
+ 4462d5348413235362d434d41432d4145532d313238205465737420566563746f727
+ 30600000000000000636c69656e74060000000000000073657276657241000000000
+ 0000004886e2f97ace46e55ba9dd7242579f2993b64e16ef3dcab95afd497333d8fa
+ 12f5ff355163e43ce224e0b0e65ff02ac8e5c7be09419c785e0ca547d55a12e2d204
+ 10000000000000004d8bbd6c639c62937b04d997f38c3770719c629d7014d49a24b4
+ f98baa1292b4907d60aa6bfade45008a636337f5168c64d9bd36034808cd564490b1
+ e656edbe7410000000000000004788218027ba4b17f7279ef0aef47a8733cf88b5bf
+ 65d6127ecadc78b8a0f65b9001f7e54719fb63c072ddd1e1a4adfb376dde37ba1aa2
+ 082362b6c2ca14a8e53410000000000000004c05953ea9d1cd6248b8c61becd7d55e
+ 46237526d8b1e23495ea7566b7f6bc24b3da1cfb2e88a975fcfb5dc4e72b5cbea509
+ b1cfdd1ef8f8195fa8bf2bd5ca1e54100000000000000049444a17ad5909548a084f
+ a182275a89a496ec6669bd08892aa9c64a512d40212147e6005bf1d510e3bbcfee8e
+ fc38243acaf4c5f2decffa009341b1e330b044241000000000000000457a8919af39
+ 3e2da1de209a01fdda275eab0a682d8931b0e6ee1b933979463a25ccbcda1956a6a5
+ 55706f0b062aa880617bd219d09391ad8576d3a73e9233f5720000000000000009aa
+ d90c603cf16cec4ee40d81acd7a865130b28cc6d0664ae2e0f406aa47ed61
+ K_main = 0x6002da6b2740056f2836ac0316ae9e02e2b24c5c109883136e90ed868
+ b2fcf62
+ K_confirmP = 0x857d0db7f5e06385853bf4b8abd43b5a
+ K_confirmV = 0x268c75933332157118063550c6bfe846
+ CMAC(K_confirmP, shareV) = 0xd340bc94a03feafd14491e316514ca5f
+ CMAC(K_confirmV, shareP) = 0x2b42d0fe76bcf9ccc208d06d60082f96
+ K_shared = 0xe832094adfc028bf288e49ab902fc208b7eeff084f259da7613c047
+ 9869d4fc9
+
+ [Context=b'SPAKE2+-P256-SHA512-HKDF-SHA512-CMAC-AES-128 Test Vector
+ s']
+ [idProver=b'client']
+ [idVerifier=b'server']
+ w0 = 0x56e0299ac95739b616a973276c1338e3651285345dde2f7faf74c25c0b50e
+ b90
+ w1 = 0x462fe5b522a17d3d35b27323113bdd252de9cbfdd6f264b35721bf59a9a74
+ f0b
+ L = 0x040540332ffec8a2faa8d17ae6da5973c11e078b8c10c89fd6af996726b802
+ 3513eff2914c3ced64fbedd4e261438fb0ea6ef9fc1faef4ba1ead780636faac1bc1
+ x = 0x254dd22780eeb6af2464dd6a2bd026b46a34966d6933607f1be956314f74b0
+ ea
+ shareP = 0x049661cfdb0f7bd24b637f8d1d0f464c17f0b9c15129ea31156dcc581
+ da6c840240b275d72f28ea73a5c088c99d73896af24a5ae26e036eb2dedaf26e511a
+ 24a48
+ y = 0x695beec24305fbd5660bc200228598e7c891fdf60a55df4bdd3a57debc3847
+ 4a
+ shareV = 0x0461f580eb3eb4b2f412d5c07491f360ad6e4492d8f23e346f0ba999f
+ bbcb9715a3c2485c3b250a6672e6698da3c9a9725645f607ee90a9b1b34fd44b9df6
+ e551a
+ Z = 0x0406f77a4bca254219dc3eeca9989f377037407105540bfddc5bdeff3d27a8
+ 7d68442e69d543a000077bd4c42e33930f890d29fb4be5e8dcc627f6811ace96c274
+ V = 0x0442952a531a2937e03808e74f6d65afbedb4cfb7fcf91991498f77db21b14
+ 6f5c2249e727e374de03f32848465aba5c5ebfe6501d3537d09160c7f42e4b3f133d
+ TT = 0x39000000000000005350414b45322b2d503235362d5348413531322d484b4
+ 4462d5348413531322d434d41432d4145532d313238205465737420566563746f727
+ 30600000000000000636c69656e74060000000000000073657276657241000000000
+ 0000004886e2f97ace46e55ba9dd7242579f2993b64e16ef3dcab95afd497333d8fa
+ 12f5ff355163e43ce224e0b0e65ff02ac8e5c7be09419c785e0ca547d55a12e2d204
+ 10000000000000004d8bbd6c639c62937b04d997f38c3770719c629d7014d49a24b4
+ f98baa1292b4907d60aa6bfade45008a636337f5168c64d9bd36034808cd564490b1
+ e656edbe74100000000000000049661cfdb0f7bd24b637f8d1d0f464c17f0b9c1512
+ 9ea31156dcc581da6c840240b275d72f28ea73a5c088c99d73896af24a5ae26e036e
+ b2dedaf26e511a24a4841000000000000000461f580eb3eb4b2f412d5c07491f360a
+ d6e4492d8f23e346f0ba999fbbcb9715a3c2485c3b250a6672e6698da3c9a9725645
+ f607ee90a9b1b34fd44b9df6e551a41000000000000000406f77a4bca254219dc3ee
+ ca9989f377037407105540bfddc5bdeff3d27a87d68442e69d543a000077bd4c42e3
+ 3930f890d29fb4be5e8dcc627f6811ace96c27441000000000000000442952a531a2
+ 937e03808e74f6d65afbedb4cfb7fcf91991498f77db21b146f5c2249e727e374de0
+ 3f32848465aba5c5ebfe6501d3537d09160c7f42e4b3f133d200000000000000056e
+ 0299ac95739b616a973276c1338e3651285345dde2f7faf74c25c0b50eb90
+ K_main = 0x111790ae23de3fc5bb43bdc1f63106461dbd8d86360adf056bf117164
+ 8bfb231503853db2625275b7136b5a823dd5a94482514fce7f791c4daca2b21c7bde
+ 756
+ K_confirmP = 0xb234d2e152a03168b76c6474d5322070
+ K_confirmV = 0x683d62024626fe0c5126ef4df58b88ee
+ CMAC(K_confirmP, shareV) = 0x0dc514d262e37470eb43e058e0d615f4
+ CMAC(K_confirmV, shareP) = 0xde076589efcd5d96c2ea6061d96772d9
+ K_shared = 0x488a34663d6be5e02590bb8e9ad9ad3e0f580dec41e8b99ed4ae4b7
+ 34da49287638cac4c9f17fe3c3ae18dda0d6d7f14c17e4640d5a2aaab959efa0cbea
+ 4e546
+
+Acknowledgements
+
+ Thanks to Ben Kaduk and Watson Ladd, from whom this specification
+ originally emanated.
+
+Authors' Addresses
+
+ Tim Taubert
+ Apple Inc.
+ One Apple Park Way
+ Cupertino, California 95014
+ United States of America
+ Email: ttaubert@apple.com
+
+
+ Christopher A. Wood
+ Email: caw@heapingbits.net