Init
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
//
|
||||
// Rfc5054VectorsTests.swift
|
||||
// PortalKitTests
|
||||
//
|
||||
// Verification of RFC 5054 Appendix B test vectors (1024-bit group with SHA-1).
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import PortalKit
|
||||
|
||||
final class Rfc5054VectorsTests: XCTestCase {
|
||||
let group = SrpGroup.rfc5054_1024
|
||||
|
||||
// RFC 5054 Appendix B inputs
|
||||
let I = "alice"
|
||||
let P = "password123"
|
||||
let sHex = "BEB25379D1A8581EB5A727673A2441EE"
|
||||
|
||||
// RFC 5054 Appendix B expected values
|
||||
let expectedKHex = "7556AA045AEF2CDD07ABAF0F665C3E818913186F"
|
||||
let expectedXHex = "94B7555AABE9127CC58CCF4993DB6CF84D16C124"
|
||||
let expectedVHex = """
|
||||
7E273DE8696FFC4F4E337D05B4B375BEB0DDE1569E8FA00A9886D8129BADA1F1\
|
||||
822223CA1A605B530E379BA4729FDC59F105B4787E5186F5C671085A1447B52A\
|
||||
48CF1970B4FB6F8400BBF4CEBFBB168152E08AB5EA53D15C1AFF87B2B9DA6E04\
|
||||
E058AD51CC72BFC9033B564E26480D78E955A5E29E7AB245DB2BE315E2099AFB
|
||||
"""
|
||||
let expectedAHex = "60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DDDA2D4393"
|
||||
let expectedBHex = "E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D105284D20"
|
||||
let expectedPubAHex = """
|
||||
61D5E490F6F1B79547B0704C436F523DD0E560F0C64115BB72557EC44352E890\
|
||||
3211C04692272D8B2D1A5358A2CF1B6E0BFCF99F921530EC8E39356179EAE45E\
|
||||
42BA92AEACED825171E1E8B9AF6D9C03E1327F44BE087EF06530E69F66615261\
|
||||
EEF54073CA11CF5858F0EDFDFE15EFEAB349EF5D76988A3672FAC47B0769447B
|
||||
"""
|
||||
let expectedPubBHex = """
|
||||
BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011BAF38964\
|
||||
DC46A0670DD125B95A981652236F99D9B681CBF87837EC996C6DA04453728610\
|
||||
D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA37089E6F9C6059F388838E7A\
|
||||
00030B331EB76840910440B1B27AAEAEEB4012B7D7665238A8E3FB004B117B58
|
||||
"""
|
||||
let expectedUHex = "CE38B9593487DA98554ED47D70A7AE5F462EF019"
|
||||
let expectedSHex = """
|
||||
B0DC82BABCF30674AE450C0287745E7990A3381F63B387AAF271A10D233861E3\
|
||||
59B48220F7C4693C9AE12B0A6F67809F0876E2D013800D6C41BB59B6D5979B5C\
|
||||
00A172B4A2A5903A0BDCAF8A709585EB2AFAFA8F3499B200210DCC1F10EB3394\
|
||||
3CD67FC88A2F39A4BE5BEC4EC0A3212DC346D7E474B29EDE8A469FFECA686E5A
|
||||
"""
|
||||
|
||||
func testMultiplierK() {
|
||||
let computedK = group.k
|
||||
let computedKHex = SrpFormat.bytesToHex(computedK.serialize())
|
||||
XCTAssertEqual(computedKHex.lowercased(), expectedKHex.lowercased(), "RFC 5054 multiplier k mismatch")
|
||||
}
|
||||
|
||||
func testPrivateKeyX() {
|
||||
guard let sData = SrpFormat.hexToBytes(sHex) else {
|
||||
XCTFail("Failed to decode salt hex")
|
||||
return
|
||||
}
|
||||
let x = SrpMath.computeRfc5054X(identity: I, password: P, salt: sData, hashAlgorithm: group.hashAlgorithm)
|
||||
let xHex = SrpFormat.bytesToHex(x.serialize())
|
||||
XCTAssertEqual(xHex.lowercased(), expectedXHex.lowercased(), "RFC 5054 private key x mismatch")
|
||||
}
|
||||
|
||||
func testVerifierV() {
|
||||
guard let xVal = BigUInt(expectedXHex, radix: 16) else {
|
||||
XCTFail("Failed to parse expected x")
|
||||
return
|
||||
}
|
||||
let v = SrpMath.computeVerifier(g: group.g, x: xVal, N: group.N)
|
||||
let vHex = SrpFormat.bytesToHex(v.toPaddedData(byteCount: 128))
|
||||
XCTAssertEqual(vHex.lowercased(), expectedVHex.lowercased(), "RFC 5054 verifier v mismatch")
|
||||
}
|
||||
|
||||
func testPublicA() {
|
||||
guard let aVal = BigUInt(expectedAHex, radix: 16) else {
|
||||
XCTFail("Failed to parse expected a")
|
||||
return
|
||||
}
|
||||
let A = SrpMath.computeA(g: group.g, a: aVal, N: group.N)
|
||||
let aHex = SrpFormat.bytesToHex(A.toPaddedData(byteCount: 128))
|
||||
XCTAssertEqual(aHex.lowercased(), expectedPubAHex.lowercased(), "RFC 5054 public key A mismatch")
|
||||
}
|
||||
|
||||
func testPublicB() {
|
||||
guard let bVal = BigUInt(expectedBHex, radix: 16),
|
||||
let vVal = BigUInt(expectedVHex, radix: 16) else {
|
||||
XCTFail("Failed to parse b or v")
|
||||
return
|
||||
}
|
||||
let B = SrpMath.computeB(k: group.k, v: vVal, g: group.g, b: bVal, N: group.N)
|
||||
let bHex = SrpFormat.bytesToHex(B.toPaddedData(byteCount: 128))
|
||||
XCTAssertEqual(bHex.lowercased(), expectedPubBHex.lowercased(), "RFC 5054 public key B mismatch")
|
||||
}
|
||||
|
||||
func testScramblerU() {
|
||||
guard let aVal = BigUInt(expectedPubAHex, radix: 16),
|
||||
let bVal = BigUInt(expectedPubBHex, radix: 16) else {
|
||||
XCTFail("Failed to parse A or B")
|
||||
return
|
||||
}
|
||||
let u = SrpMath.computeU(A: aVal, B: bVal, padLength: 128, hashAlgorithm: group.hashAlgorithm)
|
||||
let uHex = SrpFormat.bytesToHex(u.serialize())
|
||||
XCTAssertEqual(uHex.lowercased(), expectedUHex.lowercased(), "RFC 5054 scrambler u mismatch")
|
||||
}
|
||||
|
||||
func testPremasterSecretS() {
|
||||
guard let aVal = BigUInt(expectedAHex, radix: 16),
|
||||
let bVal = BigUInt(expectedBHex, radix: 16),
|
||||
let pubA = BigUInt(expectedPubAHex, radix: 16),
|
||||
let pubB = BigUInt(expectedPubBHex, radix: 16),
|
||||
let xVal = BigUInt(expectedXHex, radix: 16),
|
||||
let vVal = BigUInt(expectedVHex, radix: 16),
|
||||
let uVal = BigUInt(expectedUHex, radix: 16) else {
|
||||
XCTFail("Failed to parse test parameters")
|
||||
return
|
||||
}
|
||||
|
||||
// Client computation: S = (B - k * (g^x mod N)) ^ (a + u * x) mod N
|
||||
let clientS = SrpMath.computeClientS(
|
||||
B: pubB,
|
||||
k: group.k,
|
||||
g: group.g,
|
||||
x: xVal,
|
||||
a: aVal,
|
||||
u: uVal,
|
||||
N: group.N
|
||||
)
|
||||
let clientSHex = SrpFormat.bytesToHex(clientS.toPaddedData(byteCount: 128))
|
||||
XCTAssertEqual(clientSHex.lowercased(), expectedSHex.lowercased(), "Client premaster secret S mismatch")
|
||||
|
||||
// Server computation: S = (A * (v^u mod N)) ^ b mod N
|
||||
let serverS = SrpMath.computeServerS(
|
||||
A: pubA,
|
||||
v: vVal,
|
||||
u: uVal,
|
||||
b: bVal,
|
||||
N: group.N
|
||||
)
|
||||
let serverSHex = SrpFormat.bytesToHex(serverS.toPaddedData(byteCount: 128))
|
||||
XCTAssertEqual(serverSHex.lowercased(), expectedSHex.lowercased(), "Server premaster secret S mismatch")
|
||||
|
||||
// Mutual agreement
|
||||
XCTAssertEqual(clientS, serverS, "Client and Server premaster secrets do not match")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user