This chapter introduces the various cryptographic primitives, algorithms and protocol building blocks used in this protocol. It introduces for each of them a functional abstraction that can be referred to in the other chapters of this specification. This chapter also maps those cryptographic primitives to specific instances with the corresponding appropriate informative or normative references. Wherever relevant, it also gives necessary or relevant information about the use of these mappings in a specific context to achieve a compliant implementation.

Given a version of the Message Format, the cryptographic primitives are mapped to specific instances. There is no cryptosuite negotiation in this protocol: one version of the Message Format has one cryptosuite as defined in this chapter.

Each section defines cryptographic primitives generically, together with concrete mappings to specific instances of these cryptographic primitives for version 1.0 of the Message Format. This chapter can also be used as guidance about which cryptographic primitives need to be supported by a device, but it must be noted that not all devices will have to support all of them. For example, a device may not require the Crypto_PBKDF() primitive, as values based on this operation could in some instances be precomputed and stored during the manufacturing process of the device. The proposed functional mapping in this chapter is normative with respect to the values computed by the functions but informative with respect to the way the functions are interfaced within implementations. For example, a function returning both a boolean to indicate success and a value if the operation is successful could also be implemented using exception mechanisms instead of returning a boolean.

It must also be noted that not all cryptographic primitives are exposed to the other parts of the specification. For example, the Crypto_TRNG() primitive SHALL NOT be called outside of the Crypto_DRBG() implementation.

CAUTION TODO: check on whether a specific language should be used or referred to for the description of the functional representations.

## Deterministic Random Bit Generator (DRBG)

This protocol relies on random numbers for many security purposes. For example, random numbers are used in generating secret keys, counters, cryptographic signature generation random secrets, etc. Those random numbers SHALL be generated using the Crypto_DRBG() function.

Function and description

bit[len] Crypto_DRBG(int len)

Returns an array of len random bits.

Mapping (Version 1.0)

Crypto_DRBG() SHALL be implemented with one of the following DRBG algorithms as defined in NIST 800-90A (the choice of which one is left to the manufacturer because the choice has no impact on the interoperability):

Crypto_DRBG() SHALL be seeded using Crypto_TRNG() with at least 256 bits of entropy (see among others Chapter 4 and Section 8.4 of NIST 800-90A).

CTR DRBG (with AES-CTR)

HMAC DRBG (with SHA-256)

HMAC DRBG (with SHA-512)

Hash DRBG (with SHA-256)

Hash DRBG (with SHA-512)

## True Random Number Generator (TRNG)

Returns an array of len random bits.

#### Function and description

bit[len] Crypto_TRNG(int len)

A TRNG (aka. Entropy Source) is required to provide an entropy seed as an input to the DRBG algorithm.

Mapping (Version 1.0)

Crypto_TRNG() MAY be implemented according to the NIST 800-90B implementation guidelines but alternate implementations MAY be used.

In accordance with good security practices, the Crypto_TRNG() SHALL never be called directly but rather SHALL be used in the implementation of Crypto_DRBG().

## Hash function (Hash)

Crypto_Hash() computes the cryptographic hash of a message.

Mapping (Version 1.0)

int CRYPTO_HASH_LEN_BITS := 256

int CRYPTO_HASH_LEN_BYTES := 32

int CRYPTO_HASH_BLOCK_LEN_BYTES := 64

Crypto_Hash(message) :=

byte[CRYPTO_HASH_LEN_BYTES] SHA-256(M := message)

SHA-256() SHALL be computed as defined in Section 6.2 of FIPS 180-4.

Returns the cryptographic hash digest of the message.

#### Function and description

byte[CRYPTO_HASH_LEN_IN_BYTES]

Crypto_Hash(byte[] message)

## Keyed-Hash Message Authentication Code (HMAC)

Returns the cryptographic keyed-hash message authentication code of a message using the given

key.

#### Function and description

byte[CRYPTO_HASH_LEN_BYTES]

Crypto_HMAC(byte[] key, byte[] message)

HMAC() SHALL be computed as defined in FIPS 198-1 using Crypto_Hash() as the underlying hash function H (this is also referred to as HMAC-SHA256()) and CRYPTO_HASH_LEN_BYTES is defined in Section 3.3, “Hash function (Hash)”.

#### Mapping (Version 1.0)

Crypto_HMAC(key, message) :=

byte[CRYPTO_HASH_LEN_BYTES] HMAC(K := key, text := message)

Crypto_HMAC() computes the cryptographic keyed-hash message authentication code of a message.

## Public Key Cryptography

Matter specifies the following scheme and parameters for public key cryptography.

### Group

The public key cryptography of Matter relies on the group defined in the following mapping table.

Mapping (Version 1.0)

Matter public key cryptography SHALL be based on Elliptic Curve Cryptography (ECC) with the elliptic curve: secp256r1 defined in Section 2.4.2 of SEC 2. (Informative: Note that this curve is also referred to as NIST P-256 or prime256v1 in FIPS 186-4 and NIST 800-186.)

PrivateKey is an opaque data type to hold either the private key or any handle or reference that allows other primitives to access the corresponding private key.

PublicKey is an opaque data type to hold the public key or any handle or reference that allows other primitives to access the corresponding public key. A public key is a point on the elliptic curve. (Note: at places in the specification where public keys are to be explicitly transmitted, the format in which they are transmitted is specified.)

int CRYPTO_GROUP_SIZE_BITS := 256

int CRYPTO_GROUP_SIZE_BYTES := 32

int CRYPTO_PUBLIC_KEY_SIZE_BYTES : = (2 * CRYPTO_GROUP_SIZE_BYTES) + 1 = 65 is the size in bytes of the public key representation when encoded using the uncompressed public key format as specified in section 2.3 of SEC 1.

struct {

PublicKey publicKey; PrivateKey privateKey;

} KeyPair;

### Key generation

Crypto_GenerateKeyPair() is the function to generate a key pair.

Generates a key pair and returns a KeyPair.

#### Function and description

KeyPair Crypto_GenerateKeyPair()

ECCGenerateKeypair() SHALL generate a key pair according to Section 3.2.1 of SEC 1.

#### Mapping (Version 1.0)

Crypto_GenerateKeypair() := KeyPair ECCGenerateKeypair()

### Signature and verification

Crypto_Sign() is used to sign a message, and Crypto_Verify() is used to verify a signature on a message.

#### Mapping (Version 1.0)

struct {

byte[CRYPTO_GROUP_SIZE_BYTES] r, byte[CRYPTO_GROUP_SIZE_BYTES] s

} Signature

These functions either generate or verify a signature of type Signature defined by the following mapping.

Returns the signature of the message using the privateKey.

#### Function and description

Signature Crypto_Sign(

PrivateKey privateKey, byte[] message)

#### Signature

ECDSASign() SHALL be the ECDSA signature function as defined in Section 4.1 of SEC 1 using

Crypto_Hash() as the underlying hash Hash() function.

#### Mapping (Version 1.0)

Crypto_Sign(privateKey, message) :=

Signature ECDSASign(dU := privateKey, M := message)

Verifies the signature of the message using the publicKey, returns TRUE if the verification succeeds,

FALSE otherwise.

#### Function and description

boolean Crypto_Verify(

PublicKey publicKey, byte[] message, Signature signature)

#### Signature verification

ECDSAVerify() SHALL be the ECDSA signature verification function as defined in Section 4.1.4 of SEC 1 using Crypto_Hash() as the underlying hash function Hash(); returns TRUE if the verification succeeds and FALSE otherwise.

#### Mapping (Version 1.0)

Crypto_Verify(publicKey, message, signature) :=

boolean ECDSAVerify(QU := publicKey, M := message, S := signature)

### ECDH

Computes a shared secret using Elliptic Curve Diffie-Hellman.

#### Function and description

byte[CRYPTO_GROUP_SIZE_BYTES]

Crypto_ECDH(

PrivateKey myPrivateKey, PublicKey theirPublicKey)

Crypto_ECDH() is used to compute a shared secret from the Elliptic Curve Diffie-Hellman (ECDH) protocol.

The output of ECDH() SHALL be the serialization of the x-coordinate of the resultant point as defined in Section 3.3.1 of SEC 1.

#### Mapping (Version 1.0)

Crypto_ECDH(myPrivateKey, theirPublicKey) :=

byte[CRYPTO_GROUP_SIZE_BYTES] ECDH(dU := myPrivateKey, QV := theirPublicKey)

### Certificate validation

Crypto_VerifyChain() is used to verify Matter certificates.

verified is TRUE if the Matter certificates are verified as prescribed by RFC 5280.

#### Mapping (Version 1.0)

Crypto_VerifyChain(certificates) := boolean verified

Crypto_VerifyChainDER() is used to verify public key X.509 v3 certificates in X.509 v3 DER format.

Function and description

boolean

Crypto_VerifyChain(MatterCertificate[] certificates)

Given Matter certificates, Crypto_VerifyChain() performs all the necessary validity checks on certificates, taking in account that the notion of "current time" for the purposes of validation SHALL abide by the rules in Section 3.5.6, “Time and date considerations for certificate path validation”.

boolean

Crypto_VerifyChainDER(DERCertificate[] certificates)

Given a list of DER-encoded certificates in RFC 5280 format, starting at the end-entity (leaf) certificate, and following the chain of trust towards the root, Crypto_VerifyChainDER() performs all the necessary validity checks on certificates.

The Validity period validation for the root and optional intermediate certificates is performed against the notBefore timestamp of the end-entity (leaf certificate) used as value for the current time.

Mapping (Version 1.0)

Crypto_VerifyChainDER(certificates) := boolean verified

verified is TRUE if the certificates are verified as prescribed by RFC 5280.

#### CAUTION

TODO: Stating that they are to be verified as prescribed by RFC 5280 is not sufficient. More information should be provided somewhere in the specification on which specific checks are to be performed.

### Time and date considerations for certificate path validation

The Basic Path Validation algorithm in RFC 5280 mandates the consideration of the "current time" against the validity period (notBefore, notAfter fields) when validating paths. The usage of "current time" assumes that such a time is available and correct, which is a strong assumption when considering some constrained devices or devices only locally reachable on a network in the absence of infrastructure to synchronize time against a global real-time reference.

When the Crypto_VerifyChain primitive is used, rather than overriding the Basic Path Validation algorithm of RFC 5280, Nodes SHALL consider the following definition of "current time" that accounts for the possible lack of a real time reference:

If a Node has a current real-time clock value which is trusted according to implementation- defined means to be accurate with regard to global real-time, whether using Time Synchronization features of this specification or other means, then it SHALL use that time;

Otherwise, the current time SHALL be set to the last-known-good UTC time.

Upon failure to validate a certificate path, where the only reason for failure is an invalid validity period of a path element, a Node MAY apply a policy of its choice to determine whether to ignore this failure and still consider the path valid.

#### Last Known Good UTC Time

Nodes SHALL maintain a stored Last Known Good UTC Time. This time is used as a fallback for cryptographic credentials expiry enforcement, if all other available time synchronization mechanisms fail.

The last known good UTC time SHALL be updated at commissioning and MAY be updated after a successful time synchronization, or by an embedded time in an OTA. Nodes SHOULD store a Last Known Good UTC Time value to persistent storage at least once a month. A Node’s initial out-of-box Last Known Good UTC time SHALL be the compile-time of the firmware.

A Node MAY adjust the Last Known Good UTC Time backwards if it believes the current Last Known Good UTC Time is incorrect and it has a good time value from a trusted source. The Node SHOULD NOT adjust the Last Known Good UTC to a time before the later of:

The build timestamp of its currently running software image

The not-before timestamp of any of its operational certificates (see Section 6.4.5, “Node Operational Credentials Certificates”).

If a Node has used the Last Known Good UTC Time, it SHOULD recheck its security materials and existing connections if it later achieves time synchronization.

## Data Confidentiality and Integrity

Symmetric block ciphers are used to provide message security.

All unicast and multicast messages between Nodes requiring protection for confidentiality and integrity with data origin authentication SHALL use Authenticated Encryption with Associated Data (AEAD) as primitive to protect those messages.

Mapping (Version 1.0)

Data confidentiality and integrity SHALL use the AES-CCM mode as defined in NIST 800-38C with the following parameters:

A.1 of NIST 800-38C.

SymmetricKey is an opaque data type to hold a symmetric block cipher key or any handle or reference that allows other primitives to access the corresponding key.

int CRYPTO_SYMMETRIC_KEY_LENGTH_BITS := 128 (this is the key length of the underlying block cipher in bits)

int CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES := 16 (this is the key length of the underlying block cipher in bytes)

int CRYPTO_AEAD_MIC_LENGTH_BITS := 128 (this is the MIC length in bits)

int CRYPTO_AEAD_MIC_LENGTH_BYTES := 16 (this is the MIC length in bytes)

int CRYPTO_AEAD_NONCE_LENGTH_BYTES := 13

Key length SHALL be CRYPTO_SYMMETRIC_KEY_LENGTH_BITS bits.

MIC length SHALL be CRYPTO_AEAD_MIC_LENGTH_BITS bits.

The parameter q SHALL be 2 (length of encoding of maximum length) as specified in Appendix

The parameter n SHALL be CRYPTO_AEAD_NONCE_LENGTH_BYTES (length of nonce in bytes) as specified in Appendix A.1 of NIST 800-38C.

### Generate and encrypt

Performs the generate and encrypt computation on payload P and the associated data A using the key K and a nonce N; the output contains the ciphertext and the tag truncated to Tlen bits (the encoding of the output depends on the mapping to the specific instance of the cryptographic primitive).

#### Function and description

byte[lengthInBytes(P) + CRYPTO_AEAD_MIC_LENGTH_BYTES] Crypto_AEAD_GenerateEncrypt(

SymmetricKey K, byte[lengthInBytes(P)] P, byte[] A,

byte[CRYPTO_AEAD_NONCE_LENGTH_BYTES] N)

AES-CCM-GenerateEncrypt() SHALL be the function described in Section 6.1 of NIST 800-38C with the counter generation function of Appendix A.3 of NIST 800-38C and the formatting function as defined in Appendix A.2 of NIST 800-38C; returns the encoding of the ciphertext and the tag of length Tlen bits, as specified in Section 6.1 of NIST 800-38C as a byte array.

#### Mapping (Version 1.0)

Crypto_AEAD_GenerateEncrypt(K, P, A, N) :=

byte[lengthInBytes(P) + CRYPTO_AEAD_MIC_LENGTH_BYTES] AES-CCM-GenerateEncrypt(K

:= K, P := P, A := A, N := N, Tlen := CRYPTO_AEAD_MIC_LENGTH_BITS)

### Decrypt and verify

#### Function and description

{boolean success, byte[lengthInBytes(P)] payload} Crypto_AEAD_DecryptVerify(

SymmetricKey K,

byte[lengthInBytes(P) + CRYPTO_AEAD_MIC_LENGTH_BYTES] C, byte[] A,

byte[CRYPTO_AEAD_NONCE_LENGTH_BYTES] N)

Performs the decrypt and verify computation on the combined ciphertext and tag C and the associated data A using the key K and a nonce N. Note that the encoding of C depends on the mapping of the specific instance of the cryptography primitive.

This function has two outcomes:

If tag verification succeeds, the success output is TRUE and the payload array contains the decrypted payload P.

If tag verification fails, the success output is FALSE and the contents of the payload array is undefined.

AES-CCM-DecryptVerify() SHALL be the function described in Section 6.2 of NIST 800-38C with the counter generation function of Appendix A.3 of NIST 800-38C and the formatting function as defined in Appendix A.2 of NIST 800-38C and C SHALL be a byte array containing the ciphertext as specified in Section 6.2 of NIST 800-38C.

If tag verification succeeds, the success output is TRUE and the payload array contains the decrypted payload P.

If tag verification fails, the success output is FALSE and the contents of the payload array is undefined.

#### Mapping (Version 1.0)

Crypto_AEAD_DecryptVerify(K, C, A, N) :=

{boolean, byte[lengthInBytes(P)]} AES-CCM-DecryptVerify(K := K, C := C, A := A, N := N, Tlen := CRYPTO_AEAD_MIC_LENGTH_BITS)

