SPB Git

spb/os-vault Public

Self-custody, multi-chain crypto wallet for macOS. One recovery phrase, six chain families, zero API keys — nothing leaves your Mac.

Swift 96% Shell 3.4% Makefile 0.6%
11.2 KB · 364 lines swift
Raw Blame History
1public typealias Int1X = FixedWidthInteger & BinaryInteger & SignedInteger & Codable23public struct Int2X<Word: UInt1X>: Hashable, Codable {4    public typealias IntegerLiteralType = UInt645    public typealias Magnitude = UInt2X<Word>6    public typealias Words = [Word.Words.Element]7    public typealias Stride = Int8    public var rawValue: Magnitude = 09    public init(rawValue: Magnitude) { self.rawValue = rawValue }10    public init(_ source: Int2X) { rawValue = source.rawValue }11    public init() {}12}1314// Swift bug?15// auto-generated == fatalError()'s16// UInt2X(hi:nonzero, lo:0) == 017public extension Int2X {18    static func == (_ lhs: Int2X, _ rhs: Int2X) -> Bool {19        lhs.rawValue == rhs.rawValue20    }21}2223extension Int2X: ExpressibleByIntegerLiteral {24    public static var isSigned: Bool { true }25    public static var bitWidth: Int { Magnitude.bitWidth }26    public static var max: Int2X { Int2X(rawValue: Magnitude.max >> 1) }27    public static var min: Int2X { Int2X(rawValue: (Magnitude.max >> 1) &+ 1) }28    public init?<T>(exactly source: T) where T: BinaryInteger {29        guard source.bitWidth <= Int2X.bitWidth || source.magnitude <= T(Int2X.max.rawValue) else {30            return nil31        }32        if !T.isSigned, source & (1 << (source.bitWidth - 1)) != 0 {33            return nil34        }35        self.init(source)36    }3738    public init<T>(_ source: T) where T: BinaryInteger {39        if !T.isSigned, Word.bitWidth * 2 <= source.bitWidth, source & (1 << (source.bitWidth - 1)) != 0 {40            fatalError("Not enough bits to represent a signed value")41        }42        rawValue = Magnitude(source.magnitude)43        if T.isSigned, source & (1 << (source.bitWidth - 1)) != 0 {44            rawValue = -rawValue45        }46    }4748    public init?<T>(exactly source: T) where T: BinaryFloatingPoint {49        guard let rv = Magnitude(exactly: source.sign == .minus ? -source : +source) else { return nil }50        self = Int2X(rawValue: rv)51        guard !isNegative else { return nil }52        if source.sign == .minus { self = -self }53    }5455    public init<T>(_ source: T) where T: BinaryFloatingPoint {56        guard let result = Int2X(exactly: source) else {57            fatalError("Not enough bits to represent a signed value")58        }59        self = result60    }6162    // alway succeeds63    public init<T: BinaryInteger>(truncatingIfNeeded source: T) {64        rawValue = Magnitude(truncatingIfNeeded: source.magnitude)65        if T.isSigned, source < 0 {66            rawValue = -rawValue67        }68    }6970    // alway succeeds71    public init<T: BinaryInteger>(clamping source: T) {72        self = Int2X(exactly: source) ?? Int2X.max73    }7475    public init(integerLiteral value: IntegerLiteralType) {76        self.init(value)77    }78}7980extension Int2X: Comparable {81    internal var isNegative: Bool {82        Int2X.max.rawValue < rawValue83    }8485    public var magnitude: Magnitude {86        isNegative ? rawValue == Int2X.min.rawValue ? rawValue : -rawValue : +rawValue87    }8889    public static func < (lhs: Int2X, rhs: Int2X) -> Bool {90        Int2X.max.rawValue < lhs.rawValue &- rhs.rawValue91    }92}9394extension Int2X: Numeric {95    // unary operators96    public static prefix func ~ (_ value: Int2X) -> Int2X {97        Int2X(rawValue: ~(value.rawValue))98    }99100    public static prefix func + (_ value: Int2X) -> Int2X {101        value102    }103104    public static prefix func - (_ value: Int2X) -> Int2X {105        Int2X(rawValue: -(value.rawValue))106    }107108    // additions109    public func addingReportingOverflow(_ other: Int2X) -> (partialValue: Int2X, overflow: Bool) {110        let (pv, of) = rawValue.addingReportingOverflow(other.rawValue)111        // For any given int the only possible case that overflows is I.min - I.min112        // in which case overflow is true and partialValue is 0113        return (Int2X(rawValue: pv), of && pv == 0)114    }115116    public static func &+ (_ lhs: Int2X, _ rhs: Int2X) -> Int2X {117        lhs.addingReportingOverflow(rhs).partialValue118    }119120    public static func + (_ lhs: Int2X, _ rhs: Int2X) -> Int2X {121        let (pv, of) = lhs.addingReportingOverflow(rhs)122        precondition(!of, "\(lhs) + \(rhs): Addition overflow!")123        return pv124    }125126    public static func += (lhs: inout Int2X, rhs: Int2X) {127        lhs = lhs + rhs128    }129130    // subtraction131    public func subtractingReportingOverflow(_ other: Int2X) -> (partialValue: Int2X, overflow: Bool) {132        let (pv, of) = rawValue.subtractingReportingOverflow(other.rawValue)133        return (Int2X(rawValue: pv), of && pv == 0)134    }135136    public static func &- (_ lhs: Int2X, _ rhs: Int2X) -> Int2X {137        lhs.subtractingReportingOverflow(rhs).partialValue138    }139140    public static func - (_ lhs: Int2X, _ rhs: Int2X) -> Int2X {141        let (pv, of) = lhs.subtractingReportingOverflow(rhs)142        precondition(!of, "\(lhs) - \(rhs): Subtruction overflow!")143        return pv144    }145146    public static func -= (lhs: inout Int2X, rhs: Int2X) {147        lhs = lhs - rhs148    }149150    // multiplication151    public func multipliedFullWidth(by other: Int2X) -> (high: Int2X, low: Magnitude) {152        let (h, l) = rawValue.multipliedFullWidth(by: other.rawValue)153        return (Int2X(h), l)154    }155156    public func multipliedReportingOverflow(by other: Int2X) -> (partialValue: Int2X, overflow: Bool) {157        let hv = magnitude.multipliedFullWidth(by: other.magnitude)158        return (isNegative != other.isNegative ? -Int2X(rawValue: hv.low) : +Int2X(rawValue: hv.low), hv.high > 0)159    }160161    public static func &* (lhs: Int2X, rhs: Int2X) -> Int2X {162        lhs.multipliedReportingOverflow(by: rhs).partialValue163    }164165    public static func * (lhs: Int2X, rhs: Int2X) -> Int2X {166        let result = lhs.multipliedReportingOverflow(by: rhs)167        precondition(!result.overflow, "Multiplication overflow!")168        return result.partialValue169    }170171    public static func *= (lhs: inout Int2X, rhs: Int2X) {172        lhs = lhs * rhs173    }174}175176// bitshifts177public extension Int2X {178    static func &>> (_ lhs: Int2X, _ rhs: Int2X) -> Int2X {179        if rhs.isNegative { return lhs &<< -rhs }180        if Int2X.bitWidth <= rhs { return 0 }181        let rv = lhs.magnitude &>> rhs.magnitude182        return lhs.isNegative ? -Int2X(rawValue: rv) : +Int2X(rawValue: rv)183    }184185    static func &<< (_ lhs: Int2X, _ rhs: Int2X) -> Int2X {186        if rhs.isNegative { return lhs &>> -rhs }187        if Int2X.bitWidth <= rhs { return 0 }188        let rv = lhs.magnitude &<< rhs.magnitude189        return lhs.isNegative ? -Int2X(rawValue: rv) : +Int2X(rawValue: rv)190    }191192    static func &>>= (_ lhs: inout Int2X, _ rhs: Int2X) {193        return lhs = lhs &>> rhs194    }195196    static func &<<= (_ lhs: inout Int2X, _ rhs: Int2X) {197        return lhs = lhs &<< rhs198    }199}200201// division202public extension Int2X {203    func quotientAndRemainder(dividingBy other: Int2X) -> (quotient: Int2X, remainder: Int2X) {204        let qv = magnitude.quotientAndRemainder(dividingBy: other.magnitude)205        let q = isNegative != other.isNegative ? -qv.quotient : +qv.quotient206        let r = isNegative ? -qv.remainder : +qv.remainder207        return (Int2X(rawValue: q), Int2X(rawValue: r))208    }209210    static func / (_ lhs: Int2X, rhs: Int2X) -> Int2X {211        lhs.quotientAndRemainder(dividingBy: rhs).quotient212    }213214    static func /= (_ lhs: inout Int2X, rhs: Int2X) {215        lhs = lhs / rhs216    }217218    static func % (_ lhs: Int2X, rhs: Int2X) -> Int2X {219        lhs.quotientAndRemainder(dividingBy: rhs).remainder220    }221222    static func %= (_ lhs: inout Int2X, rhs: Int2X) {223        lhs = lhs % rhs224    }225226    func dividedReportingOverflow(by other: Int2X) -> (partialValue: Int2X, overflow: Bool) {227        return (self / other, false)228    }229230    func remainderReportingOverflow(dividingBy other: Int2X) -> (partialValue: Int2X, overflow: Bool) {231        return (self % other, false)232    }233234    func dividingFullWidth(_ dividend: (high: Int2X, low: Magnitude)) -> (quotient: Int2X, remainder: Int2X) {235        let qv = magnitude.dividingFullWidth((high: dividend.high.magnitude, low: dividend.low))236        let q = isNegative != dividend.high.isNegative ? -qv.quotient : +qv.quotient237        let r = isNegative ? -qv.remainder : +qv.remainder238        return (Int2X(rawValue: q), Int2X(rawValue: r))239    }240}241242// UInt2X -> String243extension Int2X: CustomStringConvertible, CustomDebugStringConvertible {244    public func toString(radix: Int = 10, uppercase: Bool = false) -> String {245        (isNegative ? "-" : "") + magnitude.toString(radix: radix, uppercase: uppercase)246    }247248    public var description: String {249        toString()250    }251252    public var debugDescription: String {253        (isNegative ? "-" : "+") + "0x" + magnitude.toString(radix: 16)254    }255}256257public extension StringProtocol {258    init?<Word>(_ source: Int2X<Word>, radix: Int = 10, uppercase: Bool = false) {259        self.init(source.toString(radix: radix, uppercase: uppercase))260    }261}262263// String <- UInt2X264extension Int2X: ExpressibleByStringLiteral {265    public init(stringLiteral value: StringLiteralType) {266        self.init()267        if let result = Int2X.fromString(value) {268            self = result269        }270    }271272    internal static func fromString(_ value: String) -> Int2X? {273        var source = value274        var sign = "+"275        if source.first == "-" || source.first == "+" {276            sign = String(source.first!)277            source.removeFirst()278        }279        guard let magnitude = Magnitude.fromString(source) else { return nil }280        return sign == "-" ? -Int2X(rawValue: magnitude) : +Int2X(rawValue: magnitude)281    }282}283284// Int -> Int2X285public extension Int {286    init<Word>(_ source: Int2X<Word>) {287        let a = Int(bitPattern: UInt(source.magnitude))288        self.init(source.isNegative ? -a : +a)289    }290}291292// Strideable293extension Int2X: Strideable {294    public func distance(to other: Int2X) -> Int {295        Int(other) - Int(self)296    }297298    public func advanced(by n: Int) -> Int2X {299        self + Int2X(n)300    }301}302303// BinaryInteger304extension Int2X: BinaryInteger {305    public var bitWidth: Int {306        rawValue.bitWidth307    }308309    public var words: Words {310        rawValue.words311    }312313    public var trailingZeroBitCount: Int {314        rawValue.trailingZeroBitCount315    }316317    public static func &= (lhs: inout Int2X, rhs: Int2X) {318        lhs.rawValue &= rhs.rawValue319    }320321    public static func |= (lhs: inout Int2X, rhs: Int2X) {322        lhs.rawValue |= rhs.rawValue323    }324325    public static func ^= (lhs: inout Int2X, rhs: Int2X) {326        lhs.rawValue ^= rhs.rawValue327    }328329    public static func <<= <RHS>(lhs: inout Int2X, rhs: RHS) where RHS: BinaryInteger {330        lhs.rawValue <<= rhs331    }332333    public static func >>= <RHS>(lhs: inout Int2X, rhs: RHS) where RHS: BinaryInteger {334        lhs.rawValue >>= rhs335    }336}337338// FixedWidthInteger339extension Int2X: FixedWidthInteger {340    public init(_truncatingBits _: UInt) {341        fatalError()342    }343344    public var nonzeroBitCount: Int {345        rawValue.nonzeroBitCount346    }347348    public var leadingZeroBitCount: Int {349        rawValue.leadingZeroBitCount350    }351352    public var byteSwapped: Int2X {353        Int2X(rawValue: rawValue.byteSwapped)354    }355}356357// SignedInteger358extension Int2X: SignedInteger {}359360public typealias Int128 = Int2X<UInt64>361public typealias Int256 = Int2X<UInt128>362public typealias Int512 = Int2X<UInt256>363public typealias Int1024 = Int2X<UInt512>364