Follow-up from a review comment on #630: #630 (comment)
can be replaced with the primitive HKDF<SHA256>.deriveKey(inputKeyMaterial:salt:info:outputByteCount: 32)
Context
PaykitReceiverNoiseKeyDerivation.derive in Bitkit/Services/PubkyService.swift hand-rolls HKDF-SHA256:
static func derive(seed: Data, network: String, receiverPath: String) -> Data {
let domainBytes = Data(domain.utf8)
let salt = Data(SHA256.hash(data: domainBytes))
var prk = Data(HMAC<SHA256>.authenticationCode(for: seed, using: SymmetricKey(data: salt)))
defer { prk.resetBytes(in: prk.startIndex ..< prk.endIndex) }
var expandInput = Data("\(version)\0\(network)\0\(receiverPath)".utf8)
expandInput.append(0x01)
return Data(HMAC<SHA256>.authenticationCode(for: expandInput, using: SymmetricKey(data: prk)))
}
This is exactly HKDF-Extract-and-Expand for a single 32-byte output block, so it is equivalent to:
HKDF<SHA256>.deriveKey(
inputKeyMaterial: SymmetricKey(data: seed),
salt: salt,
info: Data("\(version)\0\(network)\0\(receiverPath)".utf8),
outputByteCount: 32
)
Why
Removes hand-rolled crypto from the wallet in favour of the platform primitive. The output bytes are identical, so this is a pure refactor.
Acceptance
PaykitReceiverNoiseKeyDerivation.derive uses HKDF<SHA256>.deriveKey.
PaykitReceiverNoiseKeyStoreTests.testDerivationMatchesVersionedCrossPlatformVector still passes unchanged — it pins the cross-platform vector shared with Android (500f4799bbb2d02103e3b74b365ddb478a3187333c053fa9eb62f4052ba6a327), so a green test is the parity guarantee.
- No change to the derived key for existing users (a changed key would fail closed in
PaykitReceiverNoiseKeyStore.validatedKeyBytes and break Paykit).
Follow-up from a review comment on #630: #630 (comment)
Context
PaykitReceiverNoiseKeyDerivation.deriveinBitkit/Services/PubkyService.swifthand-rolls HKDF-SHA256:This is exactly HKDF-Extract-and-Expand for a single 32-byte output block, so it is equivalent to:
Why
Removes hand-rolled crypto from the wallet in favour of the platform primitive. The output bytes are identical, so this is a pure refactor.
Acceptance
PaykitReceiverNoiseKeyDerivation.deriveusesHKDF<SHA256>.deriveKey.PaykitReceiverNoiseKeyStoreTests.testDerivationMatchesVersionedCrossPlatformVectorstill passes unchanged — it pins the cross-platform vector shared with Android (500f4799bbb2d02103e3b74b365ddb478a3187333c053fa9eb62f4052ba6a327), so a green test is the parity guarantee.PaykitReceiverNoiseKeyStore.validatedKeyBytesand break Paykit).