## Message privacy

Message privacy is implemented using a block cipher in CTR mode.

Mapping (Version 1.0)

Message privacy SHALL use the AES-CTR mode as defined in NIST 800-38A with the following parameters:

int CRYPTO_PRIVACY_NONCE_LENGTH_BYTES := 13

Key length SHALL be CRYPTO_SYMMETRIC_KEY_LENGTH_BITS bits.

Performs the encryption of the message M using the key K and a nonce N; the output contains the data M encrypted.

#### Function and description

byte[lengthInBytes(M)] Crypto_Privacy_Encrypt(

SymmetricKey K, byte[lengthInBytes(M)] M,

byte[CRYPTO_PRIVACY_NONCE_LENGTH_BYTES] N)

### Privacy encryption

AES-CTR-Encrypt() SHALL be the encryption function described in Section 6.5 of NIST 800-38A with the sequence of counters T being generated according to the counter generation function of Appendix A.3 of NIST 800-38C using N and the value of q = 2; returns the encrypted message as a byte array.

#### Mapping (Version 1.0)

Crypto_Privacy_Encrypt(K, M, N) := byte[lengthInBytes(M)]

AES-CTR-Encrypt(K := K, P := M, N := N)

Performs the decryption of C using the key K and a nonce N; the output M is the decryption of C

#### Function and description

byte[lengthInBytes(C)] Crypto_Privacy_Decrypt(

SymmetricKey K, byte[lengthInBytes(C)] C,

byte[CRYPTO_PRIVACY_NONCE_LENGTH_BYTES] N)

### Privacy decryption

AES-CTR-Decrypt() SHALL be the decryption function described in Section 6.5 of NIST 800-38A with the sequence of counters T being generated according to the counter generation function of Appendix A.3 of NIST 800-38C using N and the value of q = 2; returns the decrypted message as a byte array.

#### Mapping (Version 1.0)

Crypto_Privacy_Decrypt(K, C, N) := byte[lengthInBytes(C)]

AES-CTR-Decrypt(K := K, C := C, N := N)

## Key Derivation Function (KDF)

Returns the key of len bits derived from inputKey using the salt and the info; len SHALL be a multiple of 8.

#### Function and description

bit[len] Crypto_KDF(

byte[] inputKey, byte[] salt, byte[] info,

int len)

Matter specifies the following key derivation function to generate encryption keys.

KDM() SHALL be the HMAC-based KDF function with Crypto_HMAC(key := salt, message := x) as the auxiliary function H as defined in Section 4.1 Option 2 of NIST 800-56C; it returns a bit array of len bits.

#### Mapping (Version 1.0)

Crypto_KDF(inputKey, salt, info, len) :=

bit[len] KDM(Z := inputKey, OtherInput := {salt := salt, L := len, FixedInfo := info})

When multiple keys of the same length are generated by a single KDF call, the following shorthand notation can be used:

Key1 || Key2 || Key3 = Crypto_KDF (

inputKey = inputKeyMaterial, salt = [],

info = [],

// 3 below matches number of keys expressed in concatenated output len = 3 * CRYPTO_SYMMETRIC_KEY_LENGTH_BITS

)

This is equivalent to the following:

Keys = Crypto_KDF (

inputKey = inputKeyMaterial, salt = [],

info = [],

len = 3 * CRYPTO_SYMMETRIC_KEY_LENGTH_BITS

)

Set Key1 to the CRYPTO_SYMMETRIC_KEY_LENGTH_BITS most significant bits of Keys.

Set Key2 to the next CRYPTO_SYMMETRIC_KEY_LENGTH_BITS significant bits of Keys.

Set Key3 to the CRYPTO_SYMMETRIC_KEY_LENGTH_BITS least significant bits of Keys.

## Password-Based Key Derivation Function (PBKDF)

Returns a value of len bits derived from the input using the salt and iterations iterations.

bit[len] Crypto_PBKDF(

byte[] input, byte[] salt, int iterations, int len)

#### Function and description

Matter specifies the following password-based key derivation function to compute a derived key from a cryptographically weak password.

Mapping (Version 1.0)

