You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Matter controller object on IOS does not expose the CompressedFabricId so I am trying to compute it myself. This code appears to do what the spec requires but it does not produce the correct value (87e1b004e235a130) Does anyone have correct code? The test data is the example from the Matter spec.
import Foundation
import CryptoKit
func hkdfExpand(prk: SymmetricKey, info: Data, outputByteCount: Int) -> Data {
var output = Data()
var t = Data()
var i: UInt8 = 1
while output.count < outputByteCount {
var hmac = HMAC<SHA256>(key: prk)
hmac.update(data: t)
hmac.update(data: info)
hmac.update(data: [i])
t = Data(hmac.finalize())
output.append(t)
i += 1
}
return output.prefix(outputByteCount)
}
func computeCompressedFabricId(fabricId: UInt64, rootPublicKey: Data) -> UInt64 {
// Step 1: Convert FabricId to 64-bit big-endian byte array
var fabricIdBytes = withUnsafeBytes(of: fabricId.bigEndian) { Data($0) }
// Step 2: Concatenate FabricId and RootPublicKey
var inputKeyMaterial = fabricIdBytes
inputKeyMaterial.append(rootPublicKey)
// Step 3: Prepare the SALT
let salt = "CompressedFabric".data(using: .utf8)!
// Step 4: Perform HKDF-Extract to derive the PRK
let prk = HMAC<SHA256>.authenticationCode(for: inputKeyMaterial, using: SymmetricKey(data: salt))
// Step 5: Perform HKDF-Expand to derive the compressedFabricId
let info = Data() // Empty info (optional context)
let outputByteCount = 8 // 64-bit output
let expandedKey = hkdfExpand(prk: SymmetricKey(data: prk), info: info, outputByteCount: outputByteCount)
// Step 6: Convert the first 8 bytes to UInt64 (big-endian)
let compressedFabricId = expandedKey.withUnsafeBytes { buffer in
buffer.load(fromByteOffset: 0, as: UInt64.self).bigEndian
}
return compressedFabricId
}
// Usage Example
let fabricId: UInt64 = 0x2906c908d115d362 // FabricId in hexadecimal
let rootPublicKey = Data([0x4a, 0x9f, 0x42, 0xb1, 0xca, 0x48, 0x40, 0xd3, 0x72, 0x92, 0xbb, 0xc7, 0xf6, 0xa7, 0xe1, 0x1e, 0x22, 0x20, 0x0c, 0x97, 0x6f, 0xc9, 0x00, 0xdb, 0xc9, 0x8a, 0x7a, 0x38, 0x3a, 0x64, 0x1c, 0xb8, 0x25, 0x4a, 0x2e, 0x56, 0xd4, 0xe2, 0x95, 0xa8, 0x47, 0x94, 0x3b, 0x4e, 0x38, 0x97, 0xc4, 0xa7, 0x73, 0xe9, 0x30, 0x27, 0x7b, 0x4d, 0x9f, 0xbe, 0xde, 0x8a, 0x05, 0x26, 0x86, 0xbf, 0xac, 0xfa]) // RootPublicKey in hexadecimal
let compressedFabricId = computeCompressedFabricId(fabricId: fabricId, rootPublicKey: rootPublicKey)
print("Compressed Fabric ID: \(String(format: "%016llx", compressedFabricId))")
The text was updated successfully, but these errors were encountered:
My controller needs to enumerate the commissioned nodes it can see on its fabric. To do that it uses MDNS to find all of the matter devices, and then matches the top half of the name to the compressed fabric id. This is because there are multiple controllers (phones) and they want to locate devices commissioned by other phones onto the same fabric. We don't have a hub tracking the list of commissioned devices so it has to be constructed by browsing MDNS.
The Matter controller object on IOS does not expose the CompressedFabricId so I am trying to compute it myself. This code appears to do what the spec requires but it does not produce the correct value (87e1b004e235a130) Does anyone have correct code? The test data is the example from the Matter spec.
The text was updated successfully, but these errors were encountered: