diff --git a/FlipcashCore/Package.swift b/FlipcashCore/Package.swift index 28dbab872..fa590d46c 100644 --- a/FlipcashCore/Package.swift +++ b/FlipcashCore/Package.swift @@ -7,6 +7,7 @@ let package = Package( name: "FlipcashCore", platforms: [ .iOS(.v18), + .macOS(.v15), ], products: [ .library( diff --git a/FlipcashCore/Sources/FlipcashCore/Solana/Keys/Derive.swift b/FlipcashCore/Sources/FlipcashCore/Solana/Keys/Derive.swift index 9a96c019d..cc964f11c 100644 --- a/FlipcashCore/Sources/FlipcashCore/Solana/Keys/Derive.swift +++ b/FlipcashCore/Sources/FlipcashCore/Solana/Keys/Derive.swift @@ -7,85 +7,19 @@ // import Foundation +import SharedCoreKit -public typealias KeyDescriptor = (key: Data, chain: Data) - -/// Deterministic wallet generation for ED25519 curve using SLIP-0010 spec -/// Reference: https://github.com/satoshilabs/slips/blob/master/slip-0010.md -/// public enum Derive { - - private static let curve: Data = Data("ed25519 seed".utf8) - private static let hardenedOffset: UInt32 = 0x80000000 - - static func masterKey(seed: Data) -> KeyDescriptor { - seed.hmac(using: curve).split32() - } - - static func path(path: Path, seed: Data) -> (keyPair: KeyPair, chaincode: Data) { - var descriptor = masterKey(seed: seed) - - path.indexes.forEach { index in - descriptor = CKDPriv(keyDescriptor: descriptor, index: hardenedOffset + index.value) - } - - return ( - KeyPair(seed: try! Seed32(descriptor.key)), - descriptor.chain - ) - } - - private static func CKDPriv(keyDescriptor: KeyDescriptor, index: UInt32) -> KeyDescriptor { - var entropy = Data() - entropy.append(0x00) - entropy.append(keyDescriptor.key) - entropy.append(contentsOf: index.bigEndian.bytes) - - return entropy.hmac(using: keyDescriptor.chain).split32() - } -} + private static let hardenedOffset: Int64 = 0x8000_0000 -/// Deterministic key derivation using BIP39 -/// Reference: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki -/// -extension Derive { - static func seedUsingBIP39(phrase: [String], password: String = "") -> Key64 { - let phrase = phrase.joined(separator: " ") - let salt = "mnemonic\(password)" - - let bytes = PBKDF.deriveKey( - algorithm: .sha512, - password: phrase, - salt: salt - ) - - return try! Key64(bytes) + try! Key64(SharedDerivation.seed(mnemonic: phrase, passphrase: password)) } - - public static func keyPairUsingBIP39(path: Path, phrase: [String], password: String = "") -> KeyPair { - let key64 = seedUsingBIP39( - phrase: phrase, - password: password - ) - - return Derive.path(path: path, seed: key64.data).keyPair - } -} - -// MARK: - Data - -private extension Data { - - func split32() -> (Data, Data) { - let lhs = Data(self[0..<32]) - let rhs = Data(self[32..<64]) - return (lhs, rhs) - } - - func hmac(using key: Data) -> Data { - var hmac = HMAC(algorithm: .sha512, key: key) - hmac.update(self) - return hmac.digestData() + public static func keyPairUsingBIP39(path: Path, phrase: [String], password: String = "") -> KeyPair { + let seed = seedUsingBIP39(phrase: phrase, password: password) + let hardenedIndexes = path.indexes.map { hardenedOffset + Int64($0.value) } + let derivedKey = SharedDerivation.derivedKey(seed: seed.data, hardenedIndexes: hardenedIndexes) + return KeyPair(seed: try! Seed32(derivedKey)) } } diff --git a/FlipcashCoreVectors/Package.swift b/FlipcashCoreVectors/Package.swift index ef2796b8d..8026c97f5 100644 --- a/FlipcashCoreVectors/Package.swift +++ b/FlipcashCoreVectors/Package.swift @@ -13,7 +13,7 @@ import PackageDescription let package = Package( name: "FlipcashCoreVectors", platforms: [ - .macOS("14.0"), // FlipcashCore's transitive deps (BigDecimal 13.3, grpc/nio) need >= 13.3 + .macOS("15.0"), // FlipcashCore's transitive deps (BigDecimal 13.3, grpc/nio) need >= 13.3 .iOS("18.0"), ], dependencies: [