94 lines
3.9 KiB
Swift
94 lines
3.9 KiB
Swift
import Foundation
|
|
|
|
enum MibNonce {
|
|
/**
|
|
* Generates the nonce string from the nonceGenerator token returned by DH key exchange.
|
|
*
|
|
* Phase 1: for each dash-separated group, take the first token's digits * random(1-99),
|
|
* pad to 5 digits, compute digitSum and lastTwo.
|
|
* Phase 2: for each group tokens 1-7, apply the operation letter with carry chain.
|
|
* Operations: M=(carry%num)+ds+cumSum, A=carry+num+ds+cumSum,
|
|
* S=carry²+num+ds+cumSum, X=carry*num+ds+cumSum, C=carry³+num+ds+cumSum
|
|
*/
|
|
static func generate(_ nonceGenerator: String) -> String {
|
|
let groups = nonceGenerator.split(separator: "-", omittingEmptySubsequences: false).map(String.init)
|
|
|
|
var paddedList: [String] = []
|
|
var lastTwoList: [Int] = []
|
|
var digitSumList: [Int] = []
|
|
var cumSum = 0
|
|
|
|
// Phase 1
|
|
for group in groups {
|
|
let tokens = group.trimmingCharacters(in: .whitespaces).components(separatedBy: " ")
|
|
let nStr = tokens[0].filter { $0.isNumber }
|
|
let n = Int(nStr) ?? 1
|
|
let r = Int.random(in: 1...99)
|
|
let product = n * r
|
|
let padded = String(format: "%05d", product)
|
|
let ds = padded.compactMap { $0.wholeNumberValue }.reduce(0, +)
|
|
let lt = Int(padded.suffix(2)) ?? 0
|
|
paddedList.append(padded)
|
|
lastTwoList.append(lt)
|
|
digitSumList.append(ds)
|
|
cumSum += ds
|
|
}
|
|
|
|
// Phase 2
|
|
var resultGroups: [String] = []
|
|
for (i, group) in groups.enumerated() {
|
|
let tokens = group.trimmingCharacters(in: .whitespaces).components(separatedBy: " ")
|
|
var carry = lastTwoList[i]
|
|
let ds = digitSumList[i]
|
|
var nonceDigits: [Int] = []
|
|
|
|
for j in 1...7 {
|
|
guard j < tokens.count else { nonceDigits.append(0); continue }
|
|
let token = tokens[j]
|
|
let op = token.filter { $0.isLetter }
|
|
let num = Int(token.filter { $0.isNumber }) ?? 1
|
|
let value: Int64
|
|
switch op {
|
|
case "M": value = Int64(carry % num) + Int64(ds) + Int64(cumSum)
|
|
case "A": value = Int64(carry) + Int64(num) + Int64(ds) + Int64(cumSum)
|
|
case "S": value = Int64(carry) * Int64(carry) + Int64(num) + Int64(ds) + Int64(cumSum)
|
|
case "X": value = Int64(carry) * Int64(num) + Int64(ds) + Int64(cumSum)
|
|
case "C": value = Int64(carry) * Int64(carry) * Int64(carry) + Int64(num) + Int64(ds) + Int64(cumSum)
|
|
default: value = 0
|
|
}
|
|
let digit = Int(String(abs(value)).suffix(2)) ?? 0
|
|
nonceDigits.append(digit)
|
|
carry = digit
|
|
}
|
|
|
|
let digitStr = nonceDigits.map { String(format: "%02d", $0) }.joined(separator: " ")
|
|
resultGroups.append("\(paddedList[i]) \(digitStr)")
|
|
}
|
|
|
|
return resultGroups.joined(separator: "-")
|
|
}
|
|
|
|
// Random long in [1_000_000, 16_000_000)
|
|
static func randomSodium() -> String {
|
|
String(Int64.random(in: 1_000_000..<16_000_000))
|
|
}
|
|
|
|
// Random long in [0, 2^40)
|
|
static func randomXxid() -> String {
|
|
String(Int64.random(in: 0..<(1 << 40)))
|
|
}
|
|
|
|
// Generates persistent App ID in IOS format: "IOS17.2-{15 alphanumeric chars}"
|
|
static func generateAppId() -> String {
|
|
let chars = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
|
|
let random = (0..<15).map { _ in chars.randomElement()! }
|
|
return "IOS17.2-\(String(random))"
|
|
}
|
|
|
|
// Random alphanumeric string of given length
|
|
static func randomAlpha(_ length: Int) -> String {
|
|
let chars = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
|
|
return String((0..<length).map { _ in chars.randomElement()! })
|
|
}
|
|
}
|