montana/Монтана-iOS/Sources/MontanaApp/Identity/Wordlist.swift

45 lines
1.8 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Foundation
import CryptoKit
/// spec, раздел "Мнемоника и seed Каноническая wordlist".
/// 2048 lowercase ASCII слов, sorted lexicographically.
/// Binding fingerprint: SHA-256(canonical_bytes) =
/// 2f5eed53a4727b4bf8880d8f3f199efc90e58503646d9ff8eff3a2ed3b24dbda
enum Wordlist {
static let canonical: [String] = {
guard let url = Bundle.main.url(forResource: "wordlist", withExtension: "txt"),
let raw = try? String(contentsOf: url, encoding: .ascii)
else {
fatalError("Resources/wordlist.txt отсутствует или повреждён")
}
let words = raw.split(separator: "\n").map { String($0) }
precondition(words.count == 2048, "wordlist должен содержать ровно 2048 слов, получено \(words.count)")
return words
}()
/// Binary search index слова в canonical wordlist.
static func index(of word: String) -> UInt16? {
var lo = 0
var hi = canonical.count
while lo < hi {
let mid = (lo + hi) / 2
if canonical[mid] < word {
lo = mid + 1
} else if canonical[mid] > word {
hi = mid
} else {
return UInt16(mid)
}
}
return nil
}
/// Verify binding fingerprint при старте приложения (spec обязательное правило).
static func verifyBindingFingerprint() -> Bool {
let canonicalBytes = canonical.map { $0 + "\n" }.joined().data(using: .ascii)!
let hash = SHA256.hash(data: canonicalBytes)
let hex = hash.map { String(format: "%02x", $0) }.joined()
return hex == "2f5eed53a4727b4bf8880d8f3f199efc90e58503646d9ff8eff3a2ed3b24dbda"
}
}