int CRYPTO_PBKDF_ITERATIONS_MIN := 1000

int CRYPTO_PBKDF_ITERATIONS_MAX := 100000

Crypto_PBKDF(input, salt, iterations, len) :=

bit[len] PBKDF2(P := input, S := salt, C := iterations, kLen := len)

PBKDF2() SHALL be the HMAC-based PBKDF function with Crypto_HMAC(key := P, message := U[j- 1]) as the auxiliary function HMAC as defined in Section 5.3 of NIST 800-132; it returns a bit array of len bits.

Crypto_PBKDFParameterSet => STRUCTURE [ tag-order ]

{

iterations [1] : UNSIGNED INTEGER [ range 32-bits ], salt [2] : OCTET STRING [ length 16..32 ],

}

CRYPTO_PBKDF_ITERATIONS_MIN <= iterations <= CRYPTO_PBKDF_ITERATIONS_MAX.

iterations: An integer value specifying the number of PBKDF2 iterations:

salt: A random value per device of at least 16 bytes and at most 32 bytes used as the PBKDF2 salt.

Maintains the set of parameters exchanged between a Commissioner and a Commissionee during their pairing.

#### Type and description

STRUCTURE Crypto_PBKDFParameterSet

## Password-Authenticated Key Exchange (PAKE)

This protocol uses password-authenticated key exchange (PAKE) for the PASE protocol.

Mapping (Version 1.0)

Matter uses SPAKE2+ as described in SPAKE2+ as PAKE with:

The SPAKE2+ verifier is the Commissionee/Responder and the SPAKE2+ prover is the Commissioner/Initiator

Crypto_PBKDF() as underlying PBKDF (see Section 3.9, “Password-Based Key Derivation Function (PBKDF)”), with arguments as described in the definition of Crypto_PAKEValues_Initiator

NIST P-256 elliptic curve as underlying group (see Section 3.5.1, “Group”).

SPAKE2+ requires two additional points on the curve: M and N. The values of M and N are taken from the draft version 2 of the SPAKE2+ specification (SPAKE2+) and are listed below in compressed format (format defined in section 2.3 of SEC 1):

M = 02886e2f97ace46e55ba9dd7242579f2993b64e16ef3dcab95afd497333d8fa12f

N = 03d8bbd6c639c62937b04d997f38c3770719c629d7014d49a24b4f98baa1292b49

Crypto_Hash() as underlying hash function (see Section 3.3, “Hash function (Hash)”).

Crypto_HMAC() as underlying HMAC function (see Section 3.4, “Keyed-Hash Message Authentication Code (HMAC)”).

KDF(info, key, salt) := Crypto_KDF(key, salt, info, CRYPTO_HASH_LEN_BITS) as underlying KDF function (see Section 3.8, “Key Derivation Function (KDF)”).

Mapping (Version 1.0)

Crypto_PAKEValues_Initiator := (w0, w1) where w0 and w1 SHALL be computed as follows:

CRYPTO_W_SIZE_BYTES := CRYPTO_GROUP_SIZE_BYTES + 8 CRYPTO_W_SIZE_BITS := CRYPTO_W_SIZE_BYTES * 8

byte w0s[CRYPTO_W_SIZE_BYTES] || byte w1s[CRYPTO_W_SIZE_BYTES] = (byte[2 * CRYPTO_W_SIZE_BYTES])

bit[2 * CRYPTO_W_SIZE_BITS]

Crypto_PBKDF(passcode, salt, iterations, 2 * CRYPTO_W_SIZE_BITS) byte w0[CRYPTO_GROUP_SIZE_BYTES] = w0s mod p

byte w1[CRYPTO_GROUP_SIZE_BYTES] = w1s mod p

where:

mod is the mathematical modulo operation and || is the string concatenation or split operator.

passcode, is the Passcode defined in Section 5.1.1.6, “Passcode”, serialized as little-endian over 4 octets. For example, passcode 18924017 would be encoded as the octet string f1:c1:20:01 and the passcode 00000005 would be encoded as the octet string 05:00:00:00.

p is the order of the underlying elliptic curve.

