Full Code of essentiaone/HDWallet for AI

develop c1c5beb470d5 cached
184 files
715.4 KB
266.3k tokens
1 requests
Download .txt
Showing preview only (836K chars total). Download the full file or copy to clipboard to get everything.
Repository: essentiaone/HDWallet
Branch: develop
Commit: c1c5beb470d5
Files: 184
Total size: 715.4 KB

Directory structure:
gitextract_m1rg5mwu/

├── .codecov.yml
├── .gitignore
├── .swiftlint.yml
├── .travis.yml
├── Cartfile
├── HDWalletKit/
│   ├── Core/
│   │   ├── BigInt/
│   │   │   ├── BigInt+Extension.swift
│   │   │   ├── BigNumber.swift
│   │   │   └── SMP.swift
│   │   ├── BitcoinScript/
│   │   │   ├── OP_CODE/
│   │   │   │   ├── Arithmetic/
│   │   │   │   │   ├── OP_0NOTEQUAL.swift
│   │   │   │   │   ├── OP_1ADD.swift
│   │   │   │   │   ├── OP_1SUB.swift
│   │   │   │   │   ├── OP_2DIV.swift
│   │   │   │   │   ├── OP_2MUL.swift
│   │   │   │   │   ├── OP_ABS.swift
│   │   │   │   │   ├── OP_ADD.swift
│   │   │   │   │   ├── OP_BOOLAND.swift
│   │   │   │   │   ├── OP_BOOLOR.swift
│   │   │   │   │   ├── OP_DIV.swift
│   │   │   │   │   ├── OP_GREATERTHAN.swift
│   │   │   │   │   ├── OP_GREATERTHANOREQUAL.swift
│   │   │   │   │   ├── OP_LESSTHAN.swift
│   │   │   │   │   ├── OP_LESSTHANOREQUAL.swift
│   │   │   │   │   ├── OP_LSHIFT.swift
│   │   │   │   │   ├── OP_MAX.swift
│   │   │   │   │   ├── OP_MIN.swift
│   │   │   │   │   ├── OP_MOD.swift
│   │   │   │   │   ├── OP_MUL.swift
│   │   │   │   │   ├── OP_NEGATE.swift
│   │   │   │   │   ├── OP_NOT.swift
│   │   │   │   │   ├── OP_NUMEQUAL.swift
│   │   │   │   │   ├── OP_NUMEQUALVERIFY.swift
│   │   │   │   │   ├── OP_NUMNOTEQUAL.swift
│   │   │   │   │   ├── OP_RSHIFT.swift
│   │   │   │   │   ├── OP_SUB.swift
│   │   │   │   │   └── OP_WITHIN.swift
│   │   │   │   ├── Bitwise Logic/
│   │   │   │   │   ├── OP_AND.swift
│   │   │   │   │   ├── OP_EQUAL.swift
│   │   │   │   │   ├── OP_EQUALVERIFY.swift
│   │   │   │   │   ├── OP_INVERT.swift
│   │   │   │   │   ├── OP_OR.swift
│   │   │   │   │   ├── OP_RESERVED1.swift
│   │   │   │   │   ├── OP_RESERVED2.swift
│   │   │   │   │   └── OP_XOR.swift
│   │   │   │   ├── Crypto/
│   │   │   │   │   ├── OP_CHECKMULTISIG.swift
│   │   │   │   │   ├── OP_CHECKMULTISIGVERIFY.swift
│   │   │   │   │   ├── OP_CHECKSIG.swift
│   │   │   │   │   ├── OP_CHECKSIGVERIFY.swift
│   │   │   │   │   ├── OP_CODESEPARATOR.swift
│   │   │   │   │   ├── OP_HASH160.swift
│   │   │   │   │   ├── OP_HASH256.swift
│   │   │   │   │   ├── OP_RIPEMD160.swift
│   │   │   │   │   ├── OP_SHA1.swift
│   │   │   │   │   └── OP_SHA256.swift
│   │   │   │   ├── Flow Control/
│   │   │   │   │   ├── OP_ELSE.swift
│   │   │   │   │   ├── OP_ENDIF.swift
│   │   │   │   │   ├── OP_IF.swift
│   │   │   │   │   ├── OP_NOP.swift
│   │   │   │   │   ├── OP_NOTIF.swift
│   │   │   │   │   ├── OP_RETURN.swift
│   │   │   │   │   ├── OP_VER.swift
│   │   │   │   │   ├── OP_VERIF.swift
│   │   │   │   │   ├── OP_VERIFY.swift
│   │   │   │   │   └── OP_VERNOTIF.swift
│   │   │   │   ├── Lock Time/
│   │   │   │   │   ├── OP_CHECKLOCKTIMEVERIFY.swift
│   │   │   │   │   └── OP_CHECKSEQUENCEVERIFY.swift
│   │   │   │   ├── OP_EXAMPLE.swift
│   │   │   │   ├── Pseudo Words/
│   │   │   │   │   ├── OP_INVALIDOPCODE.swift
│   │   │   │   │   ├── OP_PUBKEY.swift
│   │   │   │   │   └── OP_PUBKEYHASH.swift
│   │   │   │   ├── Push Data/
│   │   │   │   │   ├── OP_0.swift
│   │   │   │   │   ├── OP_1NEGATE.swift
│   │   │   │   │   ├── OP_N.swift
│   │   │   │   │   ├── OP_PUSHDATA.swift
│   │   │   │   │   └── OP_RESERVED.swift
│   │   │   │   ├── Reserved Words/
│   │   │   │   │   └── OP_NOPN.swift
│   │   │   │   ├── Splice/
│   │   │   │   │   ├── OP_BIN2NUM.swift
│   │   │   │   │   ├── OP_CAT.swift
│   │   │   │   │   ├── OP_NUM2BIN.swift
│   │   │   │   │   ├── OP_SIZE.swift
│   │   │   │   │   └── OP_SPLIT.swift
│   │   │   │   └── Stack/
│   │   │   │       ├── OP_2DROP.swift
│   │   │   │       ├── OP_2DUP.swift
│   │   │   │       ├── OP_2OVER.swift
│   │   │   │       ├── OP_2ROT.swift
│   │   │   │       ├── OP_2SWAP.swift
│   │   │   │       ├── OP_3DUP.swift
│   │   │   │       ├── OP_DEPTH.swift
│   │   │   │       ├── OP_DROP.swift
│   │   │   │       ├── OP_DUP.swift
│   │   │   │       ├── OP_FROMALTSTACK.swift
│   │   │   │       ├── OP_IFDUP.swift
│   │   │   │       ├── OP_NIP.swift
│   │   │   │       ├── OP_OVER.swift
│   │   │   │       ├── OP_PICK.swift
│   │   │   │       ├── OP_ROLL.swift
│   │   │   │       ├── OP_ROT.swift
│   │   │   │       ├── OP_SWAP.swift
│   │   │   │       ├── OP_TOTALSTACK.swift
│   │   │   │       └── OP_TUCK.swift
│   │   │   ├── OpCodeFactory.swift
│   │   │   ├── OpCodeProtocol.swift
│   │   │   ├── Opcode.swift
│   │   │   ├── Script.swift
│   │   │   ├── ScriptChunk.swift
│   │   │   ├── ScriptChunkHelper.swift
│   │   │   ├── ScriptExecutionContext.swift
│   │   │   ├── ScriptFactory.swift
│   │   │   └── ScriptMachine.swift
│   │   ├── ByteStream.swift
│   │   ├── Converter/
│   │   │   └── WeiEthterConverter.swift
│   │   ├── Crypto/
│   │   │   ├── Encryption/
│   │   │   │   ├── Crypto.swift
│   │   │   │   ├── ECDSA.swift
│   │   │   │   ├── EIP155Signer.swift
│   │   │   │   ├── EllipticCurveEncrypterSecp256k1.swift
│   │   │   │   └── SecpResult.swift
│   │   │   └── Hash/
│   │   │       └── RIPEMD160.swift
│   │   ├── DataConvertable.swift
│   │   ├── DerivationNode.swift
│   │   ├── Encodeing/
│   │   │   ├── Base58Encode.swift
│   │   │   ├── Bech32.swift
│   │   │   ├── EIP55.swift
│   │   │   └── RLP.swift
│   │   ├── Error/
│   │   │   └── HDWalletKitError.swift
│   │   ├── Extensions/
│   │   │   ├── Data+Random.swift
│   │   │   ├── Data+Script.swift
│   │   │   └── String+Hex.swift
│   │   ├── Typealiaces.swift
│   │   ├── VarInt.swift
│   │   └── VarString.swift
│   ├── Keystore/
│   │   ├── KeystoreInterface.swift
│   │   ├── KeystoreV3.swift
│   │   └── KeystoreV3Json.swift
│   ├── Mnemonic/
│   │   ├── Mnemonic.swift
│   │   └── WordList.swift
│   ├── Models/
│   │   └── Account.swift
│   └── Wallet/
│       ├── AccountBased/
│       │   ├── ERC20/
│       │   │   └── ERC20.swift
│       │   └── Ethereum/
│       │       └── Model/
│       │           ├── EthereumAddress.swift
│       │           └── EthereumRawTransaction.swift
│       ├── Coin.swift
│       ├── PrivateKey.swift
│       ├── PublicKey.swift
│       ├── UTXOBased/
│       │   ├── Bitcoin/
│       │   │   ├── BitcoinAddress.swift
│       │   │   ├── BitcoinTransactionSignatureSerializer.swift
│       │   │   └── Transaction+SignatureHash.swift
│       │   ├── BitcoinCash/
│       │   │   ├── BitcoinCashAddress.swift
│       │   │   └── BitcoinCashVersionByte.swift
│       │   ├── Constants/
│       │   │   ├── SighashType.swift
│       │   │   └── UtilsAndLimits.swift
│       │   ├── Default/
│       │   │   ├── UtxoSelector.swift
│       │   │   ├── UtxoTransactionBuilder.swift
│       │   │   └── UtxoTransactionSigner.swift
│       │   ├── Model/
│       │   │   ├── TransactionInput.swift
│       │   │   ├── UnsignedTransaction.swift
│       │   │   └── UnspendTransaction/
│       │   │       ├── TransactionOutPoint.swift
│       │   │       ├── TransactionOutput.swift
│       │   │       └── UnspendTransaction.swift
│       │   ├── Protocols/
│       │   │   ├── UtxoSelectorInterface.swift
│       │   │   ├── UtxoTransactionBuilderInterface.swift
│       │   │   └── UtxoTransactionSignerInterface.swift
│       │   ├── Transaction.swift
│       │   ├── UTXOWallet.swift
│       │   └── UtxoPrivateKeyType.swift
│       └── Wallet.swift
├── HDWalletKit.podspec
├── HDWalletKit.xcodeproj/
│   ├── project.pbxproj
│   └── xcshareddata/
│       └── xcschemes/
│           ├── HDWalletKit.xcscheme
│           └── HDWalletKit_Tests.xcscheme
├── HDWalletKit_Tests/
│   ├── AddressGenerationTests.swift
│   ├── ConverterTests.swift
│   ├── CryptoTests.swift
│   ├── ERC20Tests.swift
│   ├── ImportWalletTests.swift
│   ├── Info.plist
│   ├── KeystoreTests.swift
│   ├── MnemonicTests.swift
│   ├── PrivateKeyTests.swift
│   ├── RIPEMD160Tests.swift
│   ├── Secp256k1Tets.swift
│   ├── SignTransactionTests.swift
│   └── UTXO/
│       └── UTXOSign.swift
├── LICENSE.md
├── Podfile
├── README.md
└── scripts/
    └── coverage.rb

================================================
FILE CONTENTS
================================================

================================================
FILE: .codecov.yml
================================================
ignore:
  - "**/WordList.swift"


================================================
FILE: .gitignore
================================================
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## Build generated
build/
DerivedData/

## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/

## Other
*.moved-aside
*.xccheckout
*.xcscmblueprint

## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM

## Playgrounds
timeline.xctimeline
playground.xcworkspace

# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
.build/

# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
Pods/
Podfile.lock
*.xcworkspace

# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build

# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control

fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output


================================================
FILE: .swiftlint.yml
================================================
disabled_rules:
 - trailing_whitespace
excluded: 
  - Carthage
  - Pods

================================================
FILE: .travis.yml
================================================
language: 
  - objective-c
osx_image: 
  - xcode10.2.1
before_install:
   - gem update cocoapods --pre
   - pod update
install:
- gem install xcpretty-travis-formatter
script:
  - xcodebuild test -workspace 'HDWalletKit.xcworkspace' -scheme 'HDWalletKit_Tests' -destination 'platform=iOS Simulator,name=iPhone 7,OS=12.1' | xcpretty -f `xcpretty-travis-formatter`
after_success:
 - bash <(curl -s https://copilot.blackducksoftware.com/ci/travis/scripts/upload)
 - ruby scripts/coverage.rb "$SCHEME"
 - bash <(curl -s https://codecov.io/bash) -f 'coverage.txt' -y '.codecov.yml'

================================================
FILE: Cartfile
================================================
github "Boilertalk/secp256k1.swift"
github "krzyzanowskim/CryptoSwift"


================================================
FILE: HDWalletKit/Core/BigInt/BigInt+Extension.swift
================================================
//
//  BigInt+Extension.swift
//  WalletKit
//
//  Created by yuzushioh on 2018/01/24.
//  Copyright © 2018 yuzushioh. All rights reserved.
//

import Foundation

extension BInt {
    internal init?(str: String, radix: Int) {
        self.init(0)
        let bint16 = BInt(16)
        
        var exp = BInt(1)
        
        str.reversed().forEach {
            guard let int = Int(String($0), radix: radix) else {
                return
            }
            let value = BInt(int)
            self += (value * exp)
            exp *= bint16
        }
    }
}

extension BInt: Codable {
    private enum CodingKeys: String, CodingKey {
        case bigInt
    }
    
    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let string = try container.decode(String.self, forKey: .bigInt)
        self = Wei(number: string, withBase: 10)!
    }
    
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(asString(withBase: 10), forKey: .bigInt)
    }
}


extension BInt {
    var data: Data {
        let count = limbs.count
        var data = Data(count: count * 8)
        data.withUnsafeMutableBytes { (pointer) -> Void in
            guard var p = pointer.bindMemory(to: UInt8.self).baseAddress else { return }
            for i in (0..<count).reversed() {
                for j in (0..<8).reversed() {
                    p.pointee = UInt8((limbs[i] >> UInt64(j * 8)) & 0xff)
                    p += 1
                }
            }
        }
        
        return data
    }
    
    init?(hex: String) {
        self.init(number: hex.lowercased(), withBase: 16)
    }
    
    init(data: Data) {
        let n = data.count
        guard n > 0 else {
            self.init(0)
            return
        }
        
        let m = (n + 7) / 8
        var limbs = Limbs(repeating: 0, count: m)
        data.withUnsafeBytes { (ptr) -> Void in
            guard var p = ptr.baseAddress?.assumingMemoryBound(to: UInt8.self) else { return }
            let r = n % 8
            let k = r == 0 ? 8 : r
            for j in (0..<k).reversed() {
                limbs[m - 1] += UInt64(p.pointee) << UInt64(j * 8)
                p += 1
            }
            guard m > 1 else { return }
            for i in (0..<(m - 1)).reversed() {
                for j in (0..<8).reversed() {
                    limbs[i] += UInt64(p.pointee) << UInt64(j * 8)
                    p += 1
                }
            }
        }
        
        self.init(limbs: limbs)
    }
}


================================================
FILE: HDWalletKit/Core/BigInt/BigNumber.swift
================================================
//
//  BigNumber.swift
//  HDWalletKit
//
//  Created by Pavlo Boiko on 1/6/19.
//  Copyright © 2019 Essentia. All rights reserved.
//

import Foundation

public struct BigNumber {
    public var int32: Int32
    public var data: Data
    
    public static let zero: BigNumber = BigNumber()
    public static let one: BigNumber = BigNumber(1)
    public static let negativeOne: BigNumber = BigNumber(1)
    
    public init() {
        self.init(0)
    }
    
    public init(_ int32: Int32) {
        self.int32 = int32
        self.data = int32.toBigNum()
    }
    
    public init(int32: Int32) {
        self.int32 = int32
        self.data = int32.toBigNum()
    }
    
    public init(_ data: Data) {
        self.data = data
        self.int32 = data.toInt32()
    }
}

extension BigNumber: Comparable {
    public static func == (lhs: BigNumber, rhs: BigNumber) -> Bool {
        return lhs.int32 == rhs.int32
    }
    
    public static func < (lhs: BigNumber, rhs: BigNumber) -> Bool {
        return lhs.int32 < rhs.int32
    }
}

private extension Int32 {
    func toBigNum() -> Data {
        let isNegative: Bool = self < 0
        var value: UInt32 = isNegative ? UInt32(-self) : UInt32(self)
        
        var data = Data(bytes: &value, count: MemoryLayout.size(ofValue: value))
        while data.last == 0 {
            data.removeLast()
        }
        
        var bytes: [UInt8] = []
        for d in data.reversed() {
            if bytes.isEmpty && d >= 0x80 {
                bytes.append(0)
            }
            bytes.append(d)
        }
        
        if isNegative {
            let first = bytes.removeFirst()
            bytes.insert(first + 0x80, at: 0)
        }
        
        let bignum = Data(bytes.reversed())
        return bignum
        
    }
}

private extension Data {
    func toInt32() -> Int32 {
        guard !self.isEmpty else {
            return 0
        }
        var data = self
        var bytes: [UInt8] = []
        var last = data.removeLast()
        let isNegative: Bool = last >= 0x80
        
        while !data.isEmpty {
            bytes.append(data.removeFirst())
        }
        
        if isNegative {
            last -= 0x80
        }
        bytes.append(last)
        
        let value: Int32 = Data(bytes).to(type: Int32.self)
        return isNegative ? -value: value
    }
}