Both w0s and w1s SHALL have a length equal to (CRYPTO_GROUP_SIZE_BYTES + 8).

salt and iterations are extracted from the Crypto_PBKDFParameterSet values.

The pair (w0,w1) is also referred to as Commissioner PAKE input

#### Mapping (Version 1.0)

Crypto_PAKEValues_Responder := (w0, L) where w0 and L SHALL be computed as follows:

byte w0s[CRYPTO_W_SIZE_BYTES] || byte w1s[CRYPTO_W_SIZE_BYTES] = (byte[2 * CRYPTO_W_SIZE_BYTES])

bit[2 * CRYPTO_W_SIZE_BITS]

Crypto_PBKDF(passcode, salt, iterations, 2 * CRYPTO_W_SIZE_BITS) byte w0[CRYPTO_GROUP_SIZE_BYTES] = w0s mod p

byte w1[CRYPTO_GROUP_SIZE_BYTES] = w1s mod p byte L[CRYPTO_PUBLIC_KEY_SIZE_BYTES] = w1 * P

where:

passcode, is the Passcode defined in Section 5.1.1.6, “Passcode”.

p is the order of the elliptic curve to be used.

Both w0s and w1s SHALL have a length equal to (CRYPTO_GROUP_SIZE_BYTES + 8).

salt and iterations are extracted from the Crypto_PBKDFParameterSet values.

P is the generator of the underlying elliptic curve.

The computation of Crypto_PAKEValues_Responder SHALL be computed at device manufacturing time and w0 and L SHALL be stored in the Responder and w1 SHALL NOT be stored in the Responder.

The pair (w0,L) is also referred to as Commissionee PAKE input or verification value

pA is in uncompressed public key format as specified in section 2.3 of SEC 1. pA SHALL be computed as specified in SPAKE2+.

#### Mapping (Version 1.0)

Crypto_pA(Crypto_PAKEValues_Initiator) := byte pA[CRYPTO_PUBLIC_KEY_SIZE_BYTES]

### Computation of pA

### Computation of pB

pB is in uncompressed public key format as specified in section 2.3 of SEC 1. pB SHALL be computed as specified in SPAKE2+.

#### Mapping (Version 1.0)

Crypto_pB(Crypto_PAKEValues_Responder) := byte pB[CRYPTO_PUBLIC_KEY_SIZE_BYTES]

Z and V SHALL be computed from pA and pB as specified in SPAKE2+.

Note the two 0x0000000000000000 null-lengths indicate that no identities are present and each null- lengths is 8 bytes wide since it is specified by the SPAKE2+ specification that lengths are eight-byte little-endian numbers. The SPAKE2+ specification indicates that we must include these length fields.

Note in case PBKDFParamRequest and PBKDFParamResponse messages are not exchanged, they SHALL be replaced by empty strings in the Context computation.

Crypto_Transcript() SHALL compute TT as specified in SPAKE2+ with:

#### Mapping (Version 1.0)

||

||

||

||

||

||

|| M

|| N

|| pA

|| pB

|| Z

|| V

|| w0

|| 0x0000000000000000 ||

||

|| Context

lengthInBytes(Context) 0x0000000000000000

lengthInBytes(M) lengthInBytes(N) lengthInBytes(pA) lengthInBytes(pB) lengthInBytes(Z) lengthInBytes(V) lengthInBytes(w0)

Context := Crypto_Hash("Matter PAKE V1 Commissioning" || PBKDFParamRequest || PBKDFParamResponse)

TT :=

Crypto_Transcript(PBKDFParamRequest, PBKDFParamResponse, pA, pB) := byte[] TT

### Computation of transcript TT

### Computation of cA, cB and Ke

Mapping (Version 1.0) |

Crypto_P2(TT, pA, pB) := {byte cA[CRYPTO_HASH_LEN_BYTES], byte cB[CRYPTO_HASH_LEN_BYTES], byte Ke[CRYPTO_HASH_LEN_BYTES/2]} Crypto_P2() SHALL compute cA, cB and Ke as specified in SPAKE2+ with cA := CRYPTO_HMAC(KcA,pB) and cB := CRYPTO_HMAC(KcB,pA). |