================================================
FILE: HDWalletKit/Core/BigInt/SMP.swift
================================================
//
//    ————————————————————————————————————————————————————————————————————————————————————————————
//    ||||||||||||||||                       SMP Core.swift                       ||||||||||||||||
//    ————————————————————————————————————————————————————————————————————————————————————————————
//    Created by Marcel Kröker on 30.09.16.
//    Copyright (c) 2016 Blubyte. All rights reserved.
//
//
//
//    ——————————————————————————————————————————— v1.0 ———————————————————————————————————————————
//    - Initial Release.
//
//    ——————————————————————————————————————————— v1.1 ———————————————————————————————————————————
//    - Improved String conversion, now about 45x faster, uses base 10^9 instead
//    of base 10.
//    - bytes renamed to limbs.
//    - Uses typealias for limbs and digits.
//
//    ——————————————————————————————————————————— v1.2 ———————————————————————————————————————————
//    - Improved String conversion, now about 10x faster, switched from base 10^9
//    to 10^18 (biggest possible decimal base).
//    - Implemented karatsuba multiplication algorithm, about 5x faster than the
//    previous algorithm.
//    - Addition is 1.3x faster.
//    - Addtiton and subtraction omit trailing zeros, algorithms need less
//    operations now.
//    - Implemented exponentiation by squaring.
//    - New storage (BStorage) for often used results.
//    - Uses uint_fast64_t instead of UInt64 for Limbs and Digits.
//
//    ——————————————————————————————————————————— v1.3 ———————————————————————————————————————————
//    - Huge Perfomance increase by skipping padding zeros and new multiplication
//    algotithms.
//    - Printing is now about 10x faster, now on par with GMP.
//    - Some operations now use multiple cores.
//
//    ——————————————————————————————————————————— v1.4 ———————————————————————————————————————————
//    - Reduced copying by using more pointers.
//    - Multiplication is about 50% faster.
//    - String to BInt conversion is 2x faster.
//    - BInt to String also performs 50% better.
//
//    ——————————————————————————————————————————— v1.5 ———————————————————————————————————————————
//    - Updated for full Swift 3 compatibility.
//    - Various optimizations:
//        - Multiplication is about 2x faster.
//        - BInt to String conversion is more than 3x faster.
//        - String to BInt conversion is more than 2x faster.
//
//    ——————————————————————————————————————————— v1.6 ———————————————————————————————————————————
//    - Code refactored into modules.
//    - Renamed the project to SMP (Swift Multiple Precision).
//    - Added arbitrary base conversion.
//
//    ——————————————————————————————————————————— v2.0 ———————————————————————————————————————————
//    - Updated for full Swift 4 compatibility.
//    - Big refactor, countless optimizations for even better performance.
//    - BInt conforms to SignedNumeric and BinaryInteger, this makes it very easy to write
//      generic code.
//    - BDouble also conforms to SignedNumeric and has new functionalities.
//
//
//
//    ————————————————————————————————————————————————————————————————————————————————————————————
//    ||||||||||||||||                         Evolution                          ||||||||||||||||
//    ————————————————————————————————————————————————————————————————————————————————————————————
//
//
//
//    Planned features of BInt v3.0:
//    - Implement some basic cryptography functions.
//    - General code cleanup, better documentation.
//    - More extensive tests.
//    - Please contact me if you have any suggestions for new features!
//
//
//
//    ————————————————————————————————————————————————————————————————————————————————————————————
//    ||||||||||||||||              Basic Project syntax conventions              ||||||||||||||||
//    ————————————————————————————————————————————————————————————————————————————————————————————
//
//    Indentation: Tabs
//
//    Align: Spaces
//
//    Style: allman
//    func foo(...)
//    {
//        ...
//    }
//
//    Single line if-statement:
//    if condition { code }
//
//    Maximum line length: 96 characters
//
//    ————————————————————————————————————————————————————————————————————————————————————————————
// MARK: - Imports
//    ————————————————————————————————————————————————————————————————————————————————————————————
//    ||||||||        Imports        |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ————————————————————————————————————————————————————————————————————————————————————————————

import Foundation

// MARK: - Typealiases
//    ————————————————————————————————————————————————————————————————————————————————————————————
//    ||||||||        Typealiases        |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ————————————————————————————————————————————————————————————————————————————————————————————
//    Limbs are basically single Digits in base 2^64. Each slot in an Limbs array stores one
//    Digit of the number. The least significant digit is stored at index 0, the most significant
//    digit is stored at the last index.

public typealias Limbs  = [UInt64]
public typealias Limb = UInt64

//    A digit is a number in base 10^18. This is the biggest possible base that
//    fits into an unsigned 64 bit number while maintaining the propery that the square root of
//    the base is a whole number and a power of ten . Digits are required for printing BInt
//    numbers. Limbs are converted into Digits first, and then printed.

public typealias Digits = [UInt64]
public typealias Digit = UInt64

// MARK: - Imports
//    ————————————————————————————————————————————————————————————————————————————————————————————
//    ||||||||        Operators        |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ————————————————————————————————————————————————————————————————————————————————————————————

precedencegroup ExponentiationPrecedence {
    associativity: left
    higherThan: MultiplicationPrecedence
    lowerThan: BitwiseShiftPrecedence
}

// Exponentiation operator
infix operator ** : ExponentiationPrecedence

// MARK: - BInt
//    ————————————————————————————————————————————————————————————————————————————————————————————
//    ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ||||||||        BInt        ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ————————————————————————————————————————————————————————————————————————————————————————————
///    BInt is an arbitrary precision integer value type. It stores a number in base 2^64 notation
///    as an array. Each element of the array is called a limb, which is of type UInt64, the whole
///    array is called limbs and has the type [UInt64]. A boolean sign variable determines if the
///    number is positive or negative. If sign == true, then the number is smaller than 0,
///    otherwise it is greater or equal to 0. It stores the 64 bit digits in little endian, that
///    is, the least significant digit is stored in the array index 0:
///
///        limbs == [] := undefined, should throw an error
///        limbs == [0], sign == false := 0, defined as positive
///        limbs == [0], sign == true := undefined, should throw an error
///        limbs == [n] := n if sign == false, otherwise -n, given 0 <= n < 2^64
///
///        limbs == [l0, l1, l2, ..., ln] :=
///        (l0 * 2^(0*64)) +
///        (11 * 2^(1*64)) +
///        (12 * 2^(2*64)) +
///        ... +
///        (ln * 2^(n*64))
public struct BInt: SignedNumeric, // Implies Numeric, Equatable, ExpressibleByIntegerLiteral
    BinaryInteger, // Implies Hashable, CustomStringConvertible, Strideable, Comparable
ExpressibleByFloatLiteral {
    //
    //
    // MARK: - Internal data
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        Internal data        |||||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    internal var sign = false
    internal var limbs = Limbs()
    
    // Required by protocol Numeric
    public typealias Magnitude = UInt64
    
    // Required by protocol Numeric
    public var magnitude: UInt64 {
        return self.limbs[0]
    }
    
    public typealias Words = [UInt]
    
    /// A collection containing the words of this value’s binary representation, in order from
    ///    the least significant to most significant.
    public var words: BInt.Words {
        return self.limbs.map { UInt($0) }
    }
    
    /// Returns the size of the BInt in bits.
    public var size: Int {
        return 1 + (self.limbs.count * MemoryLayout<Limb>.size * 8)
    }
    
    //
    //
    // MARK: - Initializers
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        Initializers        ||||||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    ///    Root initializer for all other initializers. Because no sign is provided, the new
    ///    instance is positive by definition.
    internal init(limbs: Limbs) {
        precondition(limbs != [], "BInt can't be initialized with limbs == []")
        self.limbs = limbs
    }
    
    /// Create an instance initialized with a sign and a limbs array.
    internal init(sign: Bool, limbs: Limbs) {
        self.init(limbs: limbs)
        self.sign = sign
    }
    
    /// Create an instance initialized with the value 0.
    init() {
        self.init(limbs: [0])
    }
    
    /// Create an instance initialized to an integer value.
    public init(_ z: Int) {
        //    Since abs(Int.min) > Int.max, it is necessary to handle
        //    z == Int.min as a special case.
        if z == Int.min {
            self.init(sign: true, limbs: [Limb(Int.max) + 1])
            return
        } else {
            self.init(sign: z < 0, limbs: [Limb(abs(z))])
        }
    }
    
    /// Create an instance initialized to an unsigned integer value.
    public init(_ n: UInt) {
        self.init(limbs: [Limb(n)])
    }
    
    /// Create an instance initialized to a string value.
    public init?(_ str: String) {
        var str = str
        var sign = false
        var base: Limbs = [1]
        var limbs: Limbs = [0]
        
        limbs.reserveCapacity(Int(Double(str.count) / log10(pow(2.0, 64.0))))
        
        if str.hasPrefix("-") {
            str.remove(at: str.startIndex)
            sign = str != "0"
        }
        
        for chunk in String(str.reversed()).split(19).map({ String($0.reversed()) }) {
            if let num = Limb(String(chunk)) {
                limbs.addProductOf(multiplier: base, multiplicand: num)
                base = base.multiplyingBy([10_000_000_000_000_000_000])
            } else {
                return nil
            }
        }
        
        self.init(sign: sign, limbs: limbs)
    }
    
    /// Create an instance initialized to a string with the value of mathematical numerical system of the specified radix (base).
    /// So for example, to get the value of hexadecimal string radix value must be set to 16.
    public init?(_ nStr: String, radix: Int) {
        if radix == 10 {
            // regular string init is faster
            // see metrics
            self.init(nStr)
            return
        }
        
        var useString = nStr
        if radix == 16 {
            if useString.hasPrefix("0x") {
                useString = String(nStr.dropFirst(2))
            }
        }
        
        if radix == 8 {
            if useString.hasPrefix("0o") {
                useString = String(nStr.dropFirst(2))
            }
        }
        
        if radix == 2 {
            if useString.hasPrefix("0b") {
                useString = String(nStr.dropFirst(2))
            }
        }
        
        let bint16 = BInt(radix)
        
        var total = BInt(0)
        var exp = BInt(1)
        
        for c in useString.reversed() {
            let int = Int(String(c), radix: radix)
            if int != nil {
                let value = BInt(int!)
                total = total + (value * exp)
                exp = exp * bint16
            } else {
                return nil
            }
            
        }
        
        self.init(String(describing: total))
    }
    
    //    Requierd by protocol ExpressibleByFloatLiteral.
    public init(floatLiteral value: Double) {
        self.init(sign: value < 0.0, limbs: [Limb(value)])
    }
    
    //    Required by protocol ExpressibleByIntegerLiteral.
    public init(integerLiteral value: Int) {
        self.init(value)
    }
    
    // Required by protocol Numeric
    public init?<T>(exactly source: T) where T: BinaryInteger {
        self.init(Int(source))
    }
    
    ///    Creates an integer from the given floating-point value, rounding toward zero.
    public init<T>(_ source: T) where T: BinaryFloatingPoint {
        self.init(Int(source))
    }
    
    ///    Creates a new instance from the given integer.
    public init<T>(_ source: T) where T: BinaryInteger {
        self.init(Int(source))
    }
    
    ///    Creates a new instance with the representable value that’s closest to the given integer.
    public init<T>(clamping source: T) where T: BinaryInteger {
        self.init(Int(source))
    }
    
    ///    Creates an integer from the given floating-point value, if it can be represented
    ///    exactly.
    public init?<T>(exactly source: T) where T: BinaryFloatingPoint {
        self.init(source)
    }
    
    ///    Creates a new instance from the bit pattern of the given instance by sign-extending or
    ///    truncating to fit this type.
    public init<T>(truncatingIfNeeded source: T) where T: BinaryInteger {
        self.init(source)
    }
    
    //
    //
    // MARK: - CustomStringConvertible conformance
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        CustomStringConvertible conformance        |||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    public var description: String {
        return (self.sign ? "-" : "").appending(self.limbs.decimalRepresentation)
    }
    
    public init?(number: String, withBase base: Int) {
        self.init(number.convertingBase(from: base, toBase: 10))
    }
    
    public func asString(withBase base: Int) -> String {
        let str = self.limbs.decimalRepresentation
        let newStr = str.convertingBase(from: 10, toBase: base)
        
        if self.sign { return "-".appending(newStr) }
        return newStr
    }
    
    //
    //
    // MARK: - Struct functions
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        Struct functions        ||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    ///    Returns BInt value as an integer, if possible.
    func toInt() -> Int? {
        //    Conversion only works when self has only one limb thats smaller or
        //    equal to abs(Int.min).
        
        if self.limbs.count != 1 { return nil }
        
        let number = self.limbs[0]
        
        //    Self is within the range of Int
        if number <= Limb(Int.max) {
            return self.sign ? -Int(number) : Int(number)
        }
        
        //    Special case: self == Int.min
        if number == (Limb(Int.max) + 1) && self.sign {
            return Int.min
        }
        
        return nil
    }
    
    var rawValue: (sign: Bool, limbs: [UInt64]) {
        return (self.sign, self.limbs)
    }
    
    ///    A Boolean value indicating whether this type is a signed integer type.
    public static var isSigned: Bool {
        return true
    }
    
    ///    Returns -1 if this value is negative and 1 if it’s positive; otherwise, 0.
    public func signum() -> BInt {
        if self.isZero() { return BInt(0) } else if self.isPositive() { return BInt(1) } else { return BInt(-1) }
    }
    
    func isPositive() -> Bool { return !self.sign }
    func isNegative() -> Bool { return  self.sign }
    func isZero() -> Bool { return self.limbs[0] == 0 && self.limbs.count == 1 }
    func isNotZero() -> Bool { return self.limbs[0] != 0 || self.limbs.count > 1 }
    func isOdd() -> Bool { return self.limbs[0] & 1 == 1 }
    func isEven() -> Bool { return self.limbs[0] & 1 == 0 }
    
    ///    The number of bits in the current binary representation of this value.
    public var bitWidth: Int {
        return self.limbs.bitWidth
    }
    
    ///    The number of trailing zeros in this value’s binary representation.
    public var trailingZeroBitCount: Int {
        var i = 0
        while true {
            if self.limbs.getBit(at: i) { return i }
            i += 1
        }
    }
    
    /// Serialization
    public func serialize() -> Data {
        let byteCount = (bitWidth + 7) / 8
        guard byteCount > 0 else { return Data()}
        
        var data = Data(count: byteCount)
        data.withUnsafeMutableBytes { (pointer) -> Void in
            let p = pointer.bindMemory(to: UInt8.self)
            var i = byteCount - 1
            for var word in words {
                for _ in 0 ..< UInt.bitWidth / 8 {
                    p[i] = UInt8(word & 0xFF)
                    word >>= 8
                    if i == 0 {
                        assert(word == 0)
                        break
                    }
                    i -= 1
                }
            }
        }
        return data
    }
    
    //
    //
    // MARK: - BInt Shifts
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt Shifts        |||||||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    public static func <<<T: BinaryInteger>(lhs: BInt, rhs: T) -> BInt {
        if rhs < 0 { return lhs >> rhs }
        
        let limbs = lhs.limbs.shiftingUp(Int(rhs))
        let sign = lhs.isNegative() && !limbs.equalTo(0)
        
        return BInt(sign: sign, limbs: limbs)
    }
    
    public static func <<=<T: BinaryInteger>(lhs: inout BInt, rhs: T) {
        lhs.limbs.shiftUp(Int(rhs))
    }
    
    public static func >><T: BinaryInteger>(lhs: BInt, rhs: T) -> BInt {
        if rhs < 0 { return lhs << rhs }
        return BInt(sign: lhs.sign, limbs: lhs.limbs.shiftingDown(Int(rhs)))
    }
    
    public static func >>=<T: BinaryInteger>(lhs: inout BInt, rhs: T) {
        lhs.limbs.shiftDown(Int(rhs))
    }
    
    //
    //
    // MARK: - BInt Bitwise AND
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt BInt Bitwise AND        |||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    ///    Returns the result of performing a bitwise AND operation on the two given values.
    public static func &(lhs: BInt, rhs: BInt) -> BInt {
        var res: Limbs = [0]
        
        for i in 0..<(64 * Swift.max(lhs.limbs.count, rhs.limbs.count)) {
            let newBit = lhs.limbs.getBit(at: i) && lhs.limbs.getBit(at: i)
            res.setBit(at: i, to: newBit)
        }
        
        return BInt(sign: lhs.sign && rhs.sign, limbs: res)
    }
    
    //    static func &(lhs: Int, rhs: BInt) -> BInt
    //    static func &(lhs: BInt, rhs: Int) -> BInt
    
    ///    Stores the result of performing a bitwise AND operation on the two given values in the
    ///    left-hand-side variable.
    public static func &=(lhs: inout BInt, rhs: BInt) {
        let res = lhs & rhs
        lhs = res
    }
    
    //    static func &=(inout lhs: Int, rhs: BInt)
    //    static func &=(inout lhs: BInt, rhs: Int)
    
    //
    //
    // MARK: - BInt Bitwise OR
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt Bitwise OR        |||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    public static func |(lhs: BInt, rhs: BInt) -> BInt {
        var res: Limbs = [0]
        
        for i in 0..<(64 * Swift.max(lhs.limbs.count, rhs.limbs.count)) {
            let newBit = lhs.limbs.getBit(at: i) || lhs.limbs.getBit(at: i)
            res.setBit(at: i, to: newBit)
        }
        
        return BInt(sign: lhs.sign || rhs.sign, limbs: res)
    }
    
    //    static func |(lhs: Int, rhs: BInt) -> BInt
    //    static func |(lhs: BInt, rhs: Int) -> BInt
    //
    public static func |=(lhs: inout BInt, rhs: BInt) {
        let res = lhs | rhs
        lhs = res
    }
    //    static func |=(inout lhs: Int, rhs: BInt)
    //    static func |=(inout lhs: BInt, rhs: Int)
    
    //
    //
    // MARK: - BInt Bitwise OR
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt Bitwise XOR        ||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    public static func ^(lhs: BInt, rhs: BInt) -> BInt {
        var res: Limbs = [0]
        
        for i in 0..<(64 * Swift.max(lhs.limbs.count, rhs.limbs.count)) {
            let newBit = lhs.limbs.getBit(at: i) != lhs.limbs.getBit(at: i)
            res.setBit(at: i, to: newBit)
        }
        
        return BInt(sign: lhs.sign != rhs.sign, limbs: res)
    }
    
    public static func ^=(lhs: inout BInt, rhs: BInt) {
        let res = lhs | rhs
        lhs = res
    }
    
    //
    //
    // MARK: - BInt Bitwise NOT
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt Bitwise NOT        ||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    public prefix static func ~(x: BInt) -> BInt {
        var res = x.limbs
        for i in 0..<(res.bitWidth) {
            res.setBit(at: i, to: !res.getBit(at: i))
        }
        
        while res.last! == 0 && res.count > 1 { res.removeLast() }
        
        return BInt(sign: !x.sign, limbs: res)
    }
    
    //
    //
    // MARK: - BInt Addition
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt Addition        |||||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    public prefix static func +(x: BInt) -> BInt {
        return x
    }
    
    // Required by protocol Numeric
    public static func +=(lhs: inout BInt, rhs: BInt) {
        if lhs.sign == rhs.sign {
            lhs.limbs.addLimbs(rhs.limbs)
            return
        }
        
        let rhsIsMin = rhs.limbs.lessThan(lhs.limbs)
        lhs.limbs.difference(rhs.limbs)
        lhs.sign = (rhs.sign && !rhsIsMin) || (lhs.sign && rhsIsMin) // DNF minimization
        
        if lhs.isZero() { lhs.sign = false }
    }
    
    // Required by protocol Numeric
    public static func +(lhs: BInt, rhs: BInt) -> BInt {
        var lhs = lhs
        lhs += rhs
        return lhs
    }
    
    static func +(lhs: Int, rhs: BInt) -> BInt { return BInt(lhs) + rhs }
    static func +(lhs: BInt, rhs: Int) -> BInt { return lhs + BInt(rhs) }
    
    static func +=(lhs: inout  Int, rhs: BInt) { lhs += (BInt(lhs) + rhs).toInt()! }
    static func +=(lhs: inout BInt, rhs: Int) { lhs += BInt(rhs)                 }
    
    //
    //
    // MARK: - BInt Negation
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt Negation        |||||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    // Required by protocol SignedNumeric
    public mutating func negate() {
        if self.isNotZero() { self.sign = !self.sign }
    }
    
    // Required by protocol SignedNumeric
    public static prefix func -(n: BInt) -> BInt {
        var n = n
        n.negate()
        return n
    }
    
    //
    //
    // MARK: - BInt Subtraction
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt Subtraction        ||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    // Required by protocol Numeric
    public static func -(lhs: BInt, rhs: BInt) -> BInt {
        return lhs + -rhs
    }
    
    static func -(lhs: Int, rhs: BInt) -> BInt { return BInt(lhs) - rhs }
    static func -(lhs: BInt, rhs: Int) -> BInt { return lhs - BInt(rhs) }
    
    // Required by protocol Numeric
    public static func -=(lhs: inout BInt, rhs: BInt) { lhs += -rhs                        }
    static func -=(lhs: inout  Int, rhs: BInt) { lhs = (BInt(lhs) - rhs).toInt()! }
    static func -=(lhs: inout BInt, rhs: Int) { lhs -= BInt(rhs)                  }
    
    //
    //
    // MARK: - BInt Multiplication
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt Multiplication        |||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    // Required by protocol Numeric
    public static func *(lhs: BInt, rhs: BInt) -> BInt {
        let sign = !(lhs.sign == rhs.sign || lhs.isZero() || rhs.isZero())
        return BInt(sign: sign, limbs: lhs.limbs.multiplyingBy(rhs.limbs))
    }
    
    static func *(lhs: Int, rhs: BInt) -> BInt { return BInt(lhs) * rhs }
    static func *(lhs: BInt, rhs: Int) -> BInt { return lhs * BInt(rhs) }
    
    // Required by protocol SignedNumeric
    public static func *=(lhs: inout BInt, rhs: BInt) { lhs = lhs * rhs                  }
    static func *=(lhs: inout  Int, rhs: BInt) { lhs = (BInt(lhs) * rhs).toInt()! }
    static func *=(lhs: inout BInt, rhs: Int) { lhs = lhs * BInt(rhs)            }
    
    //
    //
    // MARK: - BInt Exponentiation
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt Exponentiation        |||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    static func **(lhs: BInt, rhs: Int) -> BInt {
        precondition(rhs >= 0, "BInts can't be exponentiated with exponents < 0")
        return BInt(sign: lhs.sign && (rhs % 2 != 0), limbs: lhs.limbs.exponentiating(rhs))
    }
    
    func factorial() -> BInt {
        precondition(!self.sign, "Can't calculate the factorial of an negative number")
        
        return BInt(limbs: Limbs.recursiveMul(0, Limb(self.toInt()!)))
    }
    
    //
    //
    // MARK: - BInt Division
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt Division        |||||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    ///    Returns the quotient and remainder of this value divided by the given value.
    public func quotientAndRemainder(dividingBy rhs: BInt) -> (quotient: BInt, remainder: BInt) {
        let limbRes = self.limbs.divMod(rhs.limbs)
        return (BInt(limbs: limbRes.quotient), BInt(limbs: limbRes.remainder))
    }
    
    public static func /(lhs: BInt, rhs: BInt) -> BInt {
        let limbs = lhs.limbs.divMod(rhs.limbs).quotient
        let sign = (lhs.sign != rhs.sign) && !limbs.equalTo(0)
        
        return BInt(sign: sign, limbs: limbs)
    }
    
    static func /(lhs: Int, rhs: BInt) -> BInt { return BInt(lhs) / rhs }
    static func /(lhs: BInt, rhs: Int) -> BInt { return lhs / BInt(rhs) }
    
    public static func /=(lhs: inout BInt, rhs: BInt) { lhs = lhs / rhs       }
    static func /=(lhs: inout BInt, rhs: Int) { lhs = lhs / BInt(rhs) }
    
    //
    //
    // MARK: - BInt Modulus
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt Modulus        ||||||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    public static func %(lhs: BInt, rhs: BInt) -> BInt {
        let limbs = lhs.limbs.divMod(rhs.limbs).remainder
        let sign = lhs.sign && !limbs.equalTo(0)
        
        return BInt(sign: sign, limbs: limbs)
    }
    
    static func %(lhs: Int, rhs: BInt) -> BInt { return BInt(lhs) % rhs  }
    static func %(lhs: BInt, rhs: Int) -> BInt { return lhs % BInt(rhs) }
    
    public static func %=(lhs: inout BInt, rhs: BInt) { lhs = lhs % rhs       }
    static func %=(lhs: inout BInt, rhs: Int) { lhs = lhs % BInt(rhs) }
    
    //
    //
    // MARK: - BInt Comparing
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        BInt Comparing        ||||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    // Required by protocol Equatable
    public static func ==(lhs: BInt, rhs: BInt) -> Bool {
        if lhs.sign != rhs.sign { return false }
        return lhs.limbs == rhs.limbs
    }
    
    static func ==<T: BinaryInteger>(lhs: BInt, rhs: T) -> Bool {
        if lhs.limbs.count != 1 { return false }
        return lhs.limbs[0] == rhs
    }
    
    static func ==<T: BinaryInteger>(lhs: T, rhs: BInt) -> Bool { return rhs == lhs }
    
    static func !=(lhs: BInt, rhs: BInt) -> Bool {
        if lhs.sign != rhs.sign { return true }
        return lhs.limbs != rhs.limbs
    }
    
    static func !=<T: BinaryInteger>(lhs: BInt, rhs: T) -> Bool {
        if lhs.limbs.count != 1 { return true }
        return lhs.limbs[0] != rhs
    }
    
    static func !=<T: BinaryInteger>(lhs: T, rhs: BInt) -> Bool { return rhs != lhs }
    
    // Required by protocol Comparable
    public static func <(lhs: BInt, rhs: BInt) -> Bool {
        if lhs.sign != rhs.sign { return lhs.sign }
        
        if lhs.sign { return rhs.limbs.lessThan(lhs.limbs) }
        return lhs.limbs.lessThan(rhs.limbs)
    }
    
    static func <<T: BinaryInteger>(lhs: BInt, rhs: T) -> Bool {
        if lhs.sign != (rhs < 0) { return lhs.sign }
        
        if lhs.sign {
            if lhs.limbs.count != 1 { return true }
            return rhs < lhs.limbs[0]
        } else {
            if lhs.limbs.count != 1 { return false }
            return lhs.limbs[0] < rhs
        }
        
    }
    
    static func <(lhs: Int, rhs: BInt) -> Bool { return BInt(lhs) < rhs }
    static func <(lhs: BInt, rhs: Int) -> Bool { return lhs < BInt(rhs) }
    
    // Required by protocol Comparable
    public static func >(lhs: BInt, rhs: BInt) -> Bool { return rhs < lhs       }
    static func >(lhs: Int, rhs: BInt) -> Bool { return BInt(lhs) > rhs }
    static func >(lhs: BInt, rhs: Int) -> Bool { return lhs > BInt(rhs) }
    
    // Required by protocol Comparable
    public static func <=(lhs: BInt, rhs: BInt) -> Bool { return !(rhs < lhs)       }
    static func <=(lhs: Int, rhs: BInt) -> Bool { return !(rhs < BInt(lhs)) }
    static func <=(lhs: BInt, rhs: Int) -> Bool { return !(BInt(rhs) < lhs) }
    
    // Required by protocol Comparable
    public static func >=(lhs: BInt, rhs: BInt) -> Bool { return !(lhs < rhs)       }
    static func >=(lhs: Int, rhs: BInt) -> Bool { return !(BInt(lhs) < rhs) }
    static func >=(lhs: BInt, rhs: Int) -> Bool { return !(lhs < BInt(rhs)) }
}
//
//
// MARK: - String operations
//    ————————————————————————————————————————————————————————————————————————————————————————————
//    ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ||||||||        String operations        |||||||||||||||||||||||||||||||||||||||||||||||||||
//    ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ————————————————————————————————————————————————————————————————————————————————————————————
//
//
//
fileprivate extension String {
    // Splits the string into equally sized parts (exept for the last one).
    func split(_ count: Int) -> [String] {
        return stride(from: 0, to: self.count, by: count).map { i -> String in
            let start = index(startIndex, offsetBy: i)
            let end = index(start, offsetBy: count, limitedBy: endIndex) ?? endIndex
            return String(self[start..<end])
        }
    }
    
    ///    Assuming that this String represents a number in some base fromBase, return a String
    ///    that contains the number converted to base toBase.
    func convertingBase(from: Int, toBase: Int) -> String {
        let chars: [Character] = [
            "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b",
            "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
            "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
            "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
            "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
            "Y", "Z"
        ]
        
        var res = ""
        var number = self
        
        if number.hasPrefix("-") {
            res = "-"
            number.removeFirst()
        }
        
        var sum = BInt(0)
        var multiplier = BInt(1)
        
        for char in number.reversed() {
            if let digit = chars.firstIndex(of: char) {
                precondition(digit < from)
                
                sum += digit * multiplier
                multiplier *= from
            } else {
                fatalError()
            }
        }
        
        repeat {
            res.insert(chars[(sum % toBase).toInt()!], at: res.startIndex)
            sum /= BInt(toBase)
        }
            while sum != 0
        
        return res
    }
}
private let DigitBase: Digit = 1_000_000_000_000_000_000
private let DigitHalfBase: Digit = 1_000_000_000
private let DigitZeros = 18
fileprivate extension Array where Element == Limb {
    var decimalRepresentation: String {
        // First, convert limbs to digits
        var digits: Digits = [0]
        var power: Digits = [1]
        
        for limb in self {
            let digit = (limb >= DigitBase)
                ? [limb % DigitBase, limb / DigitBase]
                : [limb]
            
            digits.addProductOfDigits(digit, power)
            
            var nextPower: Digits = [0]
            nextPower.addProductOfDigits(power, [446_744_073_709_551_616, 18])
            power = nextPower
        }
        
        // Then, convert digits to string
        var res = String(digits.last!)
        
        if digits.count == 1 { return res }
        
        for i in (0..<(digits.count - 1)).reversed() {
            let str = String(digits[i])
            
            let leadingZeros = String(repeating: "0", count: DigitZeros - str.count)
            
            res.append(leadingZeros.appending(str))
        }
        
        return res
    }
}
fileprivate extension Digit {
    mutating func addReportingOverflowDigit(_ addend: Digit) -> Bool {
        self = self &+ addend
        if self >= DigitBase { self -= DigitBase; return true }
        return false
    }
    
    func multipliedFullWidthDigit(by multiplicand: Digit) -> (Digit, Digit) {
        let (lLo, lHi) = (self % DigitHalfBase, self / DigitHalfBase)
        let (rLo, rHi) = (multiplicand % DigitHalfBase, multiplicand / DigitHalfBase)
        
        let K = (lHi * rLo) + (rHi * lLo)
        
        var resLo = (lLo * rLo) + ((K % DigitHalfBase) * DigitHalfBase)
        var resHi = (lHi * rHi) + (K / DigitHalfBase)
        
        if resLo >= DigitBase {
            resLo -= DigitBase
            resHi += 1
        }
        
        return (resLo, resHi)
    }
}
fileprivate extension Array where Element == Digit {
    mutating func addOneDigit(
        _ addend: Limb,
        padding paddingZeros: Int
        ) {
        let sc = self.count
        
        if paddingZeros > sc { self += Digits(repeating: 0, count: paddingZeros &- sc) }
        if paddingZeros >= sc { self.append(addend); return }
        
        // Now, i < sc
        var i = paddingZeros
        
        let ovfl = self[i].addReportingOverflowDigit(addend)
        
        while ovfl {
            i += 1
            if i == sc { self.append(1); return }
            self[i] += 1
            if self[i] != DigitBase { return }
            self[i] = 0
        }
    }
    
    mutating func addTwoDigit(
        _ addendLow: Limb,
        _ addendHigh: Limb,
        padding paddingZeros: Int) {
        let sc = self.count
        
        if paddingZeros > sc { self += Digits(repeating: 0, count: paddingZeros &- sc) }
        if paddingZeros >= sc { self += [addendLow, addendHigh]; return }
        
        // Now, i < sc
        var i = paddingZeros
        var newDigit: Digit
        
        let ovfl1 = self[i].addReportingOverflowDigit(addendLow)
        i += 1
        
        if i == sc {
            newDigit = (addendHigh &+ (ovfl1 ? 1 : 0)) % DigitBase
            self.append(newDigit)
            if newDigit == 0 { self.append(1) }
            return
        }
        
        // Still, i < sc
        var ovfl2 = self[i].addReportingOverflowDigit(addendHigh)
        if ovfl1 {
            self[i] += 1
            if self[i] == DigitBase { self[i] = 0; ovfl2 = true }
        }
        
        while ovfl2 {
            i += 1
            if i == sc { self.append(1); return }
            self[i] += 1
            if self[i] != DigitBase { return }
            self[i] = 0
        }
    }
    
    mutating func addProductOfDigits(_ multiplier: Digits, _ multiplicand: Digits) {
        let (mpc, mcc) = (multiplier.count, multiplicand.count)
        self.reserveCapacity(mpc &+ mcc)
        
        var l, r, resLo, resHi: Digit
        
        for i in 0..<mpc {
            l = multiplier[i]
            if l == 0 { continue }
            
            for j in 0..<mcc {
                r = multiplicand[j]
                if r == 0 { continue }
                
                (resLo, resHi) = l.multipliedFullWidthDigit(by: r)
                
                if resHi == 0 {
                    self.addOneDigit(resLo, padding: i + j)
                } else {
                    self.addTwoDigit(resLo, resHi, padding: i + j)
                }
            }
        }
    }
}
//
//
// MARK: - Limbs extension
//    ————————————————————————————————————————————————————————————————————————————————————————————
//    ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ||||||||        Limbs extension        |||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//    ————————————————————————————————————————————————————————————————————————————————————————————
//
//
//
// Extension to Limbs type
fileprivate extension Array where Element == Limb {
    //
    //
    // MARK: - Limbs bitlevel
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        Limbs bitlevel        ||||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    /// Returns the number of bits that contribute to the represented number, ignoring all
    /// leading zeros.
    var bitWidth: Int {
        var lastBits = 0
        var last = self.last!
        
        while last != 0 {
            last >>= 1
            lastBits += 1
        }
        
        return ((self.count - 1) * 64) + lastBits
    }
    
    ///    Get bit i of limbs.
    func getBit(at i: Int) -> Bool {
        let limbIndex = Int(Limb(i) >> 6)
        
        if limbIndex >= self.count { return false }
        
        let bitIndex = Limb(i) & 0b111_111
        
        return (self[limbIndex] & (1 << bitIndex)) != 0
    }
    
    /// Set bit i of limbs to b. b must be 0 for false, and everything else for true.
    mutating func setBit(
        at i: Int,
        to bit: Bool
        ) {
        let limbIndex = Int(Limb(i) >> 6)
        
        if limbIndex >= self.count && !bit { return }
        
        let bitIndex = Limb(i) & 0b111_111
        
        while limbIndex >= self.count { self.append(0) }
        
        if bit {
            self[limbIndex] |= (1 << bitIndex)
        } else {
            self[limbIndex] &= ~(1 << bitIndex)
        }
    }
    
    //
    //
    // MARK: - Limbs Shifting
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        Limbs Shifting        ||||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    mutating func shiftUp(_ shift: Int) {
        // No shifting is required in this case
        if shift == 0 || self.equalTo(0) { return }
        
        let limbShifts = shift >> 6
        let bitShifts = Limb(shift) & 0x3f
        
        if bitShifts != 0 {
            var previousCarry = Limb(0)
            var carry = Limb(0)
            var ele = Limb(0) // use variable to minimize array accesses
            
            for i in 0..<self.count {
                ele = self[i]
                
                carry = ele >> (64 - bitShifts)
                
                ele <<= bitShifts
                ele |= previousCarry // carry from last step
                previousCarry = carry
                
                self[i] = ele
            }
            
            if previousCarry != 0 { self.append(previousCarry) }
        }
        
        if limbShifts != 0 {
            self.insert(contentsOf: Limbs(repeating: 0, count: limbShifts), at: 0)
        }
    }
    
    func shiftingUp(_ shift: Int) -> Limbs {
        var res = self
        res.shiftUp(shift)
        return res
    }
    
    mutating func shiftDown(_ shift: Int) {
        if shift == 0 || self.equalTo(0) { return }
        
        let limbShifts = shift >> 6
        let bitShifts = Limb(shift) & 0x3f
        
        if limbShifts >= self.count {
            self = [0]
            return
        }
        
        self.removeSubrange(0..<limbShifts)
        
        if bitShifts != 0 {
            var previousCarry = Limb(0)
            var carry = Limb(0)
            var ele = Limb(0) // use variable to minimize array accesses
            
            var i = self.count - 1 // use while for high performance
            while i >= 0 {
                ele = self[i]
                
                carry = ele << (64 - bitShifts)
                
                ele >>= bitShifts
                ele |= previousCarry
                previousCarry = carry
                
                self[i] = ele
                
                i -= 1
            }
        }
        
        if self.last! == 0 && self.count != 1 { self.removeLast() }
    }
    
    func shiftingDown(_ shift: Int) -> Limbs {
        var res = self
        res.shiftDown(shift)
        return res
    }
    
    //
    //
    // MARK: - Limbs Addition
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        Limbs Addition        ||||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    mutating func addLimbs(_ addend: Limbs) {
        let (sc, ac) = (self.count, addend.count)
        
        var (newLimb, ovfl) = (Limb(0), false)
        
        let minCount = Swift.min(sc, ac)
        
        var i = 0
        while i < minCount {
            if ovfl {
                (newLimb, ovfl) = self[i].addingReportingOverflow(addend[i])
                newLimb = newLimb &+ 1
                
                ovfl = ovfl || newLimb == 0
            } else {
                (newLimb, ovfl) = self[i].addingReportingOverflow(addend[i])
            }
            
            self[i] = newLimb
            i += 1
        }
        
        while ovfl {
            if i < sc {
                if i < ac {
                    (newLimb, ovfl) = self[i].addingReportingOverflow(addend[i])
                    newLimb = newLimb &+ 1
                    ovfl = ovfl || newLimb == 0
                } else {
                    (newLimb, ovfl) = self[i].addingReportingOverflow(1)
                }
                
                self[i] = newLimb
            } else {
                if i < ac {
                    (newLimb, ovfl) = addend[i].addingReportingOverflow(1)
                    self.append(newLimb)
                } else {
                    self.append(1)
                    return
                }
            }
            
            i += 1
        }
        
        if self.count < ac {
            self.append(contentsOf: addend.suffix(from: i))
        }
    }
    
    /// Adding Limbs and returning result
    func adding(_ addend: Limbs) -> Limbs {
        var res = self
        res.addLimbs(addend)
        return res
    }
    
    // CURRENTLY NOT USED:
    ///    Add the addend to Limbs, while using a padding at the lower end.
    ///    Every zero is a Limb, that means one padding zero equals 64 padding bits
    mutating func addLimbs(
        _ addend: Limbs,
        padding paddingZeros: Int
        ) {
        let sc = self.count
        
        if paddingZeros > sc { self += Digits(repeating: 0, count: paddingZeros &- sc) }
        if paddingZeros >= sc { self += addend; return }
        
        // Now, i < sc
        let ac = addend.count &+ paddingZeros
        
        var (newLimb, ovfl) = (Limb(0), false)
        
        let minCount = Swift.min(sc, ac)
        
        var i = paddingZeros
        while i < minCount {
            if ovfl {
                (newLimb, ovfl) = self[i].addingReportingOverflow(addend[i &- paddingZeros])
                newLimb = newLimb &+ 1
                self[i] = newLimb
                ovfl = ovfl || newLimb == 0
            } else {
                (self[i], ovfl) = self[i].addingReportingOverflow(addend[i &- paddingZeros])
            }
            
            i += 1
        }
        
        while ovfl {
            if i < sc {
                let adding = i < ac ? addend[i &- paddingZeros] &+ 1 : 1
                (self[i], ovfl) = self[i].addingReportingOverflow(adding)
                ovfl = ovfl || adding == 0
            } else {
                if i < ac {
                    (newLimb, ovfl) = addend[i &- paddingZeros].addingReportingOverflow(1)
                    self.append(newLimb)
                } else {
                    self.append(1)
                    return
                }
            }
            
            i += 1
        }
        
        if self.count < ac {
            self.append(contentsOf: addend.suffix(from: i &- paddingZeros))
        }
    }
    
    mutating func addOneLimb(
        _ addend: Limb,
        padding paddingZeros: Int
        ) {
        let sc = self.count
        
        if paddingZeros > sc { self += Digits(repeating: 0, count: paddingZeros &- sc) }
        if paddingZeros >= sc { self.append(addend); return }
        
        // Now, i < lhc
        var i = paddingZeros
        
        var ovfl: Bool
        (self[i], ovfl) = self[i].addingReportingOverflow(addend)
        
        while ovfl {
            i += 1
            if i == sc { self.append(1); return }
            (self[i], ovfl) = self[i].addingReportingOverflow(1)
        }
    }
    
    /// Basically self.addOneLimb([addendLow, addendHigh], padding: paddingZeros), but faster
    mutating func addTwoLimb(
        _ addendLow: Limb,
        _ addendHigh: Limb,
        padding paddingZeros: Int) {
        let sc = self.count
        
        if paddingZeros > sc { self += Digits(repeating: 0, count: paddingZeros &- sc) }
        if paddingZeros >= sc { self += [addendLow, addendHigh]; return }
        
        // Now, i < sc
        var i = paddingZeros
        var newLimb: Limb
        
        var ovfl1: Bool
        (self[i], ovfl1) = self[i].addingReportingOverflow(addendLow)
        i += 1
        
        if i == sc {
            newLimb = addendHigh &+ (ovfl1 ? 1 : 0)
            self.append(newLimb)
            if newLimb == 0 { self.append(1) }
            return
        }
        
        // Still, i < sc
        var ovfl2: Bool
        (self[i], ovfl2) = self[i].addingReportingOverflow(addendHigh)
        
        if ovfl1 {
            self[i] = self[i] &+ 1
            if self[i] == 0 { ovfl2 = true }
        }
        
        while ovfl2 {
            i += 1
            if i == sc { self.append(1); return }
            (self[i], ovfl2) = self[i].addingReportingOverflow(1)
        }
    }
    
    //
    //
    // MARK: - Limbs Subtraction
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        Limbs Subtraction        |||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    /// Calculates difference between Limbs in left limb
    mutating func difference(_ subtrahend: Limbs) {
        var subtrahend = subtrahend
        // swap to get difference
        if self.lessThan(subtrahend) { swap(&self, &subtrahend) }
        
        let rhc = subtrahend.count
        var ovfl = false
        
        var i = 0
        
        // skip first zeros
        while i < rhc && subtrahend[i] == 0 { i += 1 }
        
        while i < rhc {
            if ovfl {
                (self[i], ovfl) = self[i].subtractingReportingOverflow(subtrahend[i])
                self[i] = self[i] &- 1
                ovfl = ovfl || self[i] == Limb.max
            } else {
                (self[i], ovfl) = self[i].subtractingReportingOverflow(subtrahend[i])
            }
            
            i += 1
        }
        
        while ovfl {
            if i >= self.count {
                self.append(Limb.max)
                break
            }
            
            (self[i], ovfl) = self[i].subtractingReportingOverflow(1)
            
            i += 1
        }
        
        if self.count > 1 && self.last! == 0 // cut excess zeros if required
        {
            var j = self.count - 2
            while j >= 1 && self[j] == 0 { j -= 1 }
            
            self.removeSubrange((j + 1)..<self.count)
        }
    }
    
    func differencing(_ subtrahend: Limbs) -> Limbs {
        var res = self
        res.difference(subtrahend)
        return res
    }
    
    //
    //
    // MARK: - Limbs Multiplication
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        Limbs Multiplication        |||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    mutating func addProductOf(
        multiplier: Limbs,
        multiplicand: Limbs
        ) {
        let (mpc, mcc) = (multiplier.count, multiplicand.count)
        
        self.reserveCapacity(mpc + mcc)
        
        // Minimize array subscript calls
        var l, r, mulHi, mulLo: Limb
        
        for i in 0..<mpc {
            l = multiplier[i]
            if l == 0 { continue }
            
            for j in 0..<mcc {
                r = multiplicand[j]
                if r == 0 { continue }
                
                (mulHi, mulLo) = l.multipliedFullWidth(by: r)
                
                if mulHi != 0 { self.addTwoLimb(mulLo, mulHi, padding: i + j) } else { self.addOneLimb(mulLo, padding: i + j) }
            }
        }
    }
    
    // Perform res += (lhs * r)
    mutating func addProductOf(
        multiplier: Limbs,
        multiplicand: Limb
        ) {
        if multiplicand < 2 {
            if multiplicand == 1 { self.addLimbs(multiplier) }
            // If r == 0 then do nothing with res
            return
        }
        
        // Minimize array subscript calls
        var l, mulHi, mulLo: Limb
        
        for i in 0..<multiplier.count {
            l = multiplier[i]
            if l == 0 { continue }
            
            (mulHi, mulLo) = l.multipliedFullWidth(by: multiplicand)
            
            if mulHi != 0 { self.addTwoLimb(mulLo, mulHi, padding: i) } else {          self.addOneLimb(mulLo, padding: i) }
        }
    }
    
    func multiplyingBy(_ multiplicand: Limbs) -> Limbs {
        var res: Limbs = [0]
        res.addProductOf(multiplier: self, multiplicand: multiplicand)
        return res
    }
    
    func squared() -> Limbs {
        var res: Limbs = [0]
        res.reserveCapacity(2 * self.count)
        
        // Minimize array subscript calls
        var l, r, mulHi, mulLo: Limb
        
        for i in 0..<self.count {
            l = self[i]
            if l == 0 { continue }
            
            for j in 0...i {
                r = self[j]
                if r == 0 { continue }
                
                (mulHi, mulLo) = l.multipliedFullWidth(by: r)
                
                if mulHi != 0 {
                    if i != j { res.addTwoLimb(mulLo, mulHi, padding: i + j) }
                    res.addTwoLimb(mulLo, mulHi, padding: i + j)
                } else {
                    if i != j { res.addOneLimb(mulLo, padding: i + j) }
                    res.addOneLimb(mulLo, padding: i + j)
                }
            }
        }
        
        return res
    }
    
    //
    //
    // MARK: - Limbs Exponentiation
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        Limbs Exponentiation        ||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    // Exponentiation by squaring
    func exponentiating(_ exponent: Int) -> Limbs {
        if exponent == 0 { return [1] }
        if exponent == 1 { return self }
        
        var base = self
        var exponent = exponent
        var y: Limbs = [1]
        
        while exponent > 1 {
            if exponent & 1 != 0 { y = y.multiplyingBy(base) }
            base = base.squared()
            exponent >>= 1
        }
        
        return base.multiplyingBy(y)
    }
    
    /// Calculate (n + 1) * (n + 2) * ... * (k - 1) * k
    static func recursiveMul(_ n: Limb, _ k: Limb) -> Limbs {
        if n >= k - 1 { return [k] }
        
        let m = (n + k) >> 1
        
        return recursiveMul(n, m).multiplyingBy(recursiveMul(m, k))
    }
    
    func factorial(_ base: Int) -> BInt {
        return BInt(limbs: Limbs.recursiveMul(0, Limb(base)))
    }
    
    //
    //
    // MARK: - Limbs Division and Modulo
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        Limbs Division and Modulo        |||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    /// An O(n) division algorithm that returns quotient and remainder.
    func divMod(_ divisor: Limbs) -> (quotient: Limbs, remainder: Limbs) {
        precondition(!divisor.equalTo(0), "Division or Modulo by zero not allowed")
        
        if self.equalTo(0) { return ([0], [0]) }
        
        var (quotient, remainder): (Limbs, Limbs) = ([0], [0])
        var (previousCarry, carry, ele): (Limb, Limb, Limb) = (0, 0, 0)
        
        // bits of lhs minus one bit
        var i = (64 * (self.count - 1)) + Int(log2(Double(self.last!)))
        
        while i >= 0 {
            // shift remainder by 1 to the left
            for r in 0..<remainder.count {
                ele = remainder[r]
                carry = ele >> 63
                ele <<= 1
                ele |= previousCarry // carry from last step
                previousCarry = carry
                remainder[r] = ele
            }
            if previousCarry != 0 { remainder.append(previousCarry) }
            
            remainder.setBit(at: 0, to: self.getBit(at: i))
            
            if !remainder.lessThan(divisor) {
                remainder.difference(divisor)
                quotient.setBit(at: i, to: true)
            }
            
            i -= 1
        }
        
        return (quotient, remainder)
    }
    
    /// Division with limbs, result is floored to nearest whole number.
    func dividing(_ divisor: Limbs) -> Limbs {
        return self.divMod(divisor).quotient
    }
    
    /// Modulo with limbs, result is floored to nearest whole number.
    func modulus(_ divisor: Limbs) -> Limbs {
        return self.divMod(divisor).remainder
    }
    
    //
    //
    // MARK: - Limbs Comparing
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //    ||||||||        Limbs Comparing        |||||||||||||||||||||||||||||||||||||||||||||||||
    //    ————————————————————————————————————————————————————————————————————————————————————————
    //
    //
    //
    
    //    Note:
    //    a < b iff b > a
    //    a <= b iff b >= a
    //    but:
    //    a < b iff !(a >= b)
    //    a <= b iff !(a > b)
    
    func lessThan(_ compare: Limbs) -> Bool {
        let lhsc = self.count
        let rhsc = compare.count
        
        if lhsc != rhsc {
            return lhsc < rhsc
        }
        
        var i = lhsc - 1
        while i >= 0 {
            if self[i] != compare[i] { return self[i] < compare[i] }
            i -= 1
        }
        
        return false // lhs == rhs
    }
    
    func equalTo(_ compare: Limb) -> Bool {
        return self[0] == compare && self.count == 1
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_0NOTEQUAL.swift
================================================
//
//  OP_0NOTEQUAL.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// replaces number with True if it's not zero, False otherwise.
public struct OP0NotEqual: OpCodeProtocol {
    public var value: UInt8 { return 0x92 }
    public var name: String { return "OP_0NOTEQUAL" }

    // (in -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let input = try context.number(at: -1)
        context.stack.removeLast()
        context.pushToStack(input != 0)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_1ADD.swift
================================================
//
//  OP_1ADD.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// 1 is added to the input.
public struct Op1Add: OpCodeProtocol {
    public var value: UInt8 { return 0x8b }
    public var name: String { return "OP_1ADD" }

    // (in -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let input = try context.number(at: -1)
        context.stack.removeLast()
        try context.pushToStack(input + 1)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_1SUB.swift
================================================
//
//  OP_1SUB.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// 1 is subtracted from the input.
public struct Op1Sub: OpCodeProtocol {
    public var value: UInt8 { return 0x8c }
    public var name: String { return "OP_1SUB" }

    // (in -- out)
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let input = try context.number(at: -1)
        context.stack.removeLast()
        try context.pushToStack(input - 1)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_2DIV.swift
================================================
//
//  OP_2DIV.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// The input is divided by 2. disabled.
public struct Op2Div: OpCodeProtocol {
    public var value: UInt8 { return 0x8e }
    public var name: String { return "OP_2DIV" }

    public func isEnabled() -> Bool {
        return false
    }

    // (in -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let input = try context.number(at: -1)
        context.stack.removeLast()
        try context.pushToStack(input / 2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_2MUL.swift
================================================
//
//  OP_2MUL.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// The input is multiplied by 2. disabled.
public struct Op2Mul: OpCodeProtocol {
    public var value: UInt8 { return 0x8d }
    public var name: String { return "OP_2MUL" }

    public func isEnabled() -> Bool {
        return false
    }

    // (in -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let input = try context.number(at: -1)
        context.stack.removeLast()
        try context.pushToStack(input * 2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_ABS.swift
================================================
//
//  OP_ABS.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// replaces number with its absolute value
public struct OpAbsolute: OpCodeProtocol {
    public var value: UInt8 { return 0x90 }
    public var name: String { return "OP_ABS" }

    // (in -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let input = try context.number(at: -1)
        context.stack.removeLast()
        try context.pushToStack(abs(input))
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_ADD.swift
================================================
//
//  OP_ADD.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// (x y -- x+y)
public struct OpAdd: OpCodeProtocol {
    public var value: UInt8 { return 0x93 }
    public var name: String { return "OP_ADD" }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        try context.pushToStack(x1 + x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_BOOLAND.swift
================================================
//
//  OP_BOOLAND.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// If both a and b are not "" (null string), the output is 1. Otherwise 0.
public struct OpBoolAnd: OpCodeProtocol {
    public var value: UInt8 { return 0x9a }
    public var name: String { return "OP_BOOLAND" }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = context.data(at: -2)
        let x2 = context.data(at: -1)
        let output: Bool = x1 != Data() && x2 != Data()

        context.stack.removeLast()
        context.stack.removeLast()
        context.pushToStack(output)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_BOOLOR.swift
================================================
//
//  OP_BOOLOR.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// If a or b is not "" (null string), the output is 1. Otherwise 0.
public struct OpBoolOr: OpCodeProtocol {
    public var value: UInt8 { return 0x9b }
    public var name: String { return "OP_BOOLOR" }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = context.data(at: -2)
        let x2 = context.data(at: -1)
        let output: Bool = x1 != Data() || x2 != Data()

        context.stack.removeLast()
        context.stack.removeLast()
        context.pushToStack(output)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_DIV.swift
================================================
//
//  OP_DIV.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// (x y -- x/y)
public struct OpDiv: OpCodeProtocol {
    public var value: UInt8 { return 0x96 }
    public var name: String { return "OP_DIV" }

    // (x1 x2 -- out)
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        // denominator must not be 0
        guard x2 != 0 else {
            throw OpCodeExecutionError.error("Division by zero error")
        }

        context.stack.removeLast()
        context.stack.removeLast()
        try context.pushToStack(x1 / x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_GREATERTHAN.swift
================================================
//
//  OP_GREATERTHAN.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// Returns 1 if x1 is greater than x2, 0 otherwise.
public struct OpGreaterThan: OpCodeProtocol {
    public var value: UInt8 { return 0xa0 }
    public var name: String { return "OP_GREATERTHAN" }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        context.pushToStack(x1 > x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_GREATERTHANOREQUAL.swift
================================================
//
//  OP_GREATERTHANOREQUAL.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// Returns 1 if x1 is greater than or equal to x2, 0 otherwise.
public struct OpGreaterThanOrEqual: OpCodeProtocol {
    public var value: UInt8 { return 0xa2 }
    public var name: String { return "OP_GREATERTHANOREQUAL" }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        context.pushToStack(x1 >= x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_LESSTHAN.swift
================================================
//
//  OP_LESSTHAN.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// Returns 1 if x1 is less than x2, 0 otherwise.
public struct OpLessThan: OpCodeProtocol {
    public var value: UInt8 { return 0x9f }
    public var name: String { return "OP_LESSTHAN" }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        context.pushToStack(x1 < x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_LESSTHANOREQUAL.swift
================================================
//
//  OP_LESSTHANOREQUAL.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// Returns 1 if x1 is less than or equal to x2, 0 otherwise.
public struct OpLessThanOrEqual: OpCodeProtocol {
    public var value: UInt8 { return 0xa1 }
    public var name: String { return "OP_LESSTHANOREQUAL" }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        context.pushToStack(x1 <= x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_LSHIFT.swift
================================================
//
//  OP_LSHIFT.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// (x y -- x<<y) disabled.
public struct OpLShift: OpCodeProtocol {
    public var value: UInt8 { return 0x98 }
    public var name: String { return "OP_LSHIFT" }

    public func isEnabled() -> Bool {
        return false
    }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        try context.pushToStack(x1 << x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_MAX.swift
================================================
//
//  OP_MAX.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Returns the larger of a and b.
public struct OpMax: OpCodeProtocol {
    public var value: UInt8 { return 0xa4 }
    public var name: String { return "OP_MAX" }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        try context.pushToStack(max(x1, x2))
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_MIN.swift
================================================
//
//  OP_MIN.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Returns the smaller of a and b.
public struct OpMin: OpCodeProtocol {
    public var value: UInt8 { return 0xa3 }
    public var name: String { return "OP_MIN" }

    // (x1 x2 -- out)
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        try context.pushToStack(min(x1, x2))
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_MOD.swift
================================================
//
//  OP_MOD.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// (x y -- x%y)
public struct OpMod: OpCodeProtocol {
    public var value: UInt8 { return 0x97 }
    public var name: String { return "OP_MOD" }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        // denominator must not be 0
        guard x2 != 0 else {
            throw OpCodeExecutionError.error("Modulo by zero error")
        }

        context.stack.removeLast()
        context.stack.removeLast()
        try context.pushToStack(x1 % x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_MUL.swift
================================================
//
//  OP_MUL.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// (x y -- x*y) disabled
public struct OpMul: OpCodeProtocol {
    public var value: UInt8 { return 0x95 }
    public var name: String { return "OP_MUL" }

    public func isEnabled() -> Bool {
        return false
    }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        try context.pushToStack(x1 * x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_NEGATE.swift
================================================
//
//  OP_NEGATE.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// negates the number, pops it from stack and pushes result.
public struct OpNegate: OpCodeProtocol {
    public var value: UInt8 { return 0x8f }
    public var name: String { return "OP_NEGATE" }

    // (in -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let input = try context.number(at: -1)
        context.stack.removeLast()
        try context.pushToStack(-input)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_NOT.swift
================================================
//
//  OP_NOT.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// replaces number with True if it's zero, False otherwise.
public struct OpNot: OpCodeProtocol {
    public var value: UInt8 { return 0x91 }
    public var name: String { return "OP_NOT" }

    // (in -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let input = try context.number(at: -1)
        context.stack.removeLast()
        context.pushToStack(input == 0)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_NUMEQUAL.swift
================================================
//
//  OP_NUMEQUAL.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// Returns 1 if the numbers are equal, 0 otherwise.
public struct OpNumEqual: OpCodeProtocol {
    public var value: UInt8 { return 0x9c }
    public var name: String { return "OP_NUMEQUAL" }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        context.pushToStack(x1 == x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_NUMEQUALVERIFY.swift
================================================
//
//  OP_NUMEQUALVERIFY.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// Same as OP_NUMEQUAL, but runs OP_VERIFY afterward.
public struct OpNumEqualVerify: OpCodeProtocol {
    public var value: UInt8 { return 0x9d }
    public var name: String { return "OP_NUMEQUALVERIFY" }

    // input : x1 x2
    // output : - / fail
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try OpCode.OP_NUMEQUAL.mainProcess(context)
        do {
            try OpCode.OP_VERIFY.mainProcess(context)
        } catch {
            throw OpCodeExecutionError.error("OP_NUMEQUALVERIFY failed.")
        }
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_NUMNOTEQUAL.swift
================================================
//
//  OP_NUMNOTEQUAL.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// Returns 1 if the numbers are not equal, 0 otherwise.
public struct OpNumNotEqual: OpCodeProtocol {
    public var value: UInt8 { return 0xe }
    public var name: String { return "OP_NUMNOTEQUAL" }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        context.pushToStack(x1 != x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_RSHIFT.swift
================================================
//
//  OP_RSHIFT.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// (x y -- x>>y) disabled.
public struct OpRShift: OpCodeProtocol {
    public var value: UInt8 { return 0x99 }
    public var name: String { return "OP_RSHIFT" }

    public func isEnabled() -> Bool {
        return false
    }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        try context.pushToStack(x1 >> x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_SUB.swift
================================================
//
//  OP_SUB.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// (x y -- x-y)
public struct OpSub: OpCodeProtocol {
    public var value: UInt8 { return 0x94 }
    public var name: String { return "OP_SUB" }

    // (x1 x2 -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = try context.number(at: -2)
        let x2 = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        try context.pushToStack(x1 - x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_WITHIN.swift
================================================
//
//  OP_WITHIN.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
import Foundation

// Returns 1 if x is within the specified range (left-inclusive), 0 otherwise.
public struct OpWithin: OpCodeProtocol {
    public var value: UInt8 { return 0xa5 }
    public var name: String { return "OP_WITHIN" }

    // (x1 min max -- out)
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(3)

        let x = try context.number(at: -3)
        let minValue = try context.number(at: -2)
        let maxValue = try context.number(at: -1)

        context.stack.removeLast()
        context.stack.removeLast()
        context.stack.removeLast()
        context.pushToStack(minValue <= x && x < maxValue)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_AND.swift
================================================
//
//  OP_AND.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Boolean AND between each bit of the inputs
public struct OpAnd: OpCodeProtocol {
    public var value: UInt8 { return 0x84 }
    public var name: String { return "OP_AND" }

    // input : x1 x2
    // output : out
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x2 = context.stack.removeLast()
        let x1 = context.stack.removeLast()

        // Inputs must be the same size
        guard x1.count == x2.count else {
            throw OpCodeExecutionError.error("Invalid operand size")
        }

        let count: Int = x1.count
        var output = Data(count: count)
        for i in 0..<count {
            output[i] = x1[i] & x2[i]
        }
        context.stack.append(output)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_EQUAL.swift
================================================
//
//  OP_EQUAL.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Returns 1 if the inputs are exactly equal, 0 otherwise.
public struct OpEqual: OpCodeProtocol {
    public var value: UInt8 { return 0x87 }
    public var name: String { return "OP_EQUAL" }

    // input : x1 x2
    // output : true / false
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x1 = context.stack.popLast()!
        let x2 = context.stack.popLast()!
        let equal: Bool = x1 == x2
        context.pushToStack(equal)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_EQUALVERIFY.swift
================================================
//
//  OP_EQUALVERIFY.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Same as OP_EQUAL, but runs OP_VERIFY afterward.
public struct OpEqualVerify: OpCodeProtocol {
    public var value: UInt8 { return 0x88 }
    public var name: String { return "OP_EQUALVERIFY" }

    // input : x1 x2
    // output : - / fail
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try OpCode.OP_EQUAL.mainProcess(context)
        do {
            try OpCode.OP_VERIFY.mainProcess(context)
        } catch {
            throw OpCodeExecutionError.error("OP_EQUALVERIFY failed.")
        }
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_INVERT.swift
================================================
//
//  OP_INVERT.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Flips all of the bits in the input. disabled.
public struct OpInvert: OpCodeProtocol {
    public var value: UInt8 { return 0x83 }
    public var name: String { return "OP_INVERT" }

    public func isEnabled() -> Bool {
        return false
    }

    // input : in
    // output : out
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let x = context.stack.removeLast()
        let output: Data = Data(from: x.map { ~$0 })
        context.stack.append(output)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_OR.swift
================================================
//
//  OP_OR.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Boolean OR between each bit of the inputs
public struct OpOr: OpCodeProtocol {
    public var value: UInt8 { return 0x85 }
    public var name: String { return "OP_OR" }

    // input : x1 x2
    // output : out
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x2 = context.stack.removeLast()
        let x1 = context.stack.removeLast()

        // Inputs must be the same size
        guard x1.count == x2.count else {
            throw OpCodeExecutionError.error("Invalid operand size")
        }

        let count: Int = x1.count
        var output = Data(count: count)
        for i in 0..<count {
            output[i] = x1[i] | x2[i]
        }
        context.stack.append(output)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_RESERVED1.swift
================================================
//
//  OP_RESERVED1.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

public struct OpReserved1: OpCodeProtocol {
    public var value: UInt8 { return 0x89 }
    public var name: String { return "OP_RESERVED1" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        throw OpCodeExecutionError.error("\(name) should not be executed.")
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_RESERVED2.swift
================================================
//
//  OP_RESERVED2.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

public struct OpReserved2: OpCodeProtocol {
    public var value: UInt8 { return 0x8a }
    public var name: String { return "OP_RESERVED2" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        throw OpCodeExecutionError.error("\(name) should not be executed.")
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_XOR.swift
================================================
//
//  OP_XOR.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Boolean EXCLUSIVE OR between each bit of the inputs
public struct OpXor: OpCodeProtocol {
    public var value: UInt8 { return 0x86 }
    public var name: String { return "OP_XOR" }

    // input : x1 x2
    // output : out
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let x2 = context.stack.removeLast()
        let x1 = context.stack.removeLast()

        // Inputs must be the same size
        guard x1.count == x2.count else {
            throw OpCodeExecutionError.error("Invalid operand size")
        }

        let count: Int = x1.count
        var output = Data(count: count)
        for i in 0..<count {
            output[i] = x1[i] ^ x2[i]
        }
        context.stack.append(output)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_CHECKMULTISIG.swift
================================================
//
//  OP_CHECKMULTISIG.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Compares the first signature against each public key until it finds an ECDSA match. Starting
// with the subsequent public key, it compares the second signature against each remaining public key
// until it finds an ECDSA match. The process is repeated until all signatures have been checked or not
// enough public keys remain to produce a successful result. All signatures need to match a public key.
// Because public keys are not checked again if they fail any signature comparison, signatures must be
// placed in the scriptSig using the same order as their corresponding public keys were placed in the
// scriptPubKey or redeemScript. If all signatures are valid, 1 is returned, 0 otherwise. Due to a bug,
// one extra unused value is removed from the stack.
public struct OpCheckMultiSig: OpCodeProtocol {
    public var value: UInt8 { return 0xae }
    public var name: String { return "OP_CHECKMULTISIG" }

    // input : x sig1 sig2 ... <number of signatures> pub1 pub2 <number of public keys>
    // output : true / false
     public func mainProcess(_ context: ScriptExecutionContext) throws {

        // Get numPublicKeys with validation
        try context.assertStackHeightGreaterThanOrEqual(1)
        let numPublicKeys = Int(try context.number(at: -1))
        guard numPublicKeys >= 0 && numPublicKeys <= BTC_MAX_KEYS_FOR_CHECKMULTISIG else {
            throw OpCodeExecutionError.error("Invalid number of keys for \(name): \(numPublicKeys).")
        }
        try context.incrementOpCount(by: numPublicKeys)
        context.stack.removeLast()

        // Get pubkeys with validation
        var publicKeys: [Data] = []
        try context.assertStackHeightGreaterThanOrEqual(numPublicKeys)
        for _ in 0..<numPublicKeys {
            publicKeys.append(context.stack.removeLast())
        }

        // Get numgSis with validation
        try context.assertStackHeightGreaterThanOrEqual(1)
        let numSigs = Int(try context.number(at: -1))
        guard numSigs >= 0 && numSigs <= numPublicKeys else {
            throw OpCodeExecutionError.error("Invalid number of signatures for \(name): \(numSigs).")
        }
        context.stack.removeLast()

        // Get sigs with validation
        var signatures: [Data] = []
        try context.assertStackHeightGreaterThanOrEqual(numSigs)
        for _ in 0..<numSigs {
            signatures.append(context.stack.removeLast())
        }

        // Remove extra opcode (OP_0)
        // Due to a bug, one extra unused value is removed from the stack.
        try context.assertStackHeightGreaterThanOrEqual(1)
        context.stack.removeLast()

        // Signatures must come in the same order as their keys.
        var success: Bool = true
        var firstSigError: Error?
        guard let tx = context.transaction, let utxo = context.utxoToVerify else {
            throw OpCodeExecutionError.error("The transaction or the utxo to verify is not set.")
        }
        while success && !signatures.isEmpty {
            let pubkeyData: Data = publicKeys.removeFirst()
            let sigData: Data = signatures[0]
            do {
                let valid = try Crypto.verifySigData(for: tx, inputIndex: Int(context.inputIndex), utxo: utxo, sigData: sigData, pubKeyData: pubkeyData)
                if valid {
                    signatures.removeFirst()
                }
            } catch let error {
                if firstSigError == nil {
                    firstSigError = error
                }
            }

            // If there are more signatures left than keys left,
            // then too many signatures have failed
            if publicKeys.count < signatures.count {
                success = false
            }
        }
        context.pushToStack(success)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_CHECKMULTISIGVERIFY.swift
================================================
//
//  OP_CHECKMULTISIGVERIFY.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Same as OP_CHECKMULTISIG, but OP_VERIFY is executed afterward.
public struct OpCheckMultiSigVerify: OpCodeProtocol {
    public var value: UInt8 { return 0xaf }
    public var name: String { return "OP_CHECKMULTISIGVERIFY" }

    // input : x sig1 sig2 ... <number of signatures> pub1 pub2 <number of public keys>
    // output : Nothing / fail
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try OpCode.OP_CHECKMULTISIG.mainProcess(context)
        do {
            try OpCode.OP_VERIFY.mainProcess(context)
        } catch {
            throw OpCodeExecutionError.error("OP_CHECKMULTISIGVERIFY failed.")
        }
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_CHECKSIG.swift
================================================
//
//  OP_CHECKSIG.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// The entire transaction's outputs, inputs, and script (from the most recently-executed OP_CODESEPARATOR to the end) are hashed. The signature used by OP_CHECKSIG must be a valid signature for this hash and public key. If it is, 1 is returned, 0 otherwise.
public struct OpCheckSig: OpCodeProtocol {
    public var value: UInt8 { return 0xac }
    public var name: String { return "OP_CHECKSIG" }

    // input : sig pubkey
    // output : true / false
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)

        let pubkeyData: Data = context.stack.removeLast()
        let sigData: Data = context.stack.removeLast()

        guard let tx = context.transaction, let utxo = context.utxoToVerify else {
            throw OpCodeExecutionError.error("The transaction or the utxo to verify is not set.")
        }
        let valid = try Crypto.verifySigData(for: tx, inputIndex: Int(context.inputIndex), utxo: utxo, sigData: sigData, pubKeyData: pubkeyData)
        context.pushToStack(valid)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_CHECKSIGVERIFY.swift
================================================
//
//  OP_CHECKSIGVERIFY.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Same as OP_CHECKSIG, but OP_VERIFY is executed afterward.
public struct OpCheckSigVerify: OpCodeProtocol {
    public var value: UInt8 { return 0xad }
    public var name: String { return "OP_CHECKSIGVERIFY" }

    // input : sig pubkey
    // output : Nothing / fail
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try OpCode.OP_CHECKSIG.mainProcess(context)
        do {
            try OpCode.OP_VERIFY.mainProcess(context)
        } catch {
            throw OpCodeExecutionError.error("OP_CHECKSIGVERIFY failed.")
        }
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_CODESEPARATOR.swift
================================================
//
//  OP_CODESEPARATOR.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/09.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation

// All of the signature checking words will only match signatures to the data after the most recently-executed OP_CODESEPARATOR.
public struct OpCodeSeparator: OpCodeProtocol {
    public var value: UInt8 { return 0xab }
    public var name: String { return "OP_CODESEPARATOR" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        // do nothing
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_HASH160.swift
================================================
//
//  OP_HASH160.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// The input is hashed twice: first with SHA-256 and then with RIPEMD-160.
public struct OpHash160: OpCodeProtocol {
    public var value: UInt8 { return 0xa9 }
    public var name: String { return "OP_HASH160" }

    // input : in
    // output : hash
     public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let data: Data = context.stack.removeLast()
        let hash = RIPEMD160.hash(data.sha256())
        context.stack.append(hash)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_HASH256.swift
================================================
//
//  OP_HASH256.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/09.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation

// The input is hashed two times with SHA-256.
public struct OpHash256: OpCodeProtocol {
    public var value: UInt8 { return 0xaa }
    public var name: String { return "OP_HASH256" }

    // input : in
    // output : hash
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let data: Data = context.stack.removeLast()
        let hash: Data = data.doubleSHA256
        context.stack.append(hash)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_RIPEMD160.swift
================================================
//
//  OP_RIPEMD160.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/09.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation

// The input is hashed using RIPEMD-160.
public struct OpRipemd160: OpCodeProtocol {
    public var value: UInt8 { return 0xa6 }
    public var name: String { return "OP_RIPEMD160" }

    // input : in
    // output : hash
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let data: Data = context.stack.removeLast()
        let hash: Data = RIPEMD160.hash(data)
        context.stack.append(hash)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_SHA1.swift
================================================
//
//  OP_SHA1.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/09.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation
import CryptoSwift

// The input is hashed using SHA-1.
public struct OpSha1: OpCodeProtocol {
    public var value: UInt8 { return 0xa7 }
    public var name: String { return "OP_SHA1" }

    // input : in
    // output : hash
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let data: Data = context.stack.removeLast()
        let hash: Data = data.sha1()
        context.stack.append(hash)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_SHA256.swift
================================================
//
//  OP_SHA256.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/09.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation

// The input is hashed using SHA-256.
public struct OpSha256: OpCodeProtocol {
    public var value: UInt8 { return 0xa8 }
    public var name: String { return "OP_SHA256" }

    // input : in
    // output : hash
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        let data: Data = context.stack.removeLast()
         let hash: Data = data.sha256()
        context.stack.append(hash)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_ELSE.swift
================================================
//
//  OP_ELSE.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/08.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation

public struct OpElse: OpCodeProtocol {
    public var value: UInt8 { return 0x67 }
    public var name: String { return "OP_ELSE" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        guard !context.conditionStack.isEmpty else {
            throw OpCodeExecutionError.error("Expected an OP_IF or OP_NOTIF branch before OP_ELSE.")
        }
        let f = context.conditionStack.removeLast()
        context.conditionStack.append(!f)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_ENDIF.swift
================================================
//
//  OP_ENDIF.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/08.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation

public struct OpEndIf: OpCodeProtocol {
    public var value: UInt8 { return 0x68 }
    public var name: String { return "OP_ENDIF" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        guard !context.conditionStack.isEmpty else {
            throw OpCodeExecutionError.error("Expected an OP_IF or OP_NOTIF branch before OP_ENDIF.")
        }
        context.conditionStack.removeLast()
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_IF.swift
================================================
//
//  OP_IF.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/08.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation

public struct OpIf: OpCodeProtocol {
    public var value: UInt8 { return 0x63 }
    public var name: String { return "OP_IF" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        var value: Bool = false
        if context.shouldExecute {
            try context.assertStackHeightGreaterThanOrEqual(1)
            value = context.bool(at: -1)
            context.stack.removeLast()
        }
        context.conditionStack.append(value)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_NOP.swift
================================================
//
//  OP_NOP.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/08.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation

// do nothing
public struct OpNop: OpCodeProtocol {
    public var value: UInt8 { return 0x61 }
    public var name: String { return "OP_NOP" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        // do nothing
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_NOTIF.swift
================================================
//
//  OP_NOTIF.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/08.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation

public struct OpNotIf: OpCodeProtocol {
    public var value: UInt8 { return 0x64 }
    public var name: String { return "OP_NOTIF" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        var value: Bool = false
        if context.shouldExecute {
            try context.assertStackHeightGreaterThanOrEqual(1)
            value = context.bool(at: -1)
            context.stack.removeLast()
        }
        context.conditionStack.append(!value)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_RETURN.swift
================================================
//
//  OP_RETURN.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

public struct OpReturn: OpCodeProtocol {
    public var value: UInt8 { return 0x6a }
    public var name: String { return "OP_RETURN" }

     public func mainProcess(_ context: ScriptExecutionContext) throws {
        throw OpCodeExecutionError.error("OP_RETURN was encountered")
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_VER.swift
================================================
//
//  OP_VER.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/08.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation

public struct OpVer: OpCodeProtocol {
    public var value: UInt8 { return 0x62 }
    public var name: String { return "OP_VER" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        throw OpCodeExecutionError.error("OP_VER should not be executed.")
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_VERIF.swift
================================================
//
//  OP_VERIF.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/08.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation

// Transaction is invalid unless occuring in an unexecuted OP_IF branch
public struct OpVerIf: OpCodeProtocol {
    public var value: UInt8 { return 0x65 }
    public var name: String { return "OP_VERIF" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        throw OpCodeExecutionError.error("OP_VERIF should not be executed.")
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_VERIFY.swift
================================================
//
//  OP_VERIFY.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Marks transaction as invalid if top stack value is not true. The top stack value is removed.
public struct OpVerify: OpCodeProtocol {
    public var value: UInt8 { return 0x69 }
    public var name: String { return "OP_VERIFY" }

    // input : true / false
    // output : - / fail
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)
        guard context.bool(at: -1) else {
            throw OpCodeExecutionError.error("OP_VERIFY failed.")
        }
        context.stack.removeLast()
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_VERNOTIF.swift
================================================
//
//  OP_VERNOTIF.swift
//  BitcoinKit
//
//  Created by Shun Usami on 2018/08/08.
//  Copyright © 2018 BitcoinKit developers. All rights reserved.
//

import Foundation

public struct OpVerNotIf: OpCodeProtocol {
    public var value: UInt8 { return 0x66 }
    public var name: String { return "OP_VERNOTIF" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        throw OpCodeExecutionError.error("OP_VERNOTIF should not be executed.")
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Lock Time/OP_CHECKLOCKTIMEVERIFY.swift
================================================
//
//  OP_CHECKLOCKTIMEVERIFY.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Marks transaction as invalid if the top stack item is greater than the transaction's nLockTime field, otherwise script evaluation continues as though an OP_NOP was executed. Transaction is also invalid if
// 1. the stack is empty; or
// 2. the top stack item is negative; or
// 3. the top stack item is greater than or equal to 500000000 while the transaction's nLockTime field is less than 500000000, or vice versa; or
// 4. the input's nSequence field is equal to 0xffffffff.
// The precise semantics are described in BIP 0065.
public struct OpCheckLockTimeVerify: OpCodeProtocol {
    public var value: UInt8 { return 0xb1 }
    public var name: String { return "OP_CHECKLOCKTIMEVERIFY " }

    // input : x
    // output : x / fail
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        // nLockTime should be Int5
        // reference: https://github.com/Bitcoin-ABC/bitcoin-abc/blob/73c5e7532e19b8f35fcf73255cd1d0df67607cd2/src/script/interpreter.cpp#L420
        let nLockTime = try context.number(at: -1)
        guard nLockTime >= 0 else {
            throw OpCodeExecutionError.error("NEGATIVE_LOCKTIME")
        }

        // checker.CheckLockTime(nLockTime)
        guard let tx = context.transaction, let txin = context.txinToVerify else {
            throw OpCodeExecutionError.error("OP_CHECKLOCKTIMEVERIFY must have a transaction in context.")
        }

        // There are two kinds of nLockTime: lock-by-blockheight and lock-by-blocktime, distinguished by whether nLockTime < LOCKTIME_THRESHOLD.
        //
        // We want to compare apples to apples, so fail the script unless the type of nLockTime being tested is the same as the nLockTime in the transaction.
        guard (tx.lockTime < BTC_LOCKTIME_THRESHOLD && nLockTime < BTC_LOCKTIME_THRESHOLD) ||
            (tx.lockTime >= BTC_LOCKTIME_THRESHOLD && nLockTime >= BTC_LOCKTIME_THRESHOLD) else {
            throw OpCodeExecutionError.error("tx.lockTime and nLockTime should be the same kind.")
        }

        guard nLockTime <= tx.lockTime  else {
            throw OpCodeExecutionError.error("The top stack item is greater than the transaction's nLockTime field")
        }

        // Finally the nLockTime feature can be disabled and thus
        // CHECKLOCKTIMEVERIFY bypassed if every txin has been finalized by setting
        // nSequence to maxint. The transaction would be allowed into the
        // blockchain, making the opcode ineffective.
        //
        // Testing if this vin is not final is sufficient to prevent this condition.
        // Alternatively we could test all inputs, but testing just this input
        // minimizes the data required to prove correct CHECKLOCKTIMEVERIFY
        // execution.
        let SEQUENCE_FINAL: UInt32 = 0xffffffff
        guard txin.sequence != SEQUENCE_FINAL else {
            throw OpCodeExecutionError.error("The input's nSequence field is equal to 0xffffffff.")
        }
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Lock Time/OP_CHECKSEQUENCEVERIFY.swift
================================================
//
//  OP_CHECKSEQUENCEVERIFY.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Marks transaction as invalid if the relative lock time of the input (enforced by BIP 0068 with nSequence) is not equal to or longer than the value of the top stack item. The precise semantics are described in BIP 0112.
public struct OpCheckSequenceVerify: OpCodeProtocol {
    public var value: UInt8 { return 0xb2 }
    public var name: String { return "OP_CHECKSEQUENCEVERIFY" }

    // input : x
    // output : x / fail
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)

        // nLockTime should be Int5
        // reference: https://github.com/Bitcoin-ABC/bitcoin-abc/blob/73c5e7532e19b8f35fcf73255cd1d0df67607cd2/src/script/interpreter.cpp#L420
        let nSequenceTmp = try context.number(at: -1)
        guard nSequenceTmp >= 0 else {
            throw OpCodeExecutionError.error("NEGATIVE_LOCKTIME")
        }
        let nSequence: UInt32 = UInt32(nSequenceTmp)

        guard let tx = context.transaction, let txin = context.txinToVerify else {
            throw OpCodeExecutionError.error("OP_CHECKLOCKTIMEVERIFY must have a transaction in context.")
        }

        let txToSequence = txin.sequence
        guard tx.version > 1 else {
            throw OpCodeExecutionError.error("Transaction's version number is not set high enough to trigger BIP 68 rules.")
        }

        let SEQUENCE_LOCKTIME_DISABLE_FLAG: UInt32 = (1 << 31)
        guard txToSequence & SEQUENCE_LOCKTIME_DISABLE_FLAG == 0 else {
            throw OpCodeExecutionError.error("SEQUENCE_LOCKTIME_DISABLE_FLAG is set.")
        }

        let SEQUENCE_LOCKTIME_TYPE_FLAG: UInt32 = (1 << 22)
        let SEQUENCE_LOCKTIME_MASK: UInt32 = 0x0000ffff
        let nLockTimeMask: UInt32 = SEQUENCE_LOCKTIME_TYPE_FLAG | SEQUENCE_LOCKTIME_MASK
        let txToSequenceMasked: UInt32 = txToSequence & nLockTimeMask
        let nSequenceMasked: UInt32 = nSequence & nLockTimeMask

        guard (txToSequenceMasked < SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked < SEQUENCE_LOCKTIME_TYPE_FLAG) ||
            (txToSequenceMasked >= SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked >= SEQUENCE_LOCKTIME_TYPE_FLAG) else {
                throw OpCodeExecutionError.error("txToSequenceMasked and nSequenceMasked should be the same kind.")
        }

        guard nSequence <= txToSequenceMasked  else {
            throw OpCodeExecutionError.error("The top stack item is greater than the transaction's nSequence field")
        }
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/OP_EXAMPLE.swift
================================================
//
//  OP_EXAMPLE.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the “Software”), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// This class should be removed when all OP_CODEs are implemented
public class OpExample: OpCodeProtocol {
    public var value: UInt8 { return 0x00 }
    public var name: String { return "OP_EXAMPLE" }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Pseudo Words/OP_INVALIDOPCODE.swift
================================================
//
//  OP_INVALIDOPCODE.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

public struct OpInvalidOpCode: OpCodeProtocol {
    public var value: UInt8 { return 0xff }
    public var name: String { return "OP_INVALIDOPCODE" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        throw OpCodeExecutionError.error("OP_INVALIDOPCODE should not be executed.")
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Pseudo Words/OP_PUBKEY.swift
================================================
//
//  OP_PUBKEY.swift
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Represents a public key hashed with OP_HASH160.
// This used internally for assisting with transaction matching. They are invalid if used in actual scripts.
public struct OpPubkey: OpCodeProtocol {
    public var value: UInt8 { return 0xfe }
    public var name: String { return "OP_PUBKEY" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        throw OpCodeExecutionError.error("OP_PUBKEY should not be executed.")
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Pseudo Words/OP_PUBKEYHASH.swift
================================================
//
//  OP_PUBKEYHASH.swift
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Represents a public key compatible with OP_CHECKSIG.
// This used internally for assisting with transaction matching. They are invalid if used in actual scripts.
public struct OpPubkeyHash: OpCodeProtocol {
    public var value: UInt8 { return 0xfd }
    public var name: String { return "OP_PUBKEYHASH" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        throw OpCodeExecutionError.error("OP_PUBKEYHASH should not be executed.")
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Push Data/OP_0.swift
================================================
//
//  OP_0.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// An empty array of bytes is pushed onto the stack.
// This is not a no-op, but is PUSHDATA op: an item is added to the stack.
//
public struct Op0: OpCodeProtocol {
    public var value: UInt8 { return 0x00 }
    public var name: String { return "OP_0" }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Push Data/OP_1NEGATE.swift
================================================
//
//  OP_1NEGATE.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// The number -1 is pushed onto the stack.
public struct Op1Negate: OpCodeProtocol {
    public var value: UInt8 { return 0x4f }
    public var name: String { return "OP_1NEGATE" }
    // input : -
    // output : -1
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.pushToStack(-1)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Push Data/OP_N.swift
================================================
//
//  OP_N.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// The number in the word name (1-16) is pushed onto the stack.
public struct OpN: OpCodeProtocol {
    public var value: UInt8 { return 0x50 + n }
    public var name: String { return "OP_\(n)" }
    private let n: UInt8
    internal init(_ n: UInt8) {
        guard (1...16).contains(n) else {
            fatalError("OP_N can be initialized with N between 1 and 16. \(n) is not valid.")
        }
        self.n = n
    }

    // input : -
    // output : n
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.pushToStack(Int32(n))
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Push Data/OP_PUSHDATA.swift
================================================
//
//  OP_PUSHDATA.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation
// Any opcode with value < PUSHDATA1 is a length of the string to be pushed on the stack.
// So opcode 0x01 is followed by 1 byte of data, 0x09 by 9 bytes and so on up to 0x4b (75 bytes)
// PUSHDATA<N> opcode is followed by N-byte length of the string that follows.

// The next 1-byte contains the number of bytes to be pushed onto the stack (allows pushing 0..255 bytes).
public struct OpPushData1: OpCodeProtocol {
    public var value: UInt8 { return 0x4c }
    public var name: String { return "OP_PUSHDATA1" }
}

// The next 2-bytes contain the number of bytes to be pushed onto the stack in little endian order (allows pushing 0..65535 bytes).
public struct OpPushData2: OpCodeProtocol {
    public var value: UInt8 { return 0x4d }
    public var name: String { return "OP_PUSHDATA2" }
}

// The next 4-bytes contain the number of bytes to be pushed onto the stack in little endian order (allows pushing 0..4294967295 bytes)
public struct OpPushData4: OpCodeProtocol {
    public var value: UInt8 { return 0x4e }
    public var name: String { return "OP_PUSHDATA4" }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Push Data/OP_RESERVED.swift
================================================
//
//  OP_RESERVED.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

public struct OpReserved: OpCodeProtocol {
    public var value: UInt8 { return 0x50 }
    public var name: String { return "OP_RESERVED" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        throw OpCodeExecutionError.error("\(name) should not be executed.")
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Reserved Words/OP_NOPN.swift
================================================
//
//  OP_NOPN.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

public struct OpNop1: OpCodeProtocol {
    public var value: UInt8 { return 0xb0 }
    public var name: String { return "OP_NOP1" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        // do nothing
    }
}

public struct OpNop4: OpCodeProtocol {
    public var value: UInt8 { return 0xb3 }
    public var name: String { return "OP_NOP4" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        // do nothing
    }
}

public struct OpNop5: OpCodeProtocol {
    public var value: UInt8 { return 0xb4 }
    public var name: String { return "OP_NOP5" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        // do nothing
    }
}

public struct OpNop6: OpCodeProtocol {
    public var value: UInt8 { return 0xb5 }
    public var name: String { return "OP_NOP6" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        // do nothing
    }
}

public struct OpNop7: OpCodeProtocol {
    public var value: UInt8 { return 0xb6 }
    public var name: String { return "OP_NOP8" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        // do nothing
    }
}

public struct OpNop8: OpCodeProtocol {
    public var value: UInt8 { return 0xb7 }
    public var name: String { return "OP_NOP8" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        // do nothing
    }
}

public struct OpNop9: OpCodeProtocol {
    public var value: UInt8 { return 0xb8 }
    public var name: String { return "OP_NOP9" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        // do nothing
    }
}

public struct OpNop10: OpCodeProtocol {
    public var value: UInt8 { return 0xb9 }
    public var name: String { return "OP_NOP10" }

    public func mainProcess(_ context: ScriptExecutionContext) throws {
        // do nothing
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Splice/OP_BIN2NUM.swift
================================================
//
//  OP_BIN2NUM.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// convert byte sequence x into a numeric value
public struct OpBin2Num: OpCodeProtocol {
    public var value: UInt8 { return 0x81 }
    public var name: String { return "OP_BIN2NUM" }

}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Splice/OP_CAT.swift
================================================
//
//  OP_CAT.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Concatenates two strings.
public struct OpConcatenate: OpCodeProtocol {
    public var value: UInt8 { return 0x7e }
    public var name: String { return "OP_CAT" }

    // input : x1 x2
    // output : out
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)
        let x1: Data = context.data(at: -2)
        let x2: Data = context.data(at: -1)
        guard x1.count + x2.count <= BTC_MAX_SCRIPT_ELEMENT_SIZE else {
            throw OpCodeExecutionError.error("Push value size limit exceeded")
        }
        context.stack.removeLast()
        context.stack.removeLast()
        context.stack.append(x1 + x2)
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Splice/OP_NUM2BIN.swift
================================================
//
//  OP_NUM2BIN.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// convert numeric value a into byte sequence of length b
public struct OpNum2Bin: OpCodeProtocol {
    public var value: UInt8 { return 0x80 }
    public var name: String { return "OP_NUM2BIN" }

}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Splice/OP_SIZE.swift
================================================
//
//  OP_SIZE.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Pushes the string length of the top element of the stack (without popping it).
public struct OpSize: OpCodeProtocol {
    public var value: UInt8 { return 0x82 }
    public var name: String { return "OP_SIZE" }

    // input : in
    // output : in size
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(1)
        let x: Data = context.data(at: -1)
        try context.pushToStack(Int32(x.count))
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Splice/OP_SPLIT.swift
================================================
//
//  OP_SPLIT.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import Foundation

// Split the operand at the given position.
public struct OpSplit: OpCodeProtocol {
    public var value: UInt8 { return 0x7f }
    public var name: String { return "OP_SPLIT" }

    // input : in position
    // output : x1 x2
    public func mainProcess(_ context: ScriptExecutionContext) throws {
        try context.assertStackHeightGreaterThanOrEqual(2)
        let data: Data = context.data(at: -2)

        // Make sure the split point is apropriate.
        let position: Int32 = try context.number(at: -1)
        guard position <= data.count else {
            throw OpCodeExecutionError.error("Invalid OP_SPLIT range")
        }

        let n1: Data = data.subdata(in: 0..<Int(position))
        let n2: Data = data.subdata(in: Int(position)..<data.count)

        // Replace existing stack values by the new values.
        context.stack[context.stack.count - 2] = n1
        context.stack[context.stack.count - 1] = n2
    }
}


================================================
FILE: HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_2DROP.swift
================================================
//
//  OP_2DROP.swift
//
//  Copyright © 2018 BitcoinKit developers
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  c
Download .txt
gitextract_m1rg5mwu/

├── .codecov.yml
├── .gitignore
├── .swiftlint.yml
├── .travis.yml
├── Cartfile
├── HDWalletKit/
│   ├── Core/
│   │   ├── BigInt/
│   │   │   ├── BigInt+Extension.swift
│   │   │   ├── BigNumber.swift
│   │   │   └── SMP.swift
│   │   ├── BitcoinScript/
│   │   │   ├── OP_CODE/
│   │   │   │   ├── Arithmetic/
│   │   │   │   │   ├── OP_0NOTEQUAL.swift
│   │   │   │   │   ├── OP_1ADD.swift
│   │   │   │   │   ├── OP_1SUB.swift
│   │   │   │   │   ├── OP_2DIV.swift
│   │   │   │   │   ├── OP_2MUL.swift
│   │   │   │   │   ├── OP_ABS.swift
│   │   │   │   │   ├── OP_ADD.swift
│   │   │   │   │   ├── OP_BOOLAND.swift
│   │   │   │   │   ├── OP_BOOLOR.swift
│   │   │   │   │   ├── OP_DIV.swift
│   │   │   │   │   ├── OP_GREATERTHAN.swift
│   │   │   │   │   ├── OP_GREATERTHANOREQUAL.swift
│   │   │   │   │   ├── OP_LESSTHAN.swift
│   │   │   │   │   ├── OP_LESSTHANOREQUAL.swift
│   │   │   │   │   ├── OP_LSHIFT.swift
│   │   │   │   │   ├── OP_MAX.swift
│   │   │   │   │   ├── OP_MIN.swift
│   │   │   │   │   ├── OP_MOD.swift
│   │   │   │   │   ├── OP_MUL.swift
│   │   │   │   │   ├── OP_NEGATE.swift
│   │   │   │   │   ├── OP_NOT.swift
│   │   │   │   │   ├── OP_NUMEQUAL.swift
│   │   │   │   │   ├── OP_NUMEQUALVERIFY.swift
│   │   │   │   │   ├── OP_NUMNOTEQUAL.swift
│   │   │   │   │   ├── OP_RSHIFT.swift
│   │   │   │   │   ├── OP_SUB.swift
│   │   │   │   │   └── OP_WITHIN.swift
│   │   │   │   ├── Bitwise Logic/
│   │   │   │   │   ├── OP_AND.swift
│   │   │   │   │   ├── OP_EQUAL.swift
│   │   │   │   │   ├── OP_EQUALVERIFY.swift
│   │   │   │   │   ├── OP_INVERT.swift
│   │   │   │   │   ├── OP_OR.swift
│   │   │   │   │   ├── OP_RESERVED1.swift
│   │   │   │   │   ├── OP_RESERVED2.swift
│   │   │   │   │   └── OP_XOR.swift
│   │   │   │   ├── Crypto/
│   │   │   │   │   ├── OP_CHECKMULTISIG.swift
│   │   │   │   │   ├── OP_CHECKMULTISIGVERIFY.swift
│   │   │   │   │   ├── OP_CHECKSIG.swift
│   │   │   │   │   ├── OP_CHECKSIGVERIFY.swift
│   │   │   │   │   ├── OP_CODESEPARATOR.swift
│   │   │   │   │   ├── OP_HASH160.swift
│   │   │   │   │   ├── OP_HASH256.swift
│   │   │   │   │   ├── OP_RIPEMD160.swift
│   │   │   │   │   ├── OP_SHA1.swift
│   │   │   │   │   └── OP_SHA256.swift
│   │   │   │   ├── Flow Control/
│   │   │   │   │   ├── OP_ELSE.swift
│   │   │   │   │   ├── OP_ENDIF.swift
│   │   │   │   │   ├── OP_IF.swift
│   │   │   │   │   ├── OP_NOP.swift
│   │   │   │   │   ├── OP_NOTIF.swift
│   │   │   │   │   ├── OP_RETURN.swift
│   │   │   │   │   ├── OP_VER.swift
│   │   │   │   │   ├── OP_VERIF.swift
│   │   │   │   │   ├── OP_VERIFY.swift
│   │   │   │   │   └── OP_VERNOTIF.swift
│   │   │   │   ├── Lock Time/
│   │   │   │   │   ├── OP_CHECKLOCKTIMEVERIFY.swift
│   │   │   │   │   └── OP_CHECKSEQUENCEVERIFY.swift
│   │   │   │   ├── OP_EXAMPLE.swift
│   │   │   │   ├── Pseudo Words/
│   │   │   │   │   ├── OP_INVALIDOPCODE.swift
│   │   │   │   │   ├── OP_PUBKEY.swift
│   │   │   │   │   └── OP_PUBKEYHASH.swift
│   │   │   │   ├── Push Data/
│   │   │   │   │   ├── OP_0.swift
│   │   │   │   │   ├── OP_1NEGATE.swift
│   │   │   │   │   ├── OP_N.swift
│   │   │   │   │   ├── OP_PUSHDATA.swift
│   │   │   │   │   └── OP_RESERVED.swift
│   │   │   │   ├── Reserved Words/
│   │   │   │   │   └── OP_NOPN.swift
│   │   │   │   ├── Splice/
│   │   │   │   │   ├── OP_BIN2NUM.swift
│   │   │   │   │   ├── OP_CAT.swift
│   │   │   │   │   ├── OP_NUM2BIN.swift
│   │   │   │   │   ├── OP_SIZE.swift
│   │   │   │   │   └── OP_SPLIT.swift
│   │   │   │   └── Stack/
│   │   │   │       ├── OP_2DROP.swift
│   │   │   │       ├── OP_2DUP.swift
│   │   │   │       ├── OP_2OVER.swift
│   │   │   │       ├── OP_2ROT.swift
│   │   │   │       ├── OP_2SWAP.swift
│   │   │   │       ├── OP_3DUP.swift
│   │   │   │       ├── OP_DEPTH.swift
│   │   │   │       ├── OP_DROP.swift
│   │   │   │       ├── OP_DUP.swift
│   │   │   │       ├── OP_FROMALTSTACK.swift
│   │   │   │       ├── OP_IFDUP.swift
│   │   │   │       ├── OP_NIP.swift
│   │   │   │       ├── OP_OVER.swift
│   │   │   │       ├── OP_PICK.swift
│   │   │   │       ├── OP_ROLL.swift
│   │   │   │       ├── OP_ROT.swift
│   │   │   │       ├── OP_SWAP.swift
│   │   │   │       ├── OP_TOTALSTACK.swift
│   │   │   │       └── OP_TUCK.swift
│   │   │   ├── OpCodeFactory.swift
│   │   │   ├── OpCodeProtocol.swift
│   │   │   ├── Opcode.swift
│   │   │   ├── Script.swift
│   │   │   ├── ScriptChunk.swift
│   │   │   ├── ScriptChunkHelper.swift
│   │   │   ├── ScriptExecutionContext.swift
│   │   │   ├── ScriptFactory.swift
│   │   │   └── ScriptMachine.swift
│   │   ├── ByteStream.swift
│   │   ├── Converter/
│   │   │   └── WeiEthterConverter.swift
│   │   ├── Crypto/
│   │   │   ├── Encryption/
│   │   │   │   ├── Crypto.swift
│   │   │   │   ├── ECDSA.swift
│   │   │   │   ├── EIP155Signer.swift
│   │   │   │   ├── EllipticCurveEncrypterSecp256k1.swift
│   │   │   │   └── SecpResult.swift
│   │   │   └── Hash/
│   │   │       └── RIPEMD160.swift
│   │   ├── DataConvertable.swift
│   │   ├── DerivationNode.swift
│   │   ├── Encodeing/
│   │   │   ├── Base58Encode.swift
│   │   │   ├── Bech32.swift
│   │   │   ├── EIP55.swift
│   │   │   └── RLP.swift
│   │   ├── Error/
│   │   │   └── HDWalletKitError.swift
│   │   ├── Extensions/
│   │   │   ├── Data+Random.swift
│   │   │   ├── Data+Script.swift
│   │   │   └── String+Hex.swift
│   │   ├── Typealiaces.swift
│   │   ├── VarInt.swift
│   │   └── VarString.swift
│   ├── Keystore/
│   │   ├── KeystoreInterface.swift
│   │   ├── KeystoreV3.swift
│   │   └── KeystoreV3Json.swift
│   ├── Mnemonic/
│   │   ├── Mnemonic.swift
│   │   └── WordList.swift
│   ├── Models/
│   │   └── Account.swift
│   └── Wallet/
│       ├── AccountBased/
│       │   ├── ERC20/
│       │   │   └── ERC20.swift
│       │   └── Ethereum/
│       │       └── Model/
│       │           ├── EthereumAddress.swift
│       │           └── EthereumRawTransaction.swift
│       ├── Coin.swift
│       ├── PrivateKey.swift
│       ├── PublicKey.swift
│       ├── UTXOBased/
│       │   ├── Bitcoin/
│       │   │   ├── BitcoinAddress.swift
│       │   │   ├── BitcoinTransactionSignatureSerializer.swift
│       │   │   └── Transaction+SignatureHash.swift
│       │   ├── BitcoinCash/
│       │   │   ├── BitcoinCashAddress.swift
│       │   │   └── BitcoinCashVersionByte.swift
│       │   ├── Constants/
│       │   │   ├── SighashType.swift
│       │   │   └── UtilsAndLimits.swift
│       │   ├── Default/
│       │   │   ├── UtxoSelector.swift
│       │   │   ├── UtxoTransactionBuilder.swift
│       │   │   └── UtxoTransactionSigner.swift
│       │   ├── Model/
│       │   │   ├── TransactionInput.swift
│       │   │   ├── UnsignedTransaction.swift
│       │   │   └── UnspendTransaction/
│       │   │       ├── TransactionOutPoint.swift
│       │   │       ├── TransactionOutput.swift
│       │   │       └── UnspendTransaction.swift
│       │   ├── Protocols/
│       │   │   ├── UtxoSelectorInterface.swift
│       │   │   ├── UtxoTransactionBuilderInterface.swift
│       │   │   └── UtxoTransactionSignerInterface.swift
│       │   ├── Transaction.swift
│       │   ├── UTXOWallet.swift
│       │   └── UtxoPrivateKeyType.swift
│       └── Wallet.swift
├── HDWalletKit.podspec
├── HDWalletKit.xcodeproj/
│   ├── project.pbxproj
│   └── xcshareddata/
│       └── xcschemes/
│           ├── HDWalletKit.xcscheme
│           └── HDWalletKit_Tests.xcscheme
├── HDWalletKit_Tests/
│   ├── AddressGenerationTests.swift
│   ├── ConverterTests.swift
│   ├── CryptoTests.swift
│   ├── ERC20Tests.swift
│   ├── ImportWalletTests.swift
│   ├── Info.plist
│   ├── KeystoreTests.swift
│   ├── MnemonicTests.swift
│   ├── PrivateKeyTests.swift
│   ├── RIPEMD160Tests.swift
│   ├── Secp256k1Tets.swift
│   ├── SignTransactionTests.swift
│   └── UTXO/
│       └── UTXOSign.swift
├── LICENSE.md
├── Podfile
├── README.md
└── scripts/
    └── coverage.rb
Condensed preview — 184 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (865K chars).
[
  {
    "path": ".codecov.yml",
    "chars": 32,
    "preview": "ignore:\n  - \"**/WordList.swift\"\n"
  },
  {
    "path": ".gitignore",
    "chars": 1473,
    "preview": "# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n"
  },
  {
    "path": ".swiftlint.yml",
    "chars": 71,
    "preview": "disabled_rules:\n - trailing_whitespace\nexcluded: \n  - Carthage\n  - Pods"
  },
  {
    "path": ".travis.yml",
    "chars": 576,
    "preview": "language: \n  - objective-c\nosx_image: \n  - xcode10.2.1\nbefore_install:\n   - gem update cocoapods --pre\n   - pod update\ni"
  },
  {
    "path": "Cartfile",
    "chars": 71,
    "preview": "github \"Boilertalk/secp256k1.swift\"\ngithub \"krzyzanowskim/CryptoSwift\"\n"
  },
  {
    "path": "HDWalletKit/Core/BigInt/BigInt+Extension.swift",
    "chars": 2645,
    "preview": "//\n//  BigInt+Extension.swift\n//  WalletKit\n//\n//  Created by yuzushioh on 2018/01/24.\n//  Copyright © 2018 yuzushioh. A"
  },
  {
    "path": "HDWalletKit/Core/BigInt/BigNumber.swift",
    "chars": 2368,
    "preview": "//\n//  BigNumber.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 1/6/19.\n//  Copyright © 2019 Essentia. All right"
  },
  {
    "path": "HDWalletKit/Core/BigInt/SMP.swift",
    "chars": 60522,
    "preview": "//\n//    ————————————————————————————————————————————————————————————————————————————————————————————\n//    ||||||||||||"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_0NOTEQUAL.swift",
    "chars": 1673,
    "preview": "//\n//  OP_0NOTEQUAL.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of cha"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_1ADD.swift",
    "chars": 1625,
    "preview": "//\n//  OP_1ADD.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_1SUB.swift",
    "chars": 1631,
    "preview": "//\n//  OP_1SUB.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_2DIV.swift",
    "chars": 1703,
    "preview": "//\n//  OP_2DIV.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_2MUL.swift",
    "chars": 1706,
    "preview": "//\n//  OP_2MUL.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_ABS.swift",
    "chars": 1644,
    "preview": "//\n//  OP_ABS.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_ADD.swift",
    "chars": 1688,
    "preview": "//\n//  OP_ADD.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_BOOLAND.swift",
    "chars": 1798,
    "preview": "//\n//  OP_BOOLAND.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charg"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_BOOLOR.swift",
    "chars": 1788,
    "preview": "//\n//  OP_BOOLOR.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_DIV.swift",
    "chars": 1835,
    "preview": "//\n//  OP_DIV.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_GREATERTHAN.swift",
    "chars": 1744,
    "preview": "//\n//  OP_GREATERTHAN.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of c"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_GREATERTHANOREQUAL.swift",
    "chars": 1778,
    "preview": "//\n//  OP_GREATERTHANOREQUAL.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, fr"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_LESSTHAN.swift",
    "chars": 1732,
    "preview": "//\n//  OP_LESSTHAN.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of char"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_LESSTHANOREQUAL.swift",
    "chars": 1766,
    "preview": "//\n//  OP_LESSTHANOREQUAL.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_LSHIFT.swift",
    "chars": 1775,
    "preview": "//\n//  OP_LSHIFT.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_MAX.swift",
    "chars": 1711,
    "preview": "//\n//  OP_MAX.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_MIN.swift",
    "chars": 1711,
    "preview": "//\n//  OP_MIN.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_MOD.swift",
    "chars": 1834,
    "preview": "//\n//  OP_MOD.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_MUL.swift",
    "chars": 1763,
    "preview": "//\n//  OP_MUL.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_NEGATE.swift",
    "chars": 1661,
    "preview": "//\n//  OP_NEGATE.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_NOT.swift",
    "chars": 1651,
    "preview": "//\n//  OP_NOT.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_NUMEQUAL.swift",
    "chars": 1736,
    "preview": "//\n//  OP_NUMEQUAL.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of char"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_NUMEQUALVERIFY.swift",
    "chars": 1744,
    "preview": "//\n//  OP_NUMEQUALVERIFY.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free o"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_NUMNOTEQUAL.swift",
    "chars": 1748,
    "preview": "//\n//  OP_NUMNOTEQUAL.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of c"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_RSHIFT.swift",
    "chars": 1775,
    "preview": "//\n//  OP_RSHIFT.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_SUB.swift",
    "chars": 1688,
    "preview": "//\n//  OP_SUB.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Arithmetic/OP_WITHIN.swift",
    "chars": 1873,
    "preview": "//\n//  OP_WITHIN.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_AND.swift",
    "chars": 1976,
    "preview": "//\n//  OP_AND.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_EQUAL.swift",
    "chars": 1719,
    "preview": "//\n//  OP_EQUAL.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge,"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_EQUALVERIFY.swift",
    "chars": 1727,
    "preview": "//\n//  OP_EQUALVERIFY.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of c"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_INVERT.swift",
    "chars": 1745,
    "preview": "//\n//  OP_INVERT.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_OR.swift",
    "chars": 1972,
    "preview": "//\n//  OP_OR.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, to"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_RESERVED1.swift",
    "chars": 1484,
    "preview": "//\n//  OP_RESERVED1.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of cha"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_RESERVED2.swift",
    "chars": 1484,
    "preview": "//\n//  OP_RESERVED2.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of cha"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Bitwise Logic/OP_XOR.swift",
    "chars": 1985,
    "preview": "//\n//  OP_XOR.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_CHECKMULTISIG.swift",
    "chars": 4973,
    "preview": "//\n//  OP_CHECKMULTISIG.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_CHECKMULTISIGVERIFY.swift",
    "chars": 1855,
    "preview": "//\n//  OP_CHECKMULTISIGVERIFY.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, f"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_CHECKSIG.swift",
    "chars": 2263,
    "preview": "//\n//  OP_CHECKSIG.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of char"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_CHECKSIGVERIFY.swift",
    "chars": 1763,
    "preview": "//\n//  OP_CHECKSIGVERIFY.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free o"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_CODESEPARATOR.swift",
    "chars": 559,
    "preview": "//\n//  OP_CODESEPARATOR.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/09.\n//  Copyright © 2018 BitcoinKit"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_HASH160.swift",
    "chars": 1713,
    "preview": "//\n//  OP_HASH160.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charg"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_HASH256.swift",
    "chars": 666,
    "preview": "//\n//  OP_HASH256.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/09.\n//  Copyright © 2018 BitcoinKit devel"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_RIPEMD160.swift",
    "chars": 669,
    "preview": "//\n//  OP_RIPEMD160.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/09.\n//  Copyright © 2018 BitcoinKit dev"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_SHA1.swift",
    "chars": 659,
    "preview": "//\n//  OP_SHA1.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/09.\n//  Copyright © 2018 BitcoinKit develope"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Crypto/OP_SHA256.swift",
    "chars": 651,
    "preview": "//\n//  OP_SHA256.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/09.\n//  Copyright © 2018 BitcoinKit develo"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_ELSE.swift",
    "chars": 639,
    "preview": "//\n//  OP_ELSE.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/08.\n//  Copyright © 2018 BitcoinKit develope"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_ENDIF.swift",
    "chars": 593,
    "preview": "//\n//  OP_ENDIF.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/08.\n//  Copyright © 2018 BitcoinKit develop"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_IF.swift",
    "chars": 640,
    "preview": "//\n//  OP_IF.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/08.\n//  Copyright © 2018 BitcoinKit developers"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_NOP.swift",
    "chars": 414,
    "preview": "//\n//  OP_NOP.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/08.\n//  Copyright © 2018 BitcoinKit developer"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_NOTIF.swift",
    "chars": 650,
    "preview": "//\n//  OP_NOTIF.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/08.\n//  Copyright © 2018 BitcoinKit develop"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_RETURN.swift",
    "chars": 1470,
    "preview": "//\n//  OP_RETURN.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_VER.swift",
    "chars": 453,
    "preview": "//\n//  OP_VER.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/08.\n//  Copyright © 2018 BitcoinKit developer"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_VERIF.swift",
    "chars": 533,
    "preview": "//\n//  OP_VERIF.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/08.\n//  Copyright © 2018 BitcoinKit develop"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_VERIFY.swift",
    "chars": 1760,
    "preview": "//\n//  OP_VERIFY.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Flow Control/OP_VERNOTIF.swift",
    "chars": 473,
    "preview": "//\n//  OP_VERNOTIF.swift\n//  BitcoinKit\n//\n//  Created by Shun Usami on 2018/08/08.\n//  Copyright © 2018 BitcoinKit deve"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Lock Time/OP_CHECKLOCKTIMEVERIFY.swift",
    "chars": 4215,
    "preview": "//\n//  OP_CHECKLOCKTIMEVERIFY.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, f"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Lock Time/OP_CHECKSEQUENCEVERIFY.swift",
    "chars": 3697,
    "preview": "//\n//  OP_CHECKSEQUENCEVERIFY.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, f"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/OP_EXAMPLE.swift",
    "chars": 1388,
    "preview": "//\n//  OP_EXAMPLE.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charg"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Pseudo Words/OP_INVALIDOPCODE.swift",
    "chars": 1505,
    "preview": "//\n//  OP_INVALIDOPCODE.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Pseudo Words/OP_PUBKEY.swift",
    "chars": 1591,
    "preview": "//\n//  OP_PUBKEY.swift\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this s"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Pseudo Words/OP_PUBKEYHASH.swift",
    "chars": 1612,
    "preview": "//\n//  OP_PUBKEYHASH.swift\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of th"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Push Data/OP_0.swift",
    "chars": 1436,
    "preview": "//\n//  OP_0.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, to "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Push Data/OP_1NEGATE.swift",
    "chars": 1516,
    "preview": "//\n//  OP_1NEGATE.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charg"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Push Data/OP_N.swift",
    "chars": 1760,
    "preview": "//\n//  OP_N.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, to "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Push Data/OP_PUSHDATA.swift",
    "chars": 2259,
    "preview": "//\n//  OP_PUSHDATA.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of char"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Push Data/OP_RESERVED.swift",
    "chars": 1481,
    "preview": "//\n//  OP_RESERVED.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of char"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Reserved Words/OP_NOPN.swift",
    "chars": 3069,
    "preview": "//\n//  OP_NOPN.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Splice/OP_BIN2NUM.swift",
    "chars": 1372,
    "preview": "//\n//  OP_BIN2NUM.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charg"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Splice/OP_CAT.swift",
    "chars": 1884,
    "preview": "//\n//  OP_CAT.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Splice/OP_NUM2BIN.swift",
    "chars": 1382,
    "preview": "//\n//  OP_NUM2BIN.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charg"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Splice/OP_SIZE.swift",
    "chars": 1667,
    "preview": "//\n//  OP_SIZE.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Splice/OP_SPLIT.swift",
    "chars": 2122,
    "preview": "//\n//  OP_SPLIT.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge,"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_2DROP.swift",
    "chars": 1606,
    "preview": "//\n//  OP_2DROP.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge,"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_2DUP.swift",
    "chars": 1706,
    "preview": "//\n//  OP_2DUP.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_2OVER.swift",
    "chars": 1741,
    "preview": "//\n//  OP_2OVER.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge,"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_2ROT.swift",
    "chars": 1849,
    "preview": "//\n//  OP_2ROT.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_2SWAP.swift",
    "chars": 1629,
    "preview": "//\n//  OP_2SWAP.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge,"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_3DUP.swift",
    "chars": 1797,
    "preview": "//\n//  OP_3DUP.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_DEPTH.swift",
    "chars": 1589,
    "preview": "//\n//  OP_DEPTH.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge,"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_DROP.swift",
    "chars": 1559,
    "preview": "//\n//  OP_DROP.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_DUP.swift",
    "chars": 1604,
    "preview": "//\n//  OP_DUP.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_FROMALTSTACK.swift",
    "chars": 1684,
    "preview": "//\n//  OP_FROMALTSTACK.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_IFDUP.swift",
    "chars": 1649,
    "preview": "//\n//  OP_IFDUP.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge,"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_NIP.swift",
    "chars": 1619,
    "preview": "//\n//  OP_NIP.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_OVER.swift",
    "chars": 1624,
    "preview": "//\n//  OP_OVER.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_PICK.swift",
    "chars": 1976,
    "preview": "//\n//  OP_PICK.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_ROLL.swift",
    "chars": 2032,
    "preview": "//\n//  OP_ROLL.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_ROT.swift",
    "chars": 1641,
    "preview": "//\n//  OP_ROT.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_SWAP.swift",
    "chars": 1583,
    "preview": "//\n//  OP_SWAP.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_TOTALSTACK.swift",
    "chars": 1675,
    "preview": "//\n//  OP_TOALTSTACK.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of ch"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OP_CODE/Stack/OP_TUCK.swift",
    "chars": 1723,
    "preview": "//\n//  OP_TUCK.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, "
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OpCodeFactory.swift",
    "chars": 3444,
    "preview": "//\n//  OpCodeFactory.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of ch"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/OpCodeProtocol.swift",
    "chars": 4832,
    "preview": "//\n//  OpCodeProtocol.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of c"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/Opcode.swift",
    "chars": 23166,
    "preview": "//\n//  OpCode.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/Script.swift",
    "chars": 16111,
    "preview": "//\n//  Script.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of charge, t"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/ScriptChunk.swift",
    "chars": 7076,
    "preview": "//\n//  ScriptChunk.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of char"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/ScriptChunkHelper.swift",
    "chars": 6322,
    "preview": "//\n//  ScriptChunkHelper.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free o"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/ScriptExecutionContext.swift",
    "chars": 7669,
    "preview": "//\n//  ScriptExecutionContext.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, f"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/ScriptFactory.swift",
    "chars": 8255,
    "preview": "//\n//  ScriptFactory.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of ch"
  },
  {
    "path": "HDWalletKit/Core/BitcoinScript/ScriptMachine.swift",
    "chars": 5599,
    "preview": "//\n//  ScriptMachine.swift\n//\n//  Copyright © 2018 BitcoinKit developers\n//\n//  Permission is hereby granted, free of ch"
  },
  {
    "path": "HDWalletKit/Core/ByteStream.swift",
    "chars": 1882,
    "preview": "//\n//  ByteStream.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 1/6/19.\n//  Copyright © 2019 Essentia. All righ"
  },
  {
    "path": "HDWalletKit/Core/Converter/WeiEthterConverter.swift",
    "chars": 1799,
    "preview": "//\n//  WeiEthterConverter.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 10/10/18.\n//  Copyright © 2018 Essentia"
  },
  {
    "path": "HDWalletKit/Core/Crypto/Encryption/Crypto.swift",
    "chars": 2840,
    "preview": "//\n//  Crypto.swift\n//  WalletKit\n//\n//  Created by yuzushioh on 2018/02/06.\n//  Copyright © 2018 yuzushioh. All rights "
  },
  {
    "path": "HDWalletKit/Core/Crypto/Encryption/ECDSA.swift",
    "chars": 2431,
    "preview": "//\n//  ECDSA.swift\n//  ECDSA\n//\n//  Created by yuzushioh on 2018/01/25.\n//  Copyright © 2018 yuzushioh. All rights reser"
  },
  {
    "path": "HDWalletKit/Core/Crypto/Encryption/EIP155Signer.swift",
    "chars": 2793,
    "preview": "import CryptoSwift\n\npublic struct EIP155Signer {\n    \n    public init(chainId: Int) {\n        self.chainId = chainId\n   "
  },
  {
    "path": "HDWalletKit/Core/Crypto/Encryption/EllipticCurveEncrypterSecp256k1.swift",
    "chars": 5235,
    "preview": "//\n//  EllipticCurveEncrypterSecp256k1.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 12.07.18.\n//  Copyright © "
  },
  {
    "path": "HDWalletKit/Core/Crypto/Encryption/SecpResult.swift",
    "chars": 373,
    "preview": "//\n//  SecpResult.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 13.07.18.\n//  Copyright © 2018 Essentia. All ri"
  },
  {
    "path": "HDWalletKit/Core/Crypto/Hash/RIPEMD160.swift",
    "chars": 14645,
    "preview": "//\n//  RIPEMD160.swift\n//  WalletKit\n//\n//  Created by yuzushioh on 2018/02/04.\n//  Copyright © 2018 yuzushioh. All righ"
  },
  {
    "path": "HDWalletKit/Core/DataConvertable.swift",
    "chars": 660,
    "preview": "//\n//  DataConvertable.swift\n//  WalletKit\n//\n//  Created by yuzushioh on 2018/02/11.\n//  Copyright © 2018 yuzushioh. Al"
  },
  {
    "path": "HDWalletKit/Core/DerivationNode.swift",
    "chars": 567,
    "preview": "//\n//  DerivationNode.swift\n//  CryptoSwift\n//\n//  Created by Pavlo Boiko on 02.07.18.\n//\n\nimport Foundation\n\npublic enu"
  },
  {
    "path": "HDWalletKit/Core/Encodeing/Base58Encode.swift",
    "chars": 3287,
    "preview": "//\n//  Base58Encode.swift\n//  WalletKit\n//\n//  Created by yuzushioh on 2018/02/11.\n//  Copyright © 2018 yuzushioh. All r"
  },
  {
    "path": "HDWalletKit/Core/Encodeing/Bech32.swift",
    "chars": 9142,
    "preview": "//\n//  Bech58.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 2/5/19.\n//  Copyright © 2019 Essentia. All rights r"
  },
  {
    "path": "HDWalletKit/Core/Encodeing/EIP55.swift",
    "chars": 948,
    "preview": "//\n//  EIP55.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 28.06.18.\n//\n\nimport CryptoSwift\n\n// NOTE: https://g"
  },
  {
    "path": "HDWalletKit/Core/Encodeing/RLP.swift",
    "chars": 4472,
    "preview": "import Foundation\n\npublic struct RLP {\n    public static func encode(_ element: Any) throws -> Data {\n        let encode"
  },
  {
    "path": "HDWalletKit/Core/Error/HDWalletKitError.swift",
    "chars": 675,
    "preview": "//\n//  HDWalletKitError.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 12.07.18.\n//  Copyright © 2018 Essentia. "
  },
  {
    "path": "HDWalletKit/Core/Extensions/Data+Random.swift",
    "chars": 404,
    "preview": "//\n//  Data+Random.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 20.08.18.\n//  Copyright © 2018 Essentia. All r"
  },
  {
    "path": "HDWalletKit/Core/Extensions/Data+Script.swift",
    "chars": 2764,
    "preview": "//\n//  Data+Script.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 1/4/19.\n//  Copyright © 2019 Essentia. All rig"
  },
  {
    "path": "HDWalletKit/Core/Extensions/String+Hex.swift",
    "chars": 1575,
    "preview": "//\n//  String+Hex.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 12.07.18.\n//  Copyright © 2018 Essentia. All ri"
  },
  {
    "path": "HDWalletKit/Core/Typealiaces.swift",
    "chars": 220,
    "preview": "//\n//  Typealiaces.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 12.07.18.\n//  Copyright © 2018 Essentia. All r"
  },
  {
    "path": "HDWalletKit/Core/VarInt.swift",
    "chars": 1792,
    "preview": "//\n//  VarInt.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 1/6/19.\n//  Copyright © 2019 Essentia. All rights r"
  },
  {
    "path": "HDWalletKit/Core/VarString.swift",
    "chars": 909,
    "preview": "//\n//  VarString.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 1/6/19.\n//  Copyright © 2019 Essentia. All right"
  },
  {
    "path": "HDWalletKit/Keystore/KeystoreInterface.swift",
    "chars": 581,
    "preview": "//\n//  KeystoreInterface.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 20.08.18.\n//  Copyright © 2018 Essentia."
  },
  {
    "path": "HDWalletKit/Keystore/KeystoreV3.swift",
    "chars": 5809,
    "preview": "//\n//  KeystoreV3.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 20.08.18.\n//  Copyright © 2018 Essentia. All ri"
  },
  {
    "path": "HDWalletKit/Keystore/KeystoreV3Json.swift",
    "chars": 1108,
    "preview": "//\n//  KeystoreV3Json.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 19.08.18.\n//  Copyright © 2018 Essentia. Al"
  },
  {
    "path": "HDWalletKit/Mnemonic/Mnemonic.swift",
    "chars": 2168,
    "preview": "//\n//  Mnemonic.swift\n//  WalletKit\n//\n//  Created by yuzushioh on 2018/02/11.\n//  Copyright © 2018 yuzushioh. All right"
  },
  {
    "path": "HDWalletKit/Mnemonic/WordList.swift",
    "chars": 142030,
    "preview": "\n//\n//  WordList.swift\n//  WalletKit\n//\n//  Created by yuzushioh on 2018/01/01.\n//  Copyright © 2018 yuzushioh. All righ"
  },
  {
    "path": "HDWalletKit/Models/Account.swift",
    "chars": 523,
    "preview": "//\n//  Account.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 04.07.18.\n//\n\nimport Foundation\n\npublic struct Acc"
  },
  {
    "path": "HDWalletKit/Wallet/AccountBased/ERC20/ERC20.swift",
    "chars": 4019,
    "preview": "//\n//  ERC20.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 24.09.18.\n//  Copyright © 2018 Essentia. All rights "
  },
  {
    "path": "HDWalletKit/Wallet/AccountBased/Ethereum/Model/EthereumAddress.swift",
    "chars": 722,
    "preview": "//\n//  Address.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 12.07.18.\n//  Copyright © 2018 Essentia. All right"
  },
  {
    "path": "HDWalletKit/Wallet/AccountBased/Ethereum/Model/EthereumRawTransaction.swift",
    "chars": 1065,
    "preview": "import Foundation\n/// RawTransaction constructs necessary information to publish transaction.\npublic struct EthereumRawT"
  },
  {
    "path": "HDWalletKit/Wallet/Coin.swift",
    "chars": 2915,
    "preview": "//\n//  Coin.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 10/3/18.\n//  Copyright © 2018 Essentia. All rights re"
  },
  {
    "path": "HDWalletKit/Wallet/PrivateKey.swift",
    "chars": 4206,
    "preview": "//\n//  PrivateKey.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 10/4/18.\n//  Copyright © 2018 Essentia. All rig"
  },
  {
    "path": "HDWalletKit/Wallet/PublicKey.swift",
    "chars": 2548,
    "preview": "//\n//  PublicKey.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 10/4/18.\n//  Copyright © 2018 Essentia. All righ"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Bitcoin/BitcoinAddress.swift",
    "chars": 2174,
    "preview": "//\n//  BitcoinAddress.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 1/8/19.\n//  Copyright © 2019 Essentia. All "
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Bitcoin/BitcoinTransactionSignatureSerializer.swift",
    "chars": 2730,
    "preview": "//\n//  BitcoinTransactionSignatureSerializer.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 2/5/19.\n//  Copyrigh"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Bitcoin/Transaction+SignatureHash.swift",
    "chars": 4952,
    "preview": "//\n//  Transaction+SignatureHash.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 2/5/19.\n//  Copyright © 2019 Ess"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/BitcoinCash/BitcoinCashAddress.swift",
    "chars": 1535,
    "preview": "//\n//  BitcoinCashAddress.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 5/1/19.\n//  Copyright © 2019 Essentia. "
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/BitcoinCash/BitcoinCashVersionByte.swift",
    "chars": 1855,
    "preview": "//\n//  BitcoinCashVersionByte.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 1/8/19.\n//  Copyright © 2019 Essent"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Constants/SighashType.swift",
    "chars": 2955,
    "preview": "//\n//  SighashType.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 1/7/19.\n//  Copyright © 2019 Essentia. All rig"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Constants/UtilsAndLimits.swift",
    "chars": 874,
    "preview": "//\n//  UtilsAndLimits.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 1/6/19.\n//  Copyright © 2019 Essentia. All "
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Default/UtxoSelector.swift",
    "chars": 3893,
    "preview": "//\n//  UtxoSelector.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 2/12/19.\n//  Copyright © 2019 Essentia. All r"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Default/UtxoTransactionBuilder.swift",
    "chars": 1142,
    "preview": "//\n//  UtxoTransactionBuilder.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 2/17/19.\n//  Copyright © 2019 Essen"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Default/UtxoTransactionSigner.swift",
    "chars": 1731,
    "preview": "//\n//  UtxoTransactionSigner.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 2/19/19.\n//  Copyright © 2019 Essent"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Model/TransactionInput.swift",
    "chars": 1869,
    "preview": "//\n//  BitcoinTransactionInput.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 1/7/19.\n//  Copyright © 2019 Essen"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Model/UnsignedTransaction.swift",
    "chars": 401,
    "preview": "//\n//  UnsignedTransaction.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 2/17/19.\n//  Copyright © 2019 Essentia"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Model/UnspendTransaction/TransactionOutPoint.swift",
    "chars": 934,
    "preview": "//\n//  BitcoinTransactionOutPoint.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 12/28/18.\n//  Copyright © 2018 "
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Model/UnspendTransaction/TransactionOutput.swift",
    "chars": 1462,
    "preview": "//\n//  BitcoinTransactionOutput.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 12/28/18.\n//  Copyright © 2018 Es"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Model/UnspendTransaction/UnspendTransaction.swift",
    "chars": 438,
    "preview": "//\n//  UnspendTransaction.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 12/28/18.\n//  Copyright © 2018 Essentia"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Protocols/UtxoSelectorInterface.swift",
    "chars": 325,
    "preview": "//\n//  UTXOSelector.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 2/19/19.\n//  Copyright © 2019 Essentia. All r"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Protocols/UtxoTransactionBuilderInterface.swift",
    "chars": 347,
    "preview": "//\n//  UtxoTransactionBuilder.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 2/19/19.\n//  Copyright © 2019 Essen"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Protocols/UtxoTransactionSignerInterface.swift",
    "chars": 321,
    "preview": "//\n//  UtxoTransactionSigner.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 2/19/19.\n//  Copyright © 2019 Essent"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/Transaction.swift",
    "chars": 3066,
    "preview": "//\n//  BitcoinTransaction.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 1/8/19.\n//  Copyright © 2019 Essentia. "
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/UTXOWallet.swift",
    "chars": 2044,
    "preview": "//\n//  UTXOWallet.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 2/19/19.\n//  Copyright © 2019 Essentia. All rig"
  },
  {
    "path": "HDWalletKit/Wallet/UTXOBased/UtxoPrivateKeyType.swift",
    "chars": 2415,
    "preview": "//\n//  UtxoPrivateKeyType.swift\n//  HDWalletKit\n//\n//  Created by Pavlo Boiko on 4/17/19.\n//  Copyright © 2019 Essentia."
  },
  {
    "path": "HDWalletKit/Wallet/Wallet.swift",
    "chars": 2329,
    "preview": "//\n//  Wallet.swift\n//  WalletKit\n//\n//  Created by yuzushioh on 2018/01/01.\n//  Copyright © 2018 yuzushioh. All rights "
  },
  {
    "path": "HDWalletKit.podspec",
    "chars": 1061,
    "preview": "Pod::Spec.new do |s|\n  s.name             = 'HDWalletKit'\n  s.version          = '0.3.6'\n  s.summary          = 'Hierarc"
  },
  {
    "path": "HDWalletKit.xcodeproj/project.pbxproj",
    "chars": 106406,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "HDWalletKit.xcodeproj/xcshareddata/xcschemes/HDWalletKit.xcscheme",
    "chars": 2871,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1020\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "HDWalletKit.xcodeproj/xcshareddata/xcschemes/HDWalletKit_Tests.xcscheme",
    "chars": 1933,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1020\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "HDWalletKit_Tests/AddressGenerationTests.swift",
    "chars": 11192,
    "preview": "//\n//  AddressGenerationTests.swift\n//  HDWalletKit_Tests\n//\n//  Created by Pavlo Boiko on 12.07.18.\n//  Copyright © 201"
  },
  {
    "path": "HDWalletKit_Tests/ConverterTests.swift",
    "chars": 3508,
    "preview": "//\n//  ConverterTests.swift\n//  HDWalletKit_Tests\n//\n//  Created by Pavlo Boiko on 10/10/18.\n//  Copyright © 2018 Essent"
  },
  {
    "path": "HDWalletKit_Tests/CryptoTests.swift",
    "chars": 5072,
    "preview": "//\n//  CryptoTests.swift\n//  HDWalletKit_Tests\n//\n//  Created by Pavlo Boiko on 12.07.18.\n//  Copyright © 2018 Essentia."
  },
  {
    "path": "HDWalletKit_Tests/ERC20Tests.swift",
    "chars": 2483,
    "preview": "//\n//  ERC20Tests.swift\n//  HDWalletKit_Tests\n//\n//  Created by Pavlo Boiko on 24.09.18.\n//  Copyright © 2018 Essentia. "
  },
  {
    "path": "HDWalletKit_Tests/ImportWalletTests.swift",
    "chars": 1061,
    "preview": "//\n//  ImportWalletTests.swift\n//  HDWalletKit_Tests\n//\n//  Created by Pavlo Boiko on 5/5/19.\n//  Copyright © 2019 Essen"
  },
  {
    "path": "HDWalletKit_Tests/Info.plist",
    "chars": 756,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "HDWalletKit_Tests/KeystoreTests.swift",
    "chars": 1418,
    "preview": "//\n//  KeystoreTests.swift\n//  HDWalletKit_Tests\n//\n//  Created by Pavlo Boiko on 22.08.18.\n//  Copyright © 2018 Essenti"
  },
  {
    "path": "HDWalletKit_Tests/MnemonicTests.swift",
    "chars": 7927,
    "preview": "//\n//  MnemonicTests.swift\n//  HDWalletKit_Tests\n//\n//  Created by Pavlo Boiko on 12.07.18.\n//  Copyright © 2018 Essenti"
  },
  {
    "path": "HDWalletKit_Tests/PrivateKeyTests.swift",
    "chars": 2921,
    "preview": "//\n//  PrivateKeyTests.swift\n//  HDWalletKit_Tests\n//\n//  Created by Pavlo Boiko on 4/18/19.\n//  Copyright © 2019 Essent"
  },
  {
    "path": "HDWalletKit_Tests/RIPEMD160Tests.swift",
    "chars": 471,
    "preview": "//\n//  RIPEMD160Tests.swift\n//  HDWalletKit_Tests\n//\n//  Created by Pavlo Boiko on 4/23/19.\n//  Copyright © 2019 Essenti"
  },
  {
    "path": "HDWalletKit_Tests/Secp256k1Tets.swift",
    "chars": 272,
    "preview": "//\n//  Secp256k1Tets.swift\n//  HDWalletKit_Tests\n//\n//  Created by Pavlo Boiko on 4/23/19.\n//  Copyright © 2019 Essentia"
  },
  {
    "path": "HDWalletKit_Tests/SignTransactionTests.swift",
    "chars": 3359,
    "preview": "//\n//  SignTransactionTests.swift\n//  HDWalletKit_Tests\n//\n//  Created by Pavlo Boiko on 20.09.18.\n//  Copyright © 2018 "
  },
  {
    "path": "HDWalletKit_Tests/UTXO/UTXOSign.swift",
    "chars": 4743,
    "preview": "//\n//  UTXOSign.swift\n//  HDWalletKit_Tests\n//\n//  Created by Pavlo Boiko on 3/26/19.\n//  Copyright © 2019 Essentia. All"
  },
  {
    "path": "LICENSE.md",
    "chars": 1068,
    "preview": "MIT License\n\nCopyright (c) 2018 Pavlo Boiko\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
  },
  {
    "path": "Podfile",
    "chars": 259,
    "preview": "platform :ios, '11.0'\n\ntarget 'HDWalletKit' do\n    use_frameworks!\n    pod 'secp256k1.swift', '~> 0.1.4'\n    pod 'Crypto"
  },
  {
    "path": "README.md",
    "chars": 5750,
    "preview": "[![Build Status](https://travis-ci.com/essentiaone/HDWallet.svg?branch=develop)](https://travis-ci.com/essentiaone/HDWal"
  },
  {
    "path": "scripts/coverage.rb",
    "chars": 409,
    "preview": "project_name = ARGV[0]\nprofdata = Dir.glob(File.join('build', '/**/Coverage.profdata')).first\nDir.glob(File.join('build'"
  }
]

About this extraction

This page contains the full source code of the essentiaone/HDWallet GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 184 files (715.4 KB), approximately 266.3k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!