├── .circleci └── config.yml ├── .gitignore ├── CHANGELOG.md ├── Cartfile ├── Cartfile.resolved ├── Example ├── How to run.md ├── Podfile ├── web3swiftExample.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── web3swiftExample.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── web3swiftExample │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift ├── LICENSE.md ├── Package.resolved ├── Package.swift ├── README.md ├── Sources ├── keccak │ ├── include │ │ └── keccak.h │ └── keccak.c ├── scrypt │ ├── asprintf.c │ ├── asprintf.h │ ├── crypto_scrypt.c │ ├── crypto_scrypt_smix.c │ ├── crypto_scrypt_smix.h │ ├── crypto_scrypt_smix_sse2.c │ ├── crypto_scrypt_smix_sse2.h │ ├── entropy.c │ ├── entropy.h │ ├── getopt.c │ ├── getopt.h │ ├── humansize.c │ ├── humansize.h │ ├── include │ │ └── scrypt.h │ ├── insecure_memzero.c │ ├── insecure_memzero.h │ ├── parsenum.h │ ├── readpass.c │ ├── readpass.h │ ├── sha256.c │ ├── sha256.h │ ├── sysendian.h │ ├── warnp.c │ └── warnp.h ├── secp256k1 │ ├── basic-config.h │ ├── ecdh_impl.h │ ├── ecdsa.h │ ├── ecdsa_impl.h │ ├── eckey.h │ ├── eckey_impl.h │ ├── ecmult.h │ ├── ecmult_const.h │ ├── ecmult_const_impl.h │ ├── ecmult_gen.h │ ├── ecmult_gen_impl.h │ ├── ecmult_impl.h │ ├── field.h │ ├── field_10x26.h │ ├── field_10x26_impl.h │ ├── field_5x52.h │ ├── field_5x52_asm_impl.h │ ├── field_5x52_impl.h │ ├── field_5x52_int128_impl.h │ ├── field_impl.h │ ├── group.h │ ├── group_impl.h │ ├── hash.h │ ├── hash_impl.h │ ├── include │ │ └── secp256k1.h │ ├── num.h │ ├── num_gmp.h │ ├── num_gmp_impl.h │ ├── num_impl.h │ ├── recovery_impl.h │ ├── scalar.h │ ├── scalar_4x64.h │ ├── scalar_4x64_impl.h │ ├── scalar_8x32.h │ ├── scalar_8x32_impl.h │ ├── scalar_impl.h │ ├── scalar_low.h │ ├── scalar_low_impl.h │ ├── scratch.h │ ├── scratch_impl.h │ ├── secp256k1-config.h │ ├── secp256k1.c │ ├── secp256k1_ec_mult_static_context.h │ ├── secp256k1_main.h │ └── util.h └── web3swift │ ├── ABIv2 │ ├── ABIv2.swift │ ├── ABIv2Decoding.swift │ ├── ABIv2Elements.swift │ ├── ABIv2Encoding.swift │ ├── ABIv2ParameterTypes.swift │ ├── ABIv2Parsing.swift │ └── ABIv2TypeParser.swift │ ├── Contract │ ├── ComparisonExtensions.swift │ ├── ContractABIv2.swift │ ├── ContractProtocol.swift │ ├── EthereumFilterEncodingExtensions.swift │ └── EventFiltering.swift │ ├── Contracts │ ├── ERC20.swift │ ├── ERC721.swift │ ├── ERC777.swift │ ├── ERC888.swift │ └── SecurityToken.swift │ ├── Convenience │ ├── Array+Extension.swift │ ├── Base58.swift │ ├── CryptoExtensions.swift │ ├── Data+Extension.swift │ ├── Int+Sequence.swift │ ├── LibSecp256k1Extension.swift │ ├── NSRegularExpressionExtension.swift │ ├── NativeTypesEncoding+Extensions.swift │ ├── RIPEMD160+StackOveflow.swift │ ├── String+Extension.swift │ └── UInt256.swift │ ├── Deprecated │ └── BlockExplorer.swift │ ├── Encryption │ ├── AES.swift │ ├── Cryptor │ │ ├── Crypto.swift │ │ ├── Cryptor.swift │ │ ├── Digest.swift │ │ ├── HMAC.swift │ │ ├── KeyDerivation.swift │ │ ├── Random.swift │ │ ├── SSLPointerTricks.swift │ │ ├── Status.swift │ │ ├── StreamCryptor.swift │ │ ├── Updatable.swift │ │ └── Utilities.swift │ ├── DerivedKey.swift │ ├── PrivateKey.swift │ ├── keccak.swift │ └── scrypt.swift │ ├── Ethereum │ ├── EthereumApi.swift │ ├── InputParameters.swift │ ├── OutputParameters.swift │ └── ShhApi.swift │ ├── Guides.swift │ ├── HookedFunctions │ ├── Web3+BrowserFunctions.swift │ └── Web3+Wallet.swift │ ├── KeystoreManager │ ├── AbstractKeystore.swift │ ├── BIP32HDNode.swift │ ├── BIP32Keystore.swift │ ├── BIP39+WordLists.swift │ ├── BIP39.swift │ ├── EthereumAddress.swift │ ├── EthereumKeystoreV3.swift │ ├── HDPath.swift │ ├── IBAN.swift │ ├── KeystoreManager.swift │ └── PlainKeystore.swift │ ├── Migration-iOS.swift │ ├── Migration.swift │ ├── Network │ ├── AnyReader.swift │ ├── JEncodable.swift │ ├── JsonRpcRequest.swift │ ├── NetworkPromises.swift │ └── NetworkProvider.swift │ ├── ObjectiveC │ ├── Bridging.swift │ ├── W3Contract.swift │ ├── W3Contracts.swift │ ├── W3Eth.swift │ ├── W3JsonRpc.swift │ ├── W3Keystore.swift │ ├── W3Personal.swift │ ├── W3Provider.swift │ ├── W3Structs.swift │ ├── W3Transaction.swift │ ├── W3TransactionIntermediate.swift │ ├── W3TxPool.swift │ ├── W3UInt.swift │ ├── W3Wallet.swift │ ├── W3Web3.swift │ └── web3swift.h │ ├── Transaction │ ├── BloomFilter.swift │ └── TransactionSigner.swift │ ├── Transactions │ ├── BlockNumber.swift │ ├── EthereumTransaction.swift │ ├── SolidityDataReader.swift │ ├── SolidityDataReader.swift~HEAD │ ├── SolidityDataWriter.swift │ ├── SolidityDataWriter.swift~HEAD │ ├── SolidityFunction.swift │ ├── SolidityFunction.swift~HEAD │ ├── SolidityTypes.swift │ ├── SolidityTypes.swift~HEAD │ └── Transaction.swift │ ├── TxPool │ ├── DecoderExtensions.swift │ └── TxPool.swift │ ├── Utils │ ├── EIP67Code.swift │ ├── EIP681.swift │ ├── EthURL.swift~HEAD │ └── RLP.swift │ └── Web3 │ ├── Batching.swift │ ├── Web3+Contract.swift │ ├── Web3+Eth.swift │ ├── Web3+EventParser.swift │ ├── Web3+HttpProvider.swift │ ├── Web3+Infura.swift │ ├── Web3+Instance.swift │ ├── Web3+JsonRpcRequest.swift │ ├── Web3+Methods.swift │ ├── Web3+Options.swift │ ├── Web3+Personal.swift │ ├── Web3+Protocols.swift │ ├── Web3+Structures.swift │ ├── Web3+TransactionIntermediate.swift │ ├── Web3+Utils.swift │ └── Web3.swift ├── Tests └── web3swiftTests │ ├── ABITests.swift │ ├── AdvancedABITests.swift │ ├── BetterABI │ ├── BetterERC20Tests.swift │ └── SolidityFunctionTests.swift │ ├── ContractV2Tests.swift │ ├── EIP67Tests.swift │ ├── ERC20Tests.swift │ ├── InfuraTests.swift │ ├── KeystoreTests.swift │ ├── LocalNodeTests.swift │ ├── MainTests.swift │ ├── NetworkTests │ ├── EthereumApiTests.swift │ └── JsonRpcTests.swift │ ├── NumberFormattingUtilTests.swift │ ├── PromiseTests.swift │ ├── RLPTests.swift │ ├── RemoteParsingTests.swift │ ├── RinkebyPersonalSignatureTests.swift │ ├── SECP256K1Tests.swift │ ├── ScryptTests.swift │ ├── Support.swift │ ├── Tests.swift │ ├── TransactionTests.swift │ ├── TxPoolTests.swift │ └── UserCasesTests.swift ├── index.rst ├── web3swift.pod.podspec ├── web3swift.podspec └── web3swift.xcodeproj ├── Before Release.md ├── How to build.md ├── Info.plist ├── project.pbxproj ├── project.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist └── xcshareddata └── xcschemes ├── keccak.xcscheme ├── scrypt.xcscheme ├── secp256k1.xcscheme └── web3swift.xcscheme /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # iOS CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/ios-migrating-from-1-2/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | 9 | # Specify the Xcode version to use 10 | macos: 11 | xcode: "9.3" 12 | 13 | steps: 14 | - checkout 15 | 16 | # Install CocoaPods 17 | - run: 18 | name: Install CocoaPods 19 | command: pod install 20 | 21 | # Build the app and run tests 22 | - run: 23 | name: Build and run tests 24 | command: fastlane scan 25 | environment: 26 | SCAN_DEVICE: iPhone 6 27 | SCAN_SCHEME: WebTests 28 | 29 | # Collect XML test results data to show in the UI, 30 | # and save the same XML files under test-results folder 31 | # in the Artifacts tab 32 | - store_test_results: 33 | path: test_output/report.xml 34 | - store_artifacts: 35 | path: /tmp/test-results 36 | destination: scan-test-results 37 | - store_artifacts: 38 | path: ~/Library/Logs/scan 39 | destination: scan-logs 40 | 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /Carthage 2 | /.build 3 | /Packages 4 | xcuserdata 5 | /Package.pins 6 | /Package.resolved 7 | .DS_Store 8 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "mxcl/PromiseKit" ~> 6.0 2 | github "attaswift/BigInt" ~> 3.1 3 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "attaswift/BigInt" "v3.1.0" 2 | github "attaswift/SipHash" "v1.2.2" 3 | github "mxcl/PromiseKit" "6.7.1" 4 | -------------------------------------------------------------------------------- /Example/How to run.md: -------------------------------------------------------------------------------- 1 | ## Running the example project 2 | 3 | ``` 4 | cd Example 5 | pod install 6 | open web3swiftExample.xcworkspace 7 | ``` -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '11.2' 2 | 3 | target 'web3swiftExample' do 4 | # use_frameworks! 5 | use_modular_headers! 6 | pod 'web3swift.pod' 7 | end 8 | -------------------------------------------------------------------------------- /Example/web3swiftExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/web3swiftExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/web3swiftExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/web3swiftExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/web3swiftExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // web3swiftExample 4 | // 5 | // Created by Alexander Vlasov on 22.12.2017. 6 | // Copyright © 2017 Alexander Vlasov. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Example/web3swiftExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /Example/web3swiftExample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Example/web3swiftExample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Example/web3swiftExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | NSAppTransportSecurity 45 | 46 | NSAllowsArbitraryLoads 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "BigInt", 6 | "repositoryURL": "https://github.com/attaswift/BigInt.git", 7 | "state": { 8 | "branch": null, 9 | "revision": "018a5925f60f9e0523edd261de394a0898fe95b7", 10 | "version": "3.1.0" 11 | } 12 | }, 13 | { 14 | "package": "Cryptor", 15 | "repositoryURL": "https://github.com/v57/BlueCryptor.git", 16 | "state": { 17 | "branch": null, 18 | "revision": "62470ce23835f8920ce58e39d59548406af85dea", 19 | "version": "1.0.23" 20 | } 21 | }, 22 | { 23 | "package": "CryptoSwift", 24 | "repositoryURL": "https://github.com/krzyzanowskim/CryptoSwift.git", 25 | "state": { 26 | "branch": null, 27 | "revision": "874280173e082cdd7ac6602be235914efe3f4dbc", 28 | "version": "0.13.0" 29 | } 30 | }, 31 | { 32 | "package": "PromiseKit", 33 | "repositoryURL": "https://github.com/mxcl/PromiseKit.git", 34 | "state": { 35 | "branch": null, 36 | "revision": "66bcc386163121f14ee543aa20b682973cc98dd7", 37 | "version": "6.5.2" 38 | } 39 | }, 40 | { 41 | "package": "SipHash", 42 | "repositoryURL": "https://github.com/attaswift/SipHash", 43 | "state": { 44 | "branch": null, 45 | "revision": "e325083424688055363bbfcb7f1a440d7d7a1bae", 46 | "version": "1.2.2" 47 | } 48 | } 49 | ] 50 | }, 51 | "version": 1 52 | } 53 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.2 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "web3swift", 8 | products: [ 9 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 10 | .library(name: "web3swift", targets: ["web3swift"]), 11 | ], 12 | dependencies: [ 13 | .package(url: "https://github.com/attaswift/BigInt.git", from: "3.1.0"), 14 | .package(url: "https://github.com/mxcl/PromiseKit.git", from: "6.4.0"), 15 | ], 16 | targets: [ 17 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 18 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 19 | .target(name: "secp256k1"), 20 | .target(name: "keccak"), 21 | .target(name: "scrypt"), 22 | .target( 23 | name: "web3swift", 24 | dependencies: ["BigInt", "secp256k1", "keccak", "scrypt", "PromiseKit"], 25 | exclude: [ 26 | "ObjectiveC", 27 | "Utils/EIP67Code.swift", 28 | "Migration-iOS.swift" 29 | ]), 30 | .testTarget( 31 | name: "web3swiftTests", 32 | dependencies: ["web3swift"]), 33 | ] 34 | ) 35 | -------------------------------------------------------------------------------- /Sources/keccak/include/keccak.h: -------------------------------------------------------------------------------- 1 | #ifndef KECCAK_FIPS202_H 2 | #define KECCAK_FIPS202_H 3 | #define __STDC_WANT_LIB_EXT1__ 1 4 | #include 5 | #include 6 | 7 | #define decshake(bits) \ 8 | int shake##bits(uint8_t*, size_t, const uint8_t*, size_t); 9 | 10 | #define decsha3(bits) \ 11 | int sha3_##bits(uint8_t*, size_t, const uint8_t*, size_t); 12 | 13 | #define deckeccak(bits) \ 14 | int keccak_##bits(uint8_t*, size_t, const uint8_t*, size_t); 15 | 16 | 17 | decshake(128) 18 | decshake(256) 19 | decsha3(224) 20 | decsha3(256) 21 | decsha3(384) 22 | decsha3(512) 23 | deckeccak(256) 24 | deckeccak(512) 25 | #endif 26 | -------------------------------------------------------------------------------- /Sources/scrypt/asprintf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "asprintf.h" 6 | 7 | /** 8 | * asprintf(ret, format, ...): 9 | * Do asprintf(3) like GNU and BSD do. 10 | */ 11 | int 12 | asprintf(char ** ret, const char * format, ...) 13 | { 14 | va_list ap; 15 | int len; 16 | size_t buflen; 17 | 18 | /* Figure out how long the string needs to be. */ 19 | va_start(ap, format); 20 | len = vsnprintf(NULL, 0, format, ap); 21 | va_end(ap); 22 | 23 | /* Did we fail? */ 24 | if (len < 0) 25 | goto err0; 26 | buflen = (size_t)(len) + 1; 27 | 28 | /* Allocate memory. */ 29 | if ((*ret = malloc(buflen)) == NULL) 30 | goto err0; 31 | 32 | /* Actually generate the string. */ 33 | va_start(ap, format); 34 | len = vsnprintf(*ret, buflen, format, ap); 35 | va_end(ap); 36 | 37 | /* Did we fail? */ 38 | if (len < 0) 39 | goto err1; 40 | 41 | /* Success! */ 42 | return (len); 43 | 44 | err1: 45 | free(*ret); 46 | err0: 47 | /* Failure! */ 48 | return (-1); 49 | } 50 | -------------------------------------------------------------------------------- /Sources/scrypt/asprintf.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASPRINTF_H_ 2 | #define _ASPRINTF_H_ 3 | 4 | /* Avoid namespace collisions with BSD/GNU asprintf. */ 5 | #ifdef asprintf 6 | #undef asprintf 7 | #endif 8 | #define asprintf libcperciva_asprintf 9 | 10 | /** 11 | * asprintf(ret, format, ...): 12 | * Do asprintf(3) like GNU and BSD do. 13 | */ 14 | int asprintf(char **, const char *, ...); 15 | 16 | #endif /* !_ASPRINTF_H_ */ 17 | -------------------------------------------------------------------------------- /Sources/scrypt/crypto_scrypt_smix.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRYPTO_SCRYPT_SMIX_H_ 2 | #define _CRYPTO_SCRYPT_SMIX_H_ 3 | 4 | #include 5 | #include 6 | 7 | /** 8 | * crypto_scrypt_smix(B, r, N, V, XY): 9 | * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; 10 | * the temporary storage V must be 128rN bytes in length; the temporary 11 | * storage XY must be 256r + 64 bytes in length. The value N must be a 12 | * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a 13 | * multiple of 64 bytes. 14 | */ 15 | void crypto_scrypt_smix(uint8_t *, size_t, uint64_t, void *, void *); 16 | 17 | #endif /* !_CRYPTO_SCRYPT_SMIX_H_ */ 18 | -------------------------------------------------------------------------------- /Sources/scrypt/crypto_scrypt_smix_sse2.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRYPTO_SCRYPT_SMIX_SSE2_H_ 2 | #define _CRYPTO_SCRYPT_SMIX_SSE2_H_ 3 | 4 | #include 5 | #include 6 | 7 | /** 8 | * crypto_scrypt_smix_sse2(B, r, N, V, XY): 9 | * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; 10 | * the temporary storage V must be 128rN bytes in length; the temporary 11 | * storage XY must be 256r + 64 bytes in length. The value N must be a 12 | * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a 13 | * multiple of 64 bytes. 14 | * 15 | * Use SSE2 instructions. 16 | */ 17 | void crypto_scrypt_smix_sse2(uint8_t *, size_t, uint64_t, void *, void *); 18 | 19 | #endif /* !_CRYPTO_SCRYPT_SMIX_SSE2_H_ */ 20 | -------------------------------------------------------------------------------- /Sources/scrypt/entropy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "warnp.h" 8 | 9 | #include "entropy.h" 10 | 11 | /** 12 | * XXX Portability 13 | * XXX We obtain random bytes from the operating system by opening 14 | * XXX /dev/urandom and reading them from that device; this works on 15 | * XXX modern UNIX-like operating systems but not on systems like 16 | * XXX win32 where there is no concept of /dev/urandom. 17 | */ 18 | 19 | /** 20 | * entropy_read(buf, buflen): 21 | * Fill the given buffer with random bytes provided by the operating system. 22 | */ 23 | int 24 | entropy_read(uint8_t * buf, size_t buflen) 25 | { 26 | int fd; 27 | ssize_t lenread; 28 | 29 | /* Sanity-check the buffer size. */ 30 | if (buflen > SSIZE_MAX) { 31 | warn0("Programmer error: " 32 | "Trying to read insane amount of random data: %zu", 33 | buflen); 34 | goto err0; 35 | } 36 | 37 | /* Open /dev/urandom. */ 38 | if ((fd = open("/dev/urandom", O_RDONLY)) == -1) { 39 | warnp("open(/dev/urandom)"); 40 | goto err0; 41 | } 42 | 43 | /* Read bytes until we have filled the buffer. */ 44 | while (buflen > 0) { 45 | if ((lenread = read(fd, buf, buflen)) == -1) { 46 | warnp("read(/dev/urandom)"); 47 | goto err1; 48 | } 49 | 50 | /* The random device should never EOF. */ 51 | if (lenread == 0) { 52 | warn0("EOF on /dev/urandom?"); 53 | goto err1; 54 | } 55 | 56 | /* We've filled a portion of the buffer. */ 57 | buf += (size_t)lenread; 58 | buflen -= (size_t)lenread; 59 | } 60 | 61 | /* Close the device. */ 62 | while (close(fd) == -1) { 63 | if (errno != EINTR) { 64 | warnp("close(/dev/urandom)"); 65 | goto err0; 66 | } 67 | } 68 | 69 | /* Success! */ 70 | return (0); 71 | 72 | err1: 73 | close(fd); 74 | err0: 75 | /* Failure! */ 76 | return (-1); 77 | } 78 | -------------------------------------------------------------------------------- /Sources/scrypt/entropy.h: -------------------------------------------------------------------------------- 1 | #ifndef _ENTROPY_H_ 2 | #define _ENTROPY_H_ 3 | 4 | #include 5 | #include 6 | 7 | /** 8 | * entropy_read(buf, buflen): 9 | * Fill the given buffer with random bytes provided by the operating system. 10 | */ 11 | int entropy_read(uint8_t *, size_t); 12 | 13 | #endif /* !_ENTROPY_H_ */ 14 | -------------------------------------------------------------------------------- /Sources/scrypt/humansize.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "asprintf.h" 4 | #include "warnp.h" 5 | 6 | #include "humansize.h" 7 | 8 | /** 9 | * humansize(size): 10 | * Given a size in bytes, allocate and return a string of the form " B" 11 | * for 0 <= N <= 999 or " B" where either 10 <= X <= 999 or 12 | * 1.0 <= X <= 9.9 and is "k", "M", "G", "T", "P", or "E"; and where 13 | * the value returned is the largest valid value <= the provided size. 14 | */ 15 | char * 16 | humansize(uint64_t size) 17 | { 18 | char * s; 19 | char prefix; 20 | int shiftcnt; 21 | int rc; 22 | 23 | /* Special-case for size < 1000. */ 24 | if (size < 1000) { 25 | rc = asprintf(&s, "%d B", (int)size); 26 | } else { 27 | /* Keep 10 * size / 1000^(3n) in size. */ 28 | for (size /= 100, shiftcnt = 1; size >= 10000; shiftcnt++) 29 | size /= 1000; 30 | 31 | /* 32 | * Figure out what prefix to use. Since 1 EB = 10^18 B and 33 | * the maximum value of a uint64_t is 2^64 which is roughly 34 | * 18.4 * 10^18, this cannot reference beyond the end of the 35 | * string. 36 | */ 37 | prefix = " kMGTPE"[shiftcnt]; 38 | 39 | /* Construct the string. */ 40 | if (size < 100) 41 | rc = asprintf(&s, "%d.%d %cB", (int)size / 10, 42 | (int)size % 10, prefix); 43 | else 44 | rc = asprintf(&s, "%d %cB", (int)size / 10, prefix); 45 | } 46 | 47 | if (rc == -1) { 48 | warnp("asprintf"); 49 | goto err0; 50 | } 51 | 52 | /* Success! */ 53 | return (s); 54 | 55 | err0: 56 | /* Failure! */ 57 | return (NULL); 58 | } 59 | 60 | /** 61 | * humansize_parse(s, size): 62 | * Parse a string matching /[0-9]+ ?[kMGTPE]?B?/ as a size in bytes. 63 | */ 64 | int 65 | humansize_parse(const char * s, uint64_t * size) 66 | { 67 | int state = 0; 68 | uint64_t multiplier = 1; 69 | 70 | do { 71 | switch (state) { 72 | case -1: 73 | /* Error state. */ 74 | break; 75 | case 0: 76 | /* Initial state. */ 77 | *size = 0; 78 | 79 | /* We must start with at least one digit. */ 80 | if ((*s < '0') || (*s > '9')) { 81 | state = -1; 82 | break; 83 | } 84 | 85 | /* FALLTHROUGH */ 86 | case 1: 87 | /* We're now processing digits. */ 88 | state = 1; 89 | 90 | /* Digit-parsing state. */ 91 | if (('0' <= *s) && (*s <= '9')) { 92 | if (*size > UINT64_MAX / 10) 93 | state = -1; 94 | else 95 | *size *= 10; 96 | if (*size > UINT64_MAX - (uint64_t)(*s - '0')) 97 | state = -1; 98 | else 99 | *size += (uint64_t)(*s - '0'); 100 | break; 101 | } 102 | 103 | /* FALLTHROUGH */ 104 | case 2: 105 | /* We move into state 3 after an optional ' '. */ 106 | state = 3; 107 | if (*s == ' ') 108 | break; 109 | 110 | /* FALLTHROUGH */ 111 | case 3: 112 | /* We may have one SI prefix. */ 113 | switch (*s) { 114 | case 'E': 115 | multiplier *= 1000; 116 | /* FALLTHROUGH */ 117 | case 'P': 118 | multiplier *= 1000; 119 | /* FALLTHROUGH */ 120 | case 'T': 121 | multiplier *= 1000; 122 | /* FALLTHROUGH */ 123 | case 'G': 124 | multiplier *= 1000; 125 | /* FALLTHROUGH */ 126 | case 'M': 127 | multiplier *= 1000; 128 | /* FALLTHROUGH */ 129 | case 'k': 130 | multiplier *= 1000; 131 | break; 132 | } 133 | 134 | /* We move into state 4 after the optional prefix. */ 135 | state = 4; 136 | if (multiplier != 1) 137 | break; 138 | 139 | /* FALLTHROUGH */ 140 | case 4: 141 | /* We move into state 5 after an optional 'B'. */ 142 | state = 5; 143 | if (*s == 'B') 144 | break; 145 | 146 | /* FALLTHROUGH */ 147 | case 5: 148 | /* We have trailing garbage. */ 149 | state = -1; 150 | break; 151 | } 152 | 153 | /* Move on to the next character. */ 154 | s++; 155 | } while (*s != '\0'); 156 | 157 | /* Multiply by multiplier. */ 158 | if (*size > UINT64_MAX / multiplier) 159 | state = -1; 160 | else 161 | *size *= multiplier; 162 | 163 | /* Anything other than state -1 is success. */ 164 | return ((state == -1) ? -1 : 0); 165 | } 166 | -------------------------------------------------------------------------------- /Sources/scrypt/humansize.h: -------------------------------------------------------------------------------- 1 | #ifndef _HUMANSIZE_H_ 2 | #define _HUMANSIZE_H_ 3 | 4 | #include 5 | 6 | /** 7 | * humansize(size): 8 | * Given a size in bytes, allocate and return a string of the form " B" 9 | * for 0 <= N <= 999 or " B" where either 10 <= X <= 999 or 10 | * 1.0 <= X <= 9.9 and is "k", "M", "G", "T", "P", or "E"; and where 11 | * the value returned is the largest valid value <= the provided size. 12 | */ 13 | char * humansize(uint64_t); 14 | 15 | /** 16 | * humansize_parse(s, size): 17 | * Parse a string matching /[0-9]+ ?[kMGTPE]?B?/ as a size in bytes. 18 | */ 19 | int humansize_parse(const char *, uint64_t *); 20 | 21 | #endif /* !_HUMANSIZE_H_ */ 22 | -------------------------------------------------------------------------------- /Sources/scrypt/include/scrypt.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2009 Colin Percival 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 | * SUCH DAMAGE. 25 | * 26 | * This file was originally written by Colin Percival as part of the Tarsnap 27 | * online backup system. 28 | */ 29 | #ifndef _CRYPTO_SCRYPT_H_ 30 | #define _CRYPTO_SCRYPT_H_ 31 | 32 | #include 33 | #include 34 | 35 | /** 36 | * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): 37 | * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, 38 | * p, buflen) and write the result into buf. The parameters r, p, and buflen 39 | * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N 40 | * must be a power of 2 greater than 1. 41 | * 42 | * Return 0 on success; or -1 on error. 43 | */ 44 | int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, 45 | uint32_t, uint32_t, uint8_t *, size_t); 46 | 47 | #endif /* !_CRYPTO_SCRYPT_H_ */ 48 | -------------------------------------------------------------------------------- /Sources/scrypt/insecure_memzero.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "insecure_memzero.h" 5 | 6 | /* Function which does the zeroing. */ 7 | static void 8 | insecure_memzero_func(volatile void * buf, size_t len) 9 | { 10 | volatile uint8_t * _buf = buf; 11 | size_t i; 12 | 13 | for (i = 0; i < len; i++) 14 | _buf[i] = 0; 15 | } 16 | 17 | /* Pointer to memory-zeroing function. */ 18 | void (* volatile insecure_memzero_ptr)(volatile void *, size_t) = 19 | insecure_memzero_func; 20 | -------------------------------------------------------------------------------- /Sources/scrypt/insecure_memzero.h: -------------------------------------------------------------------------------- 1 | #ifndef _INSECURE_MEMZERO_H_ 2 | #define _INSECURE_MEMZERO_H_ 3 | 4 | #include 5 | 6 | /* Pointer to memory-zeroing function. */ 7 | extern void (* volatile insecure_memzero_ptr)(volatile void *, size_t); 8 | 9 | /** 10 | * insecure_memzero(buf, len): 11 | * Attempt to zero ${len} bytes at ${buf} in spite of optimizing compilers' 12 | * best (standards-compliant) attempts to remove the buffer-zeroing. In 13 | * particular, to avoid performing the zeroing, a compiler would need to 14 | * use optimistic devirtualization; recognize that non-volatile objects do not 15 | * need to be treated as volatile, even if they are accessed via volatile 16 | * qualified pointers; and perform link-time optimization; in addition to the 17 | * dead-code elimination which often causes buffer-zeroing to be elided. 18 | * 19 | * Note however that zeroing a buffer does not guarantee that the data held 20 | * in the buffer is not stored elsewhere; in particular, there may be copies 21 | * held in CPU registers or in anonymous allocations on the stack, even if 22 | * every named variable is successfully sanitized. Solving the "wipe data 23 | * from the system" problem will require a C language extension which does not 24 | * yet exist. 25 | * 26 | * For more information, see: 27 | * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html 28 | * http://www.daemonology.net/blog/2014-09-06-zeroing-buffers-is-insufficient.html 29 | */ 30 | static inline void 31 | insecure_memzero(volatile void * buf, size_t len) 32 | { 33 | 34 | (insecure_memzero_ptr)(buf, len); 35 | } 36 | 37 | #endif /* !_INSECURE_MEMZERO_H_ */ 38 | -------------------------------------------------------------------------------- /Sources/scrypt/readpass.h: -------------------------------------------------------------------------------- 1 | #ifndef _READPASS_H_ 2 | #define _READPASS_H_ 3 | 4 | /* Avoid namespace collisions with other "readpass" functions. */ 5 | #ifdef readpass 6 | #undef readpass 7 | #endif 8 | #define readpass libcperciva_readpass 9 | 10 | /** 11 | * readpass(passwd, prompt, confirmprompt, devtty) 12 | * If ${devtty} is non-zero, read a password from /dev/tty if possible; if 13 | * not, read from stdin. If reading from a tty (either /dev/tty or stdin), 14 | * disable echo and prompt the user by printing ${prompt} to stderr. If 15 | * ${confirmprompt} is non-NULL, read a second password (prompting if a 16 | * terminal is being used) and repeat until the user enters the same password 17 | * twice. Return the password as a malloced NUL-terminated string via 18 | * ${passwd}. 19 | */ 20 | int readpass(char **, const char *, const char *, int); 21 | 22 | #endif /* !_READPASS_H_ */ 23 | -------------------------------------------------------------------------------- /Sources/scrypt/sha256.h: -------------------------------------------------------------------------------- 1 | #ifndef _SHA256_H_ 2 | #define _SHA256_H_ 3 | 4 | #include 5 | #include 6 | 7 | /* 8 | * Use #defines in order to avoid namespace collisions with anyone else's 9 | * SHA256 code (e.g., the code in OpenSSL). 10 | */ 11 | #define SHA256_Init libcperciva_SHA256_Init 12 | #define SHA256_Update libcperciva_SHA256_Update 13 | #define SHA256_Final libcperciva_SHA256_Final 14 | #define SHA256_Buf libcperciva_SHA256_Buf 15 | #define SHA256_CTX libcperciva_SHA256_CTX 16 | #define HMAC_SHA256_Init libcperciva_HMAC_SHA256_Init 17 | #define HMAC_SHA256_Update libcperciva_HMAC_SHA256_Update 18 | #define HMAC_SHA256_Final libcperciva_HMAC_SHA256_Final 19 | #define HMAC_SHA256_Buf libcperciva_HMAC_SHA256_Buf 20 | #define HMAC_SHA256_CTX libcperciva_HMAC_SHA256_CTX 21 | 22 | /* Context structure for SHA256 operations. */ 23 | typedef struct { 24 | uint32_t state[8]; 25 | uint64_t count; 26 | uint8_t buf[64]; 27 | } SHA256_CTX; 28 | 29 | /** 30 | * SHA256_Init(ctx): 31 | * Initialize the SHA256 context ${ctx}. 32 | */ 33 | void SHA256_Init(SHA256_CTX *); 34 | 35 | /** 36 | * SHA256_Update(ctx, in, len): 37 | * Input ${len} bytes from ${in} into the SHA256 context ${ctx}. 38 | */ 39 | void SHA256_Update(SHA256_CTX *, const void *, size_t); 40 | 41 | /** 42 | * SHA256_Final(digest, ctx): 43 | * Output the SHA256 hash of the data input to the context ${ctx} into the 44 | * buffer ${digest}. 45 | */ 46 | void SHA256_Final(uint8_t[32], SHA256_CTX *); 47 | 48 | /** 49 | * SHA256_Buf(in, len, digest): 50 | * Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}. 51 | */ 52 | void SHA256_Buf(const void *, size_t, uint8_t[32]); 53 | 54 | /* Context structure for HMAC-SHA256 operations. */ 55 | typedef struct { 56 | SHA256_CTX ictx; 57 | SHA256_CTX octx; 58 | } HMAC_SHA256_CTX; 59 | 60 | /** 61 | * HMAC_SHA256_Init(ctx, K, Klen): 62 | * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from 63 | * ${K}. 64 | */ 65 | void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t); 66 | 67 | /** 68 | * HMAC_SHA256_Update(ctx, in, len): 69 | * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}. 70 | */ 71 | void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t); 72 | 73 | /** 74 | * HMAC_SHA256_Final(digest, ctx): 75 | * Output the HMAC-SHA256 of the data input to the context ${ctx} into the 76 | * buffer ${digest}. 77 | */ 78 | void HMAC_SHA256_Final(uint8_t[32], HMAC_SHA256_CTX *); 79 | 80 | /** 81 | * HMAC_SHA256_Buf(K, Klen, in, len, digest): 82 | * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of 83 | * length ${Klen}, and write the result to ${digest}. 84 | */ 85 | void HMAC_SHA256_Buf(const void *, size_t, const void *, size_t, uint8_t[32]); 86 | 87 | /** 88 | * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): 89 | * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and 90 | * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). 91 | */ 92 | void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, 93 | uint64_t, uint8_t *, size_t); 94 | 95 | #endif /* !_SHA256_H_ */ 96 | -------------------------------------------------------------------------------- /Sources/scrypt/sysendian.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYSENDIAN_H_ 2 | #define _SYSENDIAN_H_ 3 | 4 | #include 5 | 6 | /* Avoid namespace collisions with BSD . */ 7 | #define be16dec libcperciva_be16dec 8 | #define be16enc libcperciva_be16enc 9 | #define be32dec libcperciva_be32dec 10 | #define be32enc libcperciva_be32enc 11 | #define be64dec libcperciva_be64dec 12 | #define be64enc libcperciva_be64enc 13 | #define le16dec libcperciva_le16dec 14 | #define le16enc libcperciva_le16enc 15 | #define le32dec libcperciva_le32dec 16 | #define le32enc libcperciva_le32enc 17 | #define le64dec libcperciva_le64dec 18 | #define le64enc libcperciva_le64enc 19 | 20 | static inline uint16_t 21 | be16dec(const void * pp) 22 | { 23 | const uint8_t * p = (uint8_t const *)pp; 24 | 25 | return (uint16_t)((uint16_t)(p[1]) + ((uint16_t)(p[0]) << 8)); 26 | } 27 | 28 | static inline void 29 | be16enc(void * pp, uint16_t x) 30 | { 31 | uint8_t * p = (uint8_t *)pp; 32 | 33 | p[1] = x & 0xff; 34 | p[0] = (x >> 8) & 0xff; 35 | } 36 | 37 | static inline uint32_t 38 | be32dec(const void * pp) 39 | { 40 | const uint8_t * p = (uint8_t const *)pp; 41 | 42 | return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + 43 | ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); 44 | } 45 | 46 | static inline void 47 | be32enc(void * pp, uint32_t x) 48 | { 49 | uint8_t * p = (uint8_t *)pp; 50 | 51 | p[3] = x & 0xff; 52 | p[2] = (x >> 8) & 0xff; 53 | p[1] = (x >> 16) & 0xff; 54 | p[0] = (x >> 24) & 0xff; 55 | } 56 | 57 | static inline uint64_t 58 | be64dec(const void * pp) 59 | { 60 | const uint8_t * p = (uint8_t const *)pp; 61 | 62 | return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) + 63 | ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) + 64 | ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) + 65 | ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56)); 66 | } 67 | 68 | static inline void 69 | be64enc(void * pp, uint64_t x) 70 | { 71 | uint8_t * p = (uint8_t *)pp; 72 | 73 | p[7] = x & 0xff; 74 | p[6] = (x >> 8) & 0xff; 75 | p[5] = (x >> 16) & 0xff; 76 | p[4] = (x >> 24) & 0xff; 77 | p[3] = (x >> 32) & 0xff; 78 | p[2] = (x >> 40) & 0xff; 79 | p[1] = (x >> 48) & 0xff; 80 | p[0] = (x >> 56) & 0xff; 81 | } 82 | 83 | static inline uint16_t 84 | le16dec(const void * pp) 85 | { 86 | const uint8_t * p = (uint8_t const *)pp; 87 | 88 | return (uint16_t)((uint16_t)(p[0]) + ((uint16_t)(p[1]) << 8)); 89 | } 90 | 91 | static inline void 92 | le16enc(void * pp, uint16_t x) 93 | { 94 | uint8_t * p = (uint8_t *)pp; 95 | 96 | p[0] = x & 0xff; 97 | p[1] = (x >> 8) & 0xff; 98 | } 99 | 100 | static inline uint32_t 101 | le32dec(const void * pp) 102 | { 103 | const uint8_t * p = (uint8_t const *)pp; 104 | 105 | return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) + 106 | ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24)); 107 | } 108 | 109 | static inline void 110 | le32enc(void * pp, uint32_t x) 111 | { 112 | uint8_t * p = (uint8_t *)pp; 113 | 114 | p[0] = x & 0xff; 115 | p[1] = (x >> 8) & 0xff; 116 | p[2] = (x >> 16) & 0xff; 117 | p[3] = (x >> 24) & 0xff; 118 | } 119 | 120 | static inline uint64_t 121 | le64dec(const void * pp) 122 | { 123 | const uint8_t * p = (uint8_t const *)pp; 124 | 125 | return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) + 126 | ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) + 127 | ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) + 128 | ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56)); 129 | } 130 | 131 | static inline void 132 | le64enc(void * pp, uint64_t x) 133 | { 134 | uint8_t * p = (uint8_t *)pp; 135 | 136 | p[0] = x & 0xff; 137 | p[1] = (x >> 8) & 0xff; 138 | p[2] = (x >> 16) & 0xff; 139 | p[3] = (x >> 24) & 0xff; 140 | p[4] = (x >> 32) & 0xff; 141 | p[5] = (x >> 40) & 0xff; 142 | p[6] = (x >> 48) & 0xff; 143 | p[7] = (x >> 56) & 0xff; 144 | } 145 | 146 | #endif /* !_SYSENDIAN_H_ */ 147 | -------------------------------------------------------------------------------- /Sources/scrypt/warnp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "warnp.h" 8 | 9 | static int initialized = 0; 10 | static char * name = NULL; 11 | 12 | /* Free the name string. */ 13 | static void 14 | done(void) 15 | { 16 | 17 | free(name); 18 | name = NULL; 19 | } 20 | 21 | /** 22 | * warnp_setprogname(progname): 23 | * Set the program name to be used by warn() and warnx() to ${progname}. 24 | */ 25 | void 26 | warnp_setprogname(const char * progname) 27 | { 28 | const char * p; 29 | 30 | /* Free the name if we already have one. */ 31 | free(name); 32 | 33 | /* Find the last segment of the program name. */ 34 | for (p = progname; progname[0] != '\0'; progname++) 35 | if (progname[0] == '/') 36 | p = progname + 1; 37 | 38 | /* Copy the name string. */ 39 | name = strdup(p); 40 | 41 | /* If we haven't already done so, register our exit handler. */ 42 | if (initialized == 0) { 43 | atexit(done); 44 | initialized = 1; 45 | } 46 | } 47 | 48 | void 49 | warn(const char * fmt, ...) 50 | { 51 | va_list ap; 52 | 53 | va_start(ap, fmt); 54 | fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)"); 55 | if (fmt != NULL) { 56 | fprintf(stderr, ": "); 57 | vfprintf(stderr, fmt, ap); 58 | } 59 | fprintf(stderr, ": %s\n", strerror(errno)); 60 | va_end(ap); 61 | } 62 | 63 | void 64 | warnx(const char * fmt, ...) 65 | { 66 | va_list ap; 67 | 68 | va_start(ap, fmt); 69 | fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)"); 70 | if (fmt != NULL) { 71 | fprintf(stderr, ": "); 72 | vfprintf(stderr, fmt, ap); 73 | } 74 | fprintf(stderr, "\n"); 75 | va_end(ap); 76 | } 77 | -------------------------------------------------------------------------------- /Sources/scrypt/warnp.h: -------------------------------------------------------------------------------- 1 | #ifndef _WARNP_H_ 2 | #define _WARNP_H_ 3 | 4 | #include 5 | #include 6 | 7 | /* Avoid namespace collisions with BSD . */ 8 | #define warn libcperciva_warn 9 | #define warnx libcperciva_warnx 10 | 11 | /** 12 | * warnp_setprogname(progname): 13 | * Set the program name to be used by warn() and warnx() to ${progname}. 14 | */ 15 | void warnp_setprogname(const char *); 16 | #define WARNP_INIT do { \ 17 | if (argv[0] != NULL) \ 18 | warnp_setprogname(argv[0]); \ 19 | } while (0) 20 | 21 | /* As in BSD . */ 22 | void warn(const char *, ...); 23 | void warnx(const char *, ...); 24 | 25 | /* 26 | * If compiled with DEBUG defined, print __FILE__ and __LINE__. 27 | */ 28 | #ifdef DEBUG 29 | #define warnline do { \ 30 | warnx("%s, %d", __FILE__, __LINE__); \ 31 | } while (0) 32 | #else 33 | #define warnline 34 | #endif 35 | 36 | /* 37 | * Call warn(3) or warnx(3) depending upon whether errno == 0; and clear 38 | * errno (so that the standard error message isn't repeated later). 39 | */ 40 | #define warnp(...) do { \ 41 | warnline; \ 42 | if (errno != 0) { \ 43 | warn(__VA_ARGS__); \ 44 | errno = 0; \ 45 | } else \ 46 | warnx(__VA_ARGS__); \ 47 | } while (0) 48 | 49 | /* 50 | * Call warnx(3) and set errno == 0. Unlike warnp, this should be used 51 | * in cases where we're reporting a problem which we discover ourselves 52 | * rather than one which is reported to us from a library or the kernel. 53 | */ 54 | #define warn0(...) do { \ 55 | warnline; \ 56 | warnx(__VA_ARGS__); \ 57 | errno = 0; \ 58 | } while (0) 59 | 60 | #endif /* !_WARNP_H_ */ 61 | -------------------------------------------------------------------------------- /Sources/secp256k1/basic-config.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_BASIC_CONFIG_H 8 | #define SECP256K1_BASIC_CONFIG_H 9 | 10 | #ifdef USE_BASIC_CONFIG 11 | 12 | #undef USE_ASM_X86_64 13 | #undef USE_ENDOMORPHISM 14 | #undef USE_FIELD_10X26 15 | #undef USE_FIELD_5X52 16 | #undef USE_FIELD_INV_BUILTIN 17 | #undef USE_FIELD_INV_NUM 18 | #undef USE_NUM_GMP 19 | #undef USE_NUM_NONE 20 | #undef USE_SCALAR_4X64 21 | #undef USE_SCALAR_8X32 22 | #undef USE_SCALAR_INV_BUILTIN 23 | #undef USE_SCALAR_INV_NUM 24 | 25 | #define USE_NUM_NONE 1 26 | #define USE_FIELD_INV_BUILTIN 1 27 | #define USE_SCALAR_INV_BUILTIN 1 28 | #define USE_FIELD_10X26 1 29 | #define USE_SCALAR_8X32 1 30 | 31 | #endif /* USE_BASIC_CONFIG */ 32 | 33 | #endif /* SECP256K1_BASIC_CONFIG_H */ 34 | -------------------------------------------------------------------------------- /Sources/secp256k1/ecdh_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_MODULE_ECDH_MAIN_H 8 | #define SECP256K1_MODULE_ECDH_MAIN_H 9 | 10 | #include "secp256k1.h" 11 | #include "ecmult_const_impl.h" 12 | 13 | int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *result, const secp256k1_pubkey *point, const unsigned char *scalar) { 14 | int ret = 0; 15 | int overflow = 0; 16 | secp256k1_gej res; 17 | secp256k1_ge pt; 18 | secp256k1_scalar s; 19 | VERIFY_CHECK(ctx != NULL); 20 | ARG_CHECK(result != NULL); 21 | ARG_CHECK(point != NULL); 22 | ARG_CHECK(scalar != NULL); 23 | 24 | secp256k1_pubkey_load(ctx, &pt, point); 25 | secp256k1_scalar_set_b32(&s, scalar, &overflow); 26 | if (overflow || secp256k1_scalar_is_zero(&s)) { 27 | ret = 0; 28 | } else { 29 | unsigned char x[32]; 30 | unsigned char y[1]; 31 | secp256k1_sha256 sha; 32 | 33 | secp256k1_ecmult_const(&res, &pt, &s, 256); 34 | secp256k1_ge_set_gej(&pt, &res); 35 | /* Compute a hash of the point in compressed form 36 | * Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not 37 | * expect its output to be secret and has a timing sidechannel. */ 38 | secp256k1_fe_normalize(&pt.x); 39 | secp256k1_fe_normalize(&pt.y); 40 | secp256k1_fe_get_b32(x, &pt.x); 41 | y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y); 42 | 43 | secp256k1_sha256_initialize(&sha); 44 | secp256k1_sha256_write(&sha, y, sizeof(y)); 45 | secp256k1_sha256_write(&sha, x, sizeof(x)); 46 | secp256k1_sha256_finalize(&sha, result); 47 | ret = 1; 48 | } 49 | 50 | secp256k1_scalar_clear(&s); 51 | return ret; 52 | } 53 | 54 | #endif /* SECP256K1_MODULE_ECDH_MAIN_H */ 55 | -------------------------------------------------------------------------------- /Sources/secp256k1/ecdsa.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECDSA_H 8 | #define SECP256K1_ECDSA_H 9 | 10 | #include 11 | 12 | #include "scalar.h" 13 | #include "group.h" 14 | #include "ecmult.h" 15 | 16 | static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size); 17 | static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s); 18 | static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message); 19 | static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid); 20 | 21 | #endif /* SECP256K1_ECDSA_H */ 22 | -------------------------------------------------------------------------------- /Sources/secp256k1/eckey.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECKEY_H 8 | #define SECP256K1_ECKEY_H 9 | 10 | #include 11 | 12 | #include "group.h" 13 | #include "scalar.h" 14 | #include "ecmult.h" 15 | #include "ecmult_gen.h" 16 | 17 | static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size); 18 | static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed); 19 | 20 | static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak); 21 | static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); 22 | static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak); 23 | static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); 24 | 25 | #endif /* SECP256K1_ECKEY_H */ 26 | -------------------------------------------------------------------------------- /Sources/secp256k1/eckey_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECKEY_IMPL_H 8 | #define SECP256K1_ECKEY_IMPL_H 9 | 10 | #include "eckey.h" 11 | 12 | #include "scalar.h" 13 | #include "field.h" 14 | #include "group.h" 15 | #include "ecmult_gen.h" 16 | 17 | static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) { 18 | if (size == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) { 19 | secp256k1_fe x; 20 | return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD); 21 | } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) { 22 | secp256k1_fe x, y; 23 | if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { 24 | return 0; 25 | } 26 | secp256k1_ge_set_xy(elem, &x, &y); 27 | if ((pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD) && 28 | secp256k1_fe_is_odd(&y) != (pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { 29 | return 0; 30 | } 31 | return secp256k1_ge_is_valid_var(elem); 32 | } else { 33 | return 0; 34 | } 35 | } 36 | 37 | static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) { 38 | if (secp256k1_ge_is_infinity(elem)) { 39 | return 0; 40 | } 41 | secp256k1_fe_normalize_var(&elem->x); 42 | secp256k1_fe_normalize_var(&elem->y); 43 | secp256k1_fe_get_b32(&pub[1], &elem->x); 44 | if (compressed) { 45 | *size = 33; 46 | pub[0] = secp256k1_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN; 47 | } else { 48 | *size = 65; 49 | pub[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED; 50 | secp256k1_fe_get_b32(&pub[33], &elem->y); 51 | } 52 | return 1; 53 | } 54 | 55 | static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) { 56 | secp256k1_scalar_add(key, key, tweak); 57 | if (secp256k1_scalar_is_zero(key)) { 58 | return 0; 59 | } 60 | return 1; 61 | } 62 | 63 | static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { 64 | secp256k1_gej pt; 65 | secp256k1_scalar one; 66 | secp256k1_gej_set_ge(&pt, key); 67 | secp256k1_scalar_set_int(&one, 1); 68 | secp256k1_ecmult(ctx, &pt, &pt, &one, tweak); 69 | 70 | if (secp256k1_gej_is_infinity(&pt)) { 71 | return 0; 72 | } 73 | secp256k1_ge_set_gej(key, &pt); 74 | return 1; 75 | } 76 | 77 | static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak) { 78 | if (secp256k1_scalar_is_zero(tweak)) { 79 | return 0; 80 | } 81 | 82 | secp256k1_scalar_mul(key, key, tweak); 83 | return 1; 84 | } 85 | 86 | static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { 87 | secp256k1_scalar zero; 88 | secp256k1_gej pt; 89 | if (secp256k1_scalar_is_zero(tweak)) { 90 | return 0; 91 | } 92 | 93 | secp256k1_scalar_set_int(&zero, 0); 94 | secp256k1_gej_set_ge(&pt, key); 95 | secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero); 96 | secp256k1_ge_set_gej(key, &pt); 97 | return 1; 98 | } 99 | 100 | #endif /* SECP256K1_ECKEY_IMPL_H */ 101 | -------------------------------------------------------------------------------- /Sources/secp256k1/ecmult.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_H 8 | #define SECP256K1_ECMULT_H 9 | 10 | #include "num.h" 11 | #include "group.h" 12 | #include "scalar.h" 13 | #include "scratch.h" 14 | 15 | typedef struct { 16 | /* For accelerating the computation of a*P + b*G: */ 17 | secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */ 18 | #ifdef USE_ENDOMORPHISM 19 | secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */ 20 | #endif 21 | } secp256k1_ecmult_context; 22 | 23 | static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx); 24 | static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb); 25 | static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, 26 | const secp256k1_ecmult_context *src, const secp256k1_callback *cb); 27 | static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx); 28 | static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx); 29 | 30 | /** Double multiply: R = na*A + ng*G */ 31 | static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng); 32 | 33 | typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data); 34 | 35 | /** 36 | * Multi-multiply: R = inp_g_sc * G + sum_i ni * Ai. 37 | * Chooses the right algorithm for a given number of points and scratch space 38 | * size. Resets and overwrites the given scratch space. If the points do not 39 | * fit in the scratch space the algorithm is repeatedly run with batches of 40 | * points. 41 | * Returns: 1 on success (including when inp_g_sc is NULL and n is 0) 42 | * 0 if there is not enough scratch space for a single point or 43 | * callback returns 0 44 | */ 45 | static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n); 46 | 47 | #endif /* SECP256K1_ECMULT_H */ 48 | -------------------------------------------------------------------------------- /Sources/secp256k1/ecmult_const.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_CONST_H 8 | #define SECP256K1_ECMULT_CONST_H 9 | 10 | #include "scalar.h" 11 | #include "group.h" 12 | 13 | /* Here `bits` should be set to the maximum bitlength of the _absolute value_ of `q`, plus 14 | * one because we internally sometimes add 2 to the number during the WNAF conversion. */ 15 | static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q, int bits); 16 | 17 | #endif /* SECP256K1_ECMULT_CONST_H */ 18 | -------------------------------------------------------------------------------- /Sources/secp256k1/ecmult_gen.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_GEN_H 8 | #define SECP256K1_ECMULT_GEN_H 9 | 10 | #include "scalar.h" 11 | #include "group.h" 12 | 13 | typedef struct { 14 | /* For accelerating the computation of a*G: 15 | * To harden against timing attacks, use the following mechanism: 16 | * * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63. 17 | * * Compute sum(n_i * 16^i * G + U_i, i=0..63), where: 18 | * * U_i = U * 2^i (for i=0..62) 19 | * * U_i = U * (1-2^63) (for i=63) 20 | * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0..63) = 0. 21 | * For each i, and each of the 16 possible values of n_i, (n_i * 16^i * G + U_i) is 22 | * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63). 23 | * None of the resulting prec group elements have a known scalar, and neither do any of 24 | * the intermediate sums while computing a*G. 25 | */ 26 | secp256k1_ge_storage (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ 27 | secp256k1_scalar blind; 28 | secp256k1_gej initial; 29 | } secp256k1_ecmult_gen_context; 30 | 31 | static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context* ctx); 32 | static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, const secp256k1_callback* cb); 33 | static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, 34 | const secp256k1_ecmult_gen_context* src, const secp256k1_callback* cb); 35 | static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); 36 | static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx); 37 | 38 | /** Multiply with the generator: R = a*G */ 39 | static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); 40 | 41 | static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32); 42 | 43 | #endif /* SECP256K1_ECMULT_GEN_H */ 44 | -------------------------------------------------------------------------------- /Sources/secp256k1/field_10x26.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_FIELD_REPR_H 8 | #define SECP256K1_FIELD_REPR_H 9 | 10 | #include 11 | 12 | typedef struct { 13 | /* X = sum(i=0..9, elem[i]*2^26) mod n */ 14 | uint32_t n[10]; 15 | #ifdef VERIFY 16 | int magnitude; 17 | int normalized; 18 | #endif 19 | } secp256k1_fe; 20 | 21 | /* Unpacks a constant into a overlapping multi-limbed FE element. */ 22 | #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ 23 | (d0) & 0x3FFFFFFUL, \ 24 | (((uint32_t)d0) >> 26) | (((uint32_t)(d1) & 0xFFFFFUL) << 6), \ 25 | (((uint32_t)d1) >> 20) | (((uint32_t)(d2) & 0x3FFFUL) << 12), \ 26 | (((uint32_t)d2) >> 14) | (((uint32_t)(d3) & 0xFFUL) << 18), \ 27 | (((uint32_t)d3) >> 8) | (((uint32_t)(d4) & 0x3UL) << 24), \ 28 | (((uint32_t)d4) >> 2) & 0x3FFFFFFUL, \ 29 | (((uint32_t)d4) >> 28) | (((uint32_t)(d5) & 0x3FFFFFUL) << 4), \ 30 | (((uint32_t)d5) >> 22) | (((uint32_t)(d6) & 0xFFFFUL) << 10), \ 31 | (((uint32_t)d6) >> 16) | (((uint32_t)(d7) & 0x3FFUL) << 16), \ 32 | (((uint32_t)d7) >> 10) \ 33 | } 34 | 35 | #ifdef VERIFY 36 | #define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} 37 | #else 38 | #define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} 39 | #endif 40 | 41 | typedef struct { 42 | uint32_t n[8]; 43 | } secp256k1_fe_storage; 44 | 45 | #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }} 46 | #define SECP256K1_FE_STORAGE_CONST_GET(d) d.n[7], d.n[6], d.n[5], d.n[4],d.n[3], d.n[2], d.n[1], d.n[0] 47 | 48 | #endif /* SECP256K1_FIELD_REPR_H */ 49 | -------------------------------------------------------------------------------- /Sources/secp256k1/field_5x52.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_FIELD_REPR_H 8 | #define SECP256K1_FIELD_REPR_H 9 | 10 | #include 11 | 12 | typedef struct { 13 | /* X = sum(i=0..4, elem[i]*2^52) mod n */ 14 | uint64_t n[5]; 15 | #ifdef VERIFY 16 | int magnitude; 17 | int normalized; 18 | #endif 19 | } secp256k1_fe; 20 | 21 | /* Unpacks a constant into a overlapping multi-limbed FE element. */ 22 | #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ 23 | (d0) | (((uint64_t)(d1) & 0xFFFFFUL) << 32), \ 24 | ((uint64_t)(d1) >> 20) | (((uint64_t)(d2)) << 12) | (((uint64_t)(d3) & 0xFFUL) << 44), \ 25 | ((uint64_t)(d3) >> 8) | (((uint64_t)(d4) & 0xFFFFFFFUL) << 24), \ 26 | ((uint64_t)(d4) >> 28) | (((uint64_t)(d5)) << 4) | (((uint64_t)(d6) & 0xFFFFUL) << 36), \ 27 | ((uint64_t)(d6) >> 16) | (((uint64_t)(d7)) << 16) \ 28 | } 29 | 30 | #ifdef VERIFY 31 | #define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} 32 | #else 33 | #define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} 34 | #endif 35 | 36 | typedef struct { 37 | uint64_t n[4]; 38 | } secp256k1_fe_storage; 39 | 40 | #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \ 41 | (d0) | (((uint64_t)(d1)) << 32), \ 42 | (d2) | (((uint64_t)(d3)) << 32), \ 43 | (d4) | (((uint64_t)(d5)) << 32), \ 44 | (d6) | (((uint64_t)(d7)) << 32) \ 45 | }} 46 | 47 | #endif /* SECP256K1_FIELD_REPR_H */ 48 | -------------------------------------------------------------------------------- /Sources/secp256k1/hash.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_HASH_H 8 | #define SECP256K1_HASH_H 9 | 10 | #include 11 | #include 12 | 13 | typedef struct { 14 | uint32_t s[8]; 15 | uint32_t buf[16]; /* In big endian */ 16 | size_t bytes; 17 | } secp256k1_sha256; 18 | 19 | static void secp256k1_sha256_initialize(secp256k1_sha256 *hash); 20 | static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size); 21 | static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32); 22 | 23 | typedef struct { 24 | secp256k1_sha256 inner, outer; 25 | } secp256k1_hmac_sha256; 26 | 27 | static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size); 28 | static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size); 29 | static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32); 30 | 31 | typedef struct { 32 | unsigned char v[32]; 33 | unsigned char k[32]; 34 | int retry; 35 | } secp256k1_rfc6979_hmac_sha256; 36 | 37 | static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); 38 | static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); 39 | static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng); 40 | 41 | #endif /* SECP256K1_HASH_H */ 42 | -------------------------------------------------------------------------------- /Sources/secp256k1/num.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_NUM_H 8 | #define SECP256K1_NUM_H 9 | 10 | #ifndef USE_NUM_NONE 11 | 12 | #include "secp256k1-config.h" 13 | 14 | #if defined(USE_NUM_GMP) 15 | #include "num_gmp.h" 16 | #else 17 | #error "Please select num implementation" 18 | #endif 19 | 20 | /** Copy a number. */ 21 | static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a); 22 | 23 | /** Convert a number's absolute value to a binary big-endian string. 24 | * There must be enough place. */ 25 | static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a); 26 | 27 | /** Set a number to the value of a binary big-endian string. */ 28 | static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen); 29 | 30 | /** Compute a modular inverse. The input must be less than the modulus. */ 31 | static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m); 32 | 33 | /** Compute the jacobi symbol (a|b). b must be positive and odd. */ 34 | static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b); 35 | 36 | /** Compare the absolute value of two numbers. */ 37 | static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b); 38 | 39 | /** Test whether two number are equal (including sign). */ 40 | static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b); 41 | 42 | /** Add two (signed) numbers. */ 43 | static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 44 | 45 | /** Subtract two (signed) numbers. */ 46 | static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 47 | 48 | /** Multiply two (signed) numbers. */ 49 | static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 50 | 51 | /** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1, 52 | even if r was negative. */ 53 | static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m); 54 | 55 | /** Right-shift the passed number by bits bits. */ 56 | static void secp256k1_num_shift(secp256k1_num *r, int bits); 57 | 58 | /** Check whether a number is zero. */ 59 | static int secp256k1_num_is_zero(const secp256k1_num *a); 60 | 61 | /** Check whether a number is one. */ 62 | static int secp256k1_num_is_one(const secp256k1_num *a); 63 | 64 | /** Check whether a number is strictly negative. */ 65 | static int secp256k1_num_is_neg(const secp256k1_num *a); 66 | 67 | /** Change a number's sign. */ 68 | static void secp256k1_num_negate(secp256k1_num *r); 69 | 70 | #endif 71 | 72 | #endif /* SECP256K1_NUM_H */ 73 | -------------------------------------------------------------------------------- /Sources/secp256k1/num_gmp.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_NUM_REPR_H 8 | #define SECP256K1_NUM_REPR_H 9 | 10 | #include 11 | 12 | #define NUM_LIMBS ((256+GMP_NUMB_BITS-1)/GMP_NUMB_BITS) 13 | 14 | typedef struct { 15 | mp_limb_t data[2*NUM_LIMBS]; 16 | int neg; 17 | int limbs; 18 | } secp256k1_num; 19 | 20 | #endif /* SECP256K1_NUM_REPR_H */ 21 | -------------------------------------------------------------------------------- /Sources/secp256k1/num_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_NUM_IMPL_H 8 | #define SECP256K1_NUM_IMPL_H 9 | 10 | #include "secp256k1-config.h" 11 | 12 | #include "num.h" 13 | 14 | #if defined(USE_NUM_GMP) 15 | #include "num_gmp_impl.h" 16 | #elif defined(USE_NUM_NONE) 17 | /* Nothing. */ 18 | #else 19 | #error "Please select num implementation" 20 | #endif 21 | 22 | #endif /* SECP256K1_NUM_IMPL_H */ 23 | -------------------------------------------------------------------------------- /Sources/secp256k1/scalar_4x64.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef struct { 14 | uint64_t d[4]; 15 | } secp256k1_scalar; 16 | 17 | #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}} 18 | 19 | #endif /* SECP256K1_SCALAR_REPR_H */ 20 | -------------------------------------------------------------------------------- /Sources/secp256k1/scalar_8x32.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef struct { 14 | uint32_t d[8]; 15 | } secp256k1_scalar; 16 | 17 | #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)}} 18 | 19 | #endif /* SECP256K1_SCALAR_REPR_H */ 20 | -------------------------------------------------------------------------------- /Sources/secp256k1/scalar_low.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef uint32_t secp256k1_scalar; 14 | 15 | #endif /* SECP256K1_SCALAR_REPR_H */ 16 | -------------------------------------------------------------------------------- /Sources/secp256k1/scratch.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2017 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef _SECP256K1_SCRATCH_ 8 | #define _SECP256K1_SCRATCH_ 9 | 10 | #define SECP256K1_SCRATCH_MAX_FRAMES 5 11 | 12 | /* The typedef is used internally; the struct name is used in the public API 13 | * (where it is exposed as a different typedef) */ 14 | typedef struct secp256k1_scratch_space_struct { 15 | void *data[SECP256K1_SCRATCH_MAX_FRAMES]; 16 | size_t offset[SECP256K1_SCRATCH_MAX_FRAMES]; 17 | size_t frame_size[SECP256K1_SCRATCH_MAX_FRAMES]; 18 | size_t frame; 19 | size_t max_size; 20 | const secp256k1_callback* error_callback; 21 | } secp256k1_scratch; 22 | 23 | static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size); 24 | 25 | static void secp256k1_scratch_destroy(secp256k1_scratch* scratch); 26 | 27 | /** Attempts to allocate a new stack frame with `n` available bytes. Returns 1 on success, 0 on failure */ 28 | static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects); 29 | 30 | /** Deallocates a stack frame */ 31 | static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch); 32 | 33 | /** Returns the maximum allocation the scratch space will allow */ 34 | static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t n_objects); 35 | 36 | /** Returns a pointer into the most recently allocated frame, or NULL if there is insufficient available space */ 37 | static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t n); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /Sources/secp256k1/scratch_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2017 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef _SECP256K1_SCRATCH_IMPL_H_ 8 | #define _SECP256K1_SCRATCH_IMPL_H_ 9 | 10 | #include "scratch.h" 11 | 12 | /* Using 16 bytes alignment because common architectures never have alignment 13 | * requirements above 8 for any of the types we care about. In addition we 14 | * leave some room because currently we don't care about a few bytes. 15 | * TODO: Determine this at configure time. */ 16 | #define ALIGNMENT 16 17 | 18 | static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size) { 19 | secp256k1_scratch* ret = (secp256k1_scratch*)checked_malloc(error_callback, sizeof(*ret)); 20 | if (ret != NULL) { 21 | memset(ret, 0, sizeof(*ret)); 22 | ret->max_size = max_size; 23 | ret->error_callback = error_callback; 24 | } 25 | return ret; 26 | } 27 | 28 | static void secp256k1_scratch_destroy(secp256k1_scratch* scratch) { 29 | if (scratch != NULL) { 30 | VERIFY_CHECK(scratch->frame == 0); 31 | free(scratch); 32 | } 33 | } 34 | 35 | static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t objects) { 36 | size_t i = 0; 37 | size_t allocated = 0; 38 | for (i = 0; i < scratch->frame; i++) { 39 | allocated += scratch->frame_size[i]; 40 | } 41 | if (scratch->max_size - allocated <= objects * ALIGNMENT) { 42 | return 0; 43 | } 44 | return scratch->max_size - allocated - objects * ALIGNMENT; 45 | } 46 | 47 | static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects) { 48 | VERIFY_CHECK(scratch->frame < SECP256K1_SCRATCH_MAX_FRAMES); 49 | 50 | if (n <= secp256k1_scratch_max_allocation(scratch, objects)) { 51 | n += objects * ALIGNMENT; 52 | scratch->data[scratch->frame] = checked_malloc(scratch->error_callback, n); 53 | if (scratch->data[scratch->frame] == NULL) { 54 | return 0; 55 | } 56 | scratch->frame_size[scratch->frame] = n; 57 | scratch->offset[scratch->frame] = 0; 58 | scratch->frame++; 59 | return 1; 60 | } else { 61 | return 0; 62 | } 63 | } 64 | 65 | static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch) { 66 | VERIFY_CHECK(scratch->frame > 0); 67 | scratch->frame -= 1; 68 | free(scratch->data[scratch->frame]); 69 | } 70 | 71 | static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t size) { 72 | void *ret; 73 | size_t frame = scratch->frame - 1; 74 | size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT; 75 | 76 | if (scratch->frame == 0 || size + scratch->offset[frame] > scratch->frame_size[frame]) { 77 | return NULL; 78 | } 79 | ret = (void *) ((unsigned char *) scratch->data[frame] + scratch->offset[frame]); 80 | memset(ret, 0, size); 81 | scratch->offset[frame] += size; 82 | 83 | return ret; 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /Sources/secp256k1/secp256k1_main.h: -------------------------------------------------------------------------------- 1 | //! Project version number for secp256k1. 2 | FOUNDATION_EXPORT double secp256k1VersionNumber; 3 | 4 | //! Project version string for secp256k1. 5 | FOUNDATION_EXPORT const unsigned char secp256k1VersionString[]; 6 | -------------------------------------------------------------------------------- /Sources/secp256k1/util.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_UTIL_H 8 | #define SECP256K1_UTIL_H 9 | 10 | #include "secp256k1-config.h" 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | typedef struct { 17 | void (*fn)(const char *text, void* data); 18 | const void* data; 19 | } secp256k1_callback; 20 | 21 | static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * const cb, const char * const text) { 22 | cb->fn(text, (void*)cb->data); 23 | } 24 | 25 | #ifdef DETERMINISTIC 26 | #define TEST_FAILURE(msg) do { \ 27 | fprintf(stderr, "%s\n", msg); \ 28 | abort(); \ 29 | } while(0); 30 | #else 31 | #define TEST_FAILURE(msg) do { \ 32 | fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \ 33 | abort(); \ 34 | } while(0) 35 | #endif 36 | 37 | #ifdef HAVE_BUILTIN_EXPECT 38 | #define EXPECT(x,c) __builtin_expect((x),(c)) 39 | #else 40 | #define EXPECT(x,c) (x) 41 | #endif 42 | 43 | #ifdef DETERMINISTIC 44 | #define CHECK(cond) do { \ 45 | if (EXPECT(!(cond), 0)) { \ 46 | TEST_FAILURE("test condition failed"); \ 47 | } \ 48 | } while(0) 49 | #else 50 | #define CHECK(cond) do { \ 51 | if (EXPECT(!(cond), 0)) { \ 52 | TEST_FAILURE("test condition failed: " #cond); \ 53 | } \ 54 | } while(0) 55 | #endif 56 | 57 | /* Like assert(), but when VERIFY is defined, and side-effect safe. */ 58 | #if defined(COVERAGE) 59 | #define VERIFY_CHECK(check) 60 | #define VERIFY_SETUP(stmt) 61 | #elif defined(VERIFY) 62 | #define VERIFY_CHECK CHECK 63 | #define VERIFY_SETUP(stmt) do { stmt; } while(0) 64 | #else 65 | #define VERIFY_CHECK(cond) do { (void)(cond); } while(0) 66 | #define VERIFY_SETUP(stmt) 67 | #endif 68 | 69 | static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_t size) { 70 | void *ret = malloc(size); 71 | if (ret == NULL) { 72 | secp256k1_callback_call(cb, "Out of memory"); 73 | } 74 | return ret; 75 | } 76 | 77 | static SECP256K1_INLINE void *checked_realloc(const secp256k1_callback* cb, void *ptr, size_t size) { 78 | void *ret = realloc(ptr, size); 79 | if (ret == NULL) { 80 | secp256k1_callback_call(cb, "Out of memory"); 81 | } 82 | return ret; 83 | } 84 | 85 | /* Macro for restrict, when available and not in a VERIFY build. */ 86 | #if defined(SECP256K1_BUILD) && defined(VERIFY) 87 | # define SECP256K1_RESTRICT 88 | #else 89 | # if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) 90 | # if SECP256K1_GNUC_PREREQ(3,0) 91 | # define SECP256K1_RESTRICT __restrict__ 92 | # elif (defined(_MSC_VER) && _MSC_VER >= 1400) 93 | # define SECP256K1_RESTRICT __restrict 94 | # else 95 | # define SECP256K1_RESTRICT 96 | # endif 97 | # else 98 | # define SECP256K1_RESTRICT restrict 99 | # endif 100 | #endif 101 | 102 | #if defined(_WIN32) 103 | # define I64FORMAT "I64d" 104 | # define I64uFORMAT "I64u" 105 | #else 106 | # define I64FORMAT "lld" 107 | # define I64uFORMAT "llu" 108 | #endif 109 | 110 | #if defined(HAVE___INT128) 111 | # if defined(__GNUC__) 112 | # define SECP256K1_GNUC_EXT __extension__ 113 | # else 114 | # define SECP256K1_GNUC_EXT 115 | # endif 116 | SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; 117 | #endif 118 | 119 | #endif /* SECP256K1_UTIL_H */ 120 | -------------------------------------------------------------------------------- /Sources/web3swift/ABIv2/ABIv2.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ABIv2.swift 3 | // web3swift 4 | // 5 | // Created by Alexander Vlasov on 02.04.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Element type protocol 12 | protocol ABIv2ElementPropertiesProtocol { 13 | /// Returns true if array is has fixed length 14 | var isStatic: Bool { get } 15 | /// Returns true if type is array 16 | var isArray: Bool { get } 17 | /// Returns true if type is tuple 18 | var isTuple: Bool { get } 19 | /// Returns array size if type 20 | var arraySize: ABIv2.Element.ArraySize { get } 21 | /// Returns subtype of array 22 | var subtype: ABIv2.Element.ParameterType? { get } 23 | /// Returns memory usage of type 24 | var memoryUsage: UInt64 { get } 25 | /// Returns default empty value for type 26 | var emptyValue: Any { get } 27 | } 28 | 29 | protocol ABIv2Encoding { 30 | var abiRepresentation: String { get } 31 | } 32 | 33 | protocol ABIv2Validation { 34 | var isValid: Bool { get } 35 | } 36 | 37 | /// Parses smart contract json abi to work with smart contract's functions 38 | public struct ABIv2 {} 39 | -------------------------------------------------------------------------------- /Sources/web3swift/Contract/ComparisonExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ComparisonExtensions.swift 3 | // web3swift 4 | // 5 | // Created by Alexander Vlasov on 09.05.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import BigInt 10 | import Foundation 11 | 12 | extension BigUInt: EventFilterComparable { 13 | public func isEqualTo(_ other: AnyObject) -> Bool { 14 | switch other { 15 | case let oth as BigUInt: 16 | return self == oth 17 | case let oth as BigInt: 18 | return magnitude == oth.magnitude && signum() == oth.signum() 19 | default: 20 | return false 21 | } 22 | } 23 | } 24 | 25 | extension BigInt: EventFilterComparable { 26 | public func isEqualTo(_ other: AnyObject) -> Bool { 27 | switch other { 28 | case let oth as BigInt: 29 | return self == oth 30 | case let oth as BigUInt: 31 | return magnitude == oth.magnitude && signum() == oth.signum() 32 | default: 33 | return false 34 | } 35 | } 36 | } 37 | 38 | extension String: EventFilterComparable { 39 | public func isEqualTo(_ other: AnyObject) -> Bool { 40 | switch other { 41 | case let oth as String: 42 | return data.keccak256() == oth.data.keccak256() 43 | case let oth as Data: 44 | return data.keccak256() == oth.keccak256() 45 | default: 46 | return false 47 | } 48 | } 49 | } 50 | 51 | extension Data: EventFilterComparable { 52 | public func isEqualTo(_ other: AnyObject) -> Bool { 53 | switch other { 54 | case let oth as String: 55 | guard let data = Data.fromHex(oth) else { return false } 56 | if self == data { 57 | return true 58 | } 59 | let hash = data.keccak256() 60 | return self == hash 61 | case let oth as Data: 62 | if self == oth { 63 | return true 64 | } 65 | let hash = oth.keccak256() 66 | return self == hash 67 | default: 68 | return false 69 | } 70 | } 71 | } 72 | 73 | extension Address: EventFilterComparable { 74 | public func isEqualTo(_ other: AnyObject) -> Bool { 75 | switch other { 76 | case let oth as String: 77 | let addr = Address(oth) 78 | return self == addr 79 | case let oth as Data: 80 | let addr = Address(oth) 81 | return self == addr 82 | case let oth as Address: 83 | return self == oth 84 | default: 85 | return false 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Sources/web3swift/Contract/EthereumFilterEncodingExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EthereumStringEncodingExtensions.swift 3 | // web3swift 4 | // 5 | // Created by Alexander Vlasov on 09.05.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import BigInt 10 | import Foundation 11 | 12 | extension BigUInt: EventFilterEncodable { 13 | public func eventFilterEncoded() -> String? { 14 | return abiEncode(bits: 256)?.hex.withHex 15 | } 16 | } 17 | 18 | extension BigInt: EventFilterEncodable { 19 | public func eventFilterEncoded() -> String? { 20 | return abiEncode(bits: 256)?.hex.withHex 21 | } 22 | } 23 | 24 | extension Data: EventFilterEncodable { 25 | public func eventFilterEncoded() -> String? { 26 | guard let padded = self.setLengthLeft(32) else { return nil } 27 | return padded.hex.withHex 28 | } 29 | } 30 | 31 | extension Address: EventFilterEncodable { 32 | public func eventFilterEncoded() -> String? { 33 | guard let padded = self.addressData.setLengthLeft(32) else { return nil } 34 | return padded.hex.withHex 35 | } 36 | } 37 | 38 | extension String: EventFilterEncodable { 39 | public func eventFilterEncoded() -> String? { 40 | return data.keccak256().hex.withHex 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Sources/web3swift/Convenience/Array+Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Array+Extension.swift 3 | // web3swift 4 | // 5 | // Created by Alexander Vlasov on 15.01.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Array { 12 | /// Splits array by chunks 13 | /// - Parameter chunkSize: Size of each subarray 14 | public func split(intoChunksOf chunkSize: Int) -> [[Element]] { 15 | return stride(from: 0, to: count, by: chunkSize).map { 16 | let endIndex = ($0.advanced(by: chunkSize) > self.count) ? self.count - $0 : chunkSize 17 | return Array(self[$0 ..< $0.advanced(by: endIndex)]) 18 | } 19 | } 20 | func safe(_ index: Int) -> Element? { 21 | guard (0.. Bound? { 40 | guard lowerBound + 1 < upperBound else { return nil } 41 | self = lowerBound+1.. 50 | /// Returns an iterator over the elements of this sequence. 51 | public func makeIterator() -> Range { 52 | return -1.. [String: GroupNamesSearchResult] { 15 | var groupnames = [String: GroupNamesSearchResult]() 16 | 17 | guard let greg = try? NSRegularExpression(pattern: "^\\(\\?<([\\w\\a_-]*)>$", options: NSRegularExpression.Options.dotMatchesLineSeparators) else { 18 | // This never happens but the alternative is to make this method throwing 19 | return groupnames 20 | } 21 | guard let reg = try? NSRegularExpression(pattern: "\\(.*?>", options: NSRegularExpression.Options.dotMatchesLineSeparators) else { 22 | // This never happens but the alternative is to make this method throwing 23 | return groupnames 24 | } 25 | let m = reg.matches(in: pattern, options: NSRegularExpression.MatchingOptions.withTransparentBounds, range: NSRange(location: 0, length: pattern.utf16.count)) 26 | for (n, g) in m.enumerated() { 27 | let r = pattern.range(from: g.range(at: 0)) 28 | let gstring = String(pattern[r!]) 29 | let gmatch = greg.matches(in: gstring, options: NSRegularExpression.MatchingOptions.anchored, range: NSRange(location: 0, length: gstring.utf16.count)) 30 | if gmatch.count > 0 { 31 | let r2 = gstring.range(from: gmatch[0].range(at: 1))! 32 | groupnames[String(gstring[r2])] = (g, gmatch[0], n) 33 | } 34 | } 35 | return groupnames 36 | } 37 | 38 | func indexOfNamedCaptureGroups() throws -> [String: Int] { 39 | var groupnames = [String: Int]() 40 | for (name, (_, _, n)) in textCheckingResultsOfNamedCaptureGroups() { 41 | groupnames[name] = n + 1 42 | } 43 | return groupnames 44 | } 45 | 46 | func rangesOfNamedCaptureGroups(match: NSTextCheckingResult) throws -> [String: Range] { 47 | var ranges = [String: Range]() 48 | for (name, (_, _, n)) in textCheckingResultsOfNamedCaptureGroups() { 49 | ranges[name] = Range(match.range(at: n + 1)) 50 | } 51 | return ranges 52 | } 53 | 54 | private func nameForIndex(_ index: Int, from: [String: GroupNamesSearchResult]) -> String? { 55 | for (name, (_, _, n)) in from { 56 | if (n + 1) == index { 57 | return name 58 | } 59 | } 60 | return nil 61 | } 62 | 63 | func captureGroups(string: String, options: NSRegularExpression.MatchingOptions = []) -> [String: String] { 64 | return captureGroups(string: string, options: options, range: NSRange(location: 0, length: string.utf16.count)) 65 | } 66 | 67 | func captureGroups(string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> [String: String] { 68 | var dict = [String: String]() 69 | let matchResult = matches(in: string, options: options, range: range) 70 | let names = textCheckingResultsOfNamedCaptureGroups() 71 | for (_, m) in matchResult.enumerated() { 72 | for i in 0 ..< m.numberOfRanges { 73 | guard let r2 = string.range(from: m.range(at: i)) else { continue } 74 | let g = String(string[r2]) 75 | if let name = nameForIndex(i, from: names) { 76 | dict[name] = g 77 | } 78 | } 79 | } 80 | return dict 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Sources/web3swift/Convenience/NativeTypesEncoding+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NativeTypesEncoding+Extensions.swift 3 | // web3swift 4 | // 5 | // Created by Alexander Vlasov on 03.04.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import BigInt 10 | import Foundation 11 | 12 | public extension Data { 13 | /// Sets data.count to toBytes and fills missing bytes at the start of the data 14 | /// - Parameter toBytes: Desired data size 15 | /// - Parameter isNegative: Fills with ff if negative. default: false 16 | /// - Returns: Data with desired size 17 | func setLengthLeft(_ toBytes: UInt64, isNegative: Bool = false) -> Data? { 18 | let existingLength = UInt64(count) 19 | if existingLength == toBytes { 20 | return Data(self) 21 | } else if existingLength > toBytes { 22 | return nil 23 | } 24 | var data: Data 25 | if isNegative { 26 | data = Data(repeating: UInt8(255), count: Int(toBytes - existingLength)) 27 | } else { 28 | data = Data(repeating: UInt8(0), count: Int(toBytes - existingLength)) 29 | } 30 | data.append(self) 31 | return data 32 | } 33 | 34 | /// Sets data.count to toBytes and fills missing bytes at the end of the data 35 | /// - Parameter toBytes: Desired data size 36 | /// - Parameter isNegative: Fills with ff if negative. default: false 37 | /// - Returns: Data with desired size 38 | func setLengthRight(_ toBytes: UInt64, isNegative: Bool = false) -> Data? { 39 | let existingLength = UInt64(count) 40 | if existingLength == toBytes { 41 | return Data(self) 42 | } else if existingLength > toBytes { 43 | return nil 44 | } 45 | var data: Data = Data() 46 | data.append(self) 47 | if isNegative { 48 | data.append(Data(repeating: UInt8(255), count: Int(toBytes - existingLength))) 49 | } else { 50 | data.append(Data(repeating: UInt8(0), count: Int(toBytes - existingLength))) 51 | } 52 | return data 53 | } 54 | } 55 | 56 | public extension BigInt { 57 | /// Converts int to data 58 | func toTwosComplement() -> Data { 59 | if sign == BigInt.Sign.plus { 60 | return magnitude.serialize() 61 | } else { 62 | let serializedLength = magnitude.serialize().count 63 | let MAX = BigUInt(1) << (serializedLength * 8) 64 | let twoComplement = MAX - magnitude 65 | return twoComplement.serialize() 66 | } 67 | } 68 | 69 | /// - Returns: Fixed size data of number 70 | func abiEncode(bits: UInt64) -> Data! { 71 | let isNegative = self < (BigInt(0)) 72 | let data = toTwosComplement() 73 | let paddedLength = UInt64(ceil((Double(bits) / 8.0))) 74 | let padded = data.setLengthLeft(paddedLength, isNegative: isNegative)! 75 | return padded 76 | } 77 | 78 | /// Converts data to BigInt 79 | static func fromTwosComplement(data: Data) -> BigInt { 80 | let isPositive = ((data[0] & 128) >> 7) == 0 81 | if isPositive { 82 | let magnitude = BigUInt(data) 83 | return BigInt(magnitude) 84 | } else { 85 | let MAX = (BigUInt(1) << (data.count * 8)) 86 | let magnitude = MAX - BigUInt(data) 87 | let bigint = BigInt(0) - BigInt(magnitude) 88 | return bigint 89 | } 90 | } 91 | } 92 | 93 | public extension BigUInt { 94 | /// - Returns: Fixed size data of number 95 | func abiEncode(bits: UInt64) -> Data? { 96 | let data = serialize() 97 | let paddedLength = UInt64(ceil((Double(bits) / 8.0))) 98 | let padded = data.setLengthLeft(paddedLength) 99 | return padded 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Sources/web3swift/Encryption/Cryptor/Crypto.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Crypto.swift 3 | // Cryptor 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | 18 | import Foundation 19 | 20 | /// 21 | /// Implements a simplified API for calculating digests over single buffers 22 | /// 23 | public protocol CryptoDigest { 24 | 25 | /// Calculates a message digest 26 | func digest(using algorithm: Digest.Algorithm) -> Self 27 | } 28 | 29 | /// 30 | /// Extension to the CryptoDigest to return the digest appropriate to the selected algorithm. 31 | /// 32 | extension CryptoDigest { 33 | 34 | /// An MD2 digest of this object 35 | public var md2: Self { 36 | return self.digest(using: .md2) 37 | } 38 | 39 | /// An MD4 digest of this object 40 | public var md4: Self { 41 | return self.digest(using: .md4) 42 | } 43 | 44 | /// An MD5 digest of this object 45 | public var md5: Self { 46 | return self.digest(using: .md5) 47 | } 48 | 49 | /// An SHA1 digest of this object 50 | public var sha1: Self { 51 | return self.digest(using: .sha1) 52 | } 53 | 54 | /// An SHA224 digest of this object 55 | public var sha224: Self { 56 | return self.digest(using: .sha224) 57 | } 58 | 59 | /// An SHA256 digest of this object 60 | public var sha256: Self { 61 | return self.digest(using: .sha256) 62 | } 63 | 64 | /// An SHA384 digest of this object 65 | public var sha384: Self { 66 | return self.digest(using: .sha384) 67 | } 68 | 69 | /// An SHA512 digest of this object 70 | public var sha512: Self { 71 | return self.digest(using: .sha512) 72 | } 73 | } 74 | 75 | /// 76 | /// Extension for Data to return an Data object containing the digest. 77 | /// 78 | extension Data: CryptoDigest { 79 | /// 80 | /// Calculates the Message Digest for this data. 81 | /// 82 | /// - Parameter algorithm: The digest algorithm to use 83 | /// 84 | /// - Returns: An `Data` object containing the message digest 85 | /// 86 | public func digest(using algorithm: Digest.Algorithm) -> Data { 87 | 88 | // This force unwrap may look scary but for CommonCrypto this cannot fail. 89 | // The API allows for optionals to support the OpenSSL implementation which can. 90 | return self.withUnsafeBytes() { (buffer: UnsafePointer) -> Data in 91 | 92 | let result = (Digest(using: algorithm).update(from: buffer, byteCount: self.count)?.final())! 93 | let data = type(of: self).init(bytes: result, count: result.count) 94 | return data 95 | } 96 | } 97 | } 98 | 99 | /// 100 | /// Extension for String to return a String containing the digest. 101 | /// 102 | extension String: CryptoDigest { 103 | /// 104 | /// Calculates the Message Digest for this string. 105 | /// The string is converted to raw data using UTF8. 106 | /// 107 | /// - Parameter algorithm: The digest algorithm to use 108 | /// 109 | /// - Returns: A hex string of the calculated digest 110 | /// 111 | public func digest(using algorithm: Digest.Algorithm) -> String { 112 | 113 | // This force unwrap may look scary but for CommonCrypto this cannot fail. 114 | // The API allows for optionals to support the OpenSSL implementation which can. 115 | let result = (Digest(using: algorithm).update(string: self as String)?.final())! 116 | return CryptoUtils.hexString(from: result) 117 | 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Sources/web3swift/Encryption/Cryptor/Cryptor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Cryptor.swift 3 | // Cryptor 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | 18 | import Foundation 19 | 20 | /// 21 | /// Encrypts or decrypts, accumulating result. 22 | /// 23 | /// Useful for small in-memory buffers. 24 | /// 25 | /// For large files or network streams use StreamCryptor. 26 | /// 27 | public class Cryptor: StreamCryptor, Updatable { 28 | 29 | /// Internal accumulator for gathering data from the update() and final() functions. 30 | var accumulator: [UInt8] = [] 31 | 32 | /// 33 | /// Retrieves the encrypted or decrypted data. 34 | /// 35 | ///- Returns: the encrypted or decrypted data or nil if an error occured. 36 | /// 37 | public func final() -> [UInt8]? { 38 | 39 | let byteCount = Int(self.getOutputLength(inputByteCount: 0, isFinal: true)) 40 | var dataOut = Array(repeating: 0, count:byteCount) 41 | var dataOutMoved = 0 42 | (dataOutMoved, self.status) = final(byteArrayOut: &dataOut) 43 | if self.status != .success { 44 | return nil 45 | } 46 | accumulator += dataOut[0.. Self? { 59 | 60 | let outputLength = Int(self.getOutputLength(inputByteCount: byteCount, isFinal: false)) 61 | var dataOut = Array(repeating: 0, count:outputLength) 62 | var dataOutMoved = 0 63 | _ = update(bufferIn: buffer, byteCountIn: byteCount, bufferOut: &dataOut, byteCapacityOut: dataOut.count, byteCountOut: &dataOutMoved) 64 | if self.status != .success { 65 | return nil 66 | } 67 | accumulator += dataOut[0.., byteCount: Int) -> RNGStatus { 43 | 44 | #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) 45 | let statusCode = CCRandomGenerateBytes(bytes, byteCount) 46 | guard let status = Status(rawValue: statusCode) else { 47 | fatalError("CCRandomGenerateBytes returned unexpected status code: \(statusCode)") 48 | } 49 | return status 50 | #elseif os(Linux) 51 | let statusCode = RAND_bytes(bytes, Int32(byteCount)) 52 | if statusCode != 1 { 53 | 54 | let errCode = ERR_get_error() 55 | return Status.rngFailure(errCode) 56 | } 57 | return Status.success 58 | #endif 59 | } 60 | 61 | /// 62 | /// Generates an array of random bytes. 63 | /// 64 | /// - Parameter bytesCount: Number of random bytes to generate 65 | /// 66 | /// - Returns: an array of random bytes 67 | /// 68 | /// - Throws: `.success` or an `.rngFailure` on failure 69 | /// 70 | public class func generate(byteCount: Int) throws -> [UInt8] { 71 | 72 | guard byteCount > 0 else { 73 | throw RNGStatus.paramError 74 | } 75 | 76 | var bytes = Array(repeating: UInt8(0), count:byteCount) 77 | let status = generate(bytes: &bytes, byteCount: byteCount) 78 | 79 | if status != .success { 80 | throw status 81 | } 82 | 83 | return bytes 84 | } 85 | 86 | /// 87 | /// A version of generateBytes that always throws an error. 88 | /// 89 | /// Use it to test that code handles this. 90 | /// 91 | /// - Parameter bytesCount: Number of random bytes to generate 92 | /// 93 | /// - Returns: An array of random bytes 94 | /// 95 | public class func generateBytesThrow(byteCount: Int) throws -> [UInt8] { 96 | 97 | if byteCount <= 0 { 98 | 99 | fatalError("generate: byteCount must be positve and non-zero") 100 | } 101 | var bytes: [UInt8] = Array(repeating: UInt8(0), count:byteCount) 102 | let status = generate(bytes: &bytes, byteCount: byteCount) 103 | throw status 104 | //return bytes 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Sources/web3swift/Encryption/Cryptor/Updatable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Updateable.swift 3 | // Cryptor 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | 18 | import Foundation 19 | 20 | /// 21 | /// A protocol for calculations that can be updated with incremental data buffers. 22 | /// 23 | public protocol Updatable { 24 | 25 | /// Status of the calculation. 26 | var status: Status { get } 27 | 28 | /// 29 | /// Low-level update routine. 30 | /// Updates the calculation with the contents of a data buffer. 31 | /// 32 | /// - Parameters: 33 | /// - buffer: Pointer to the data buffer 34 | /// - byteCount: Length of the buffer in bytes 35 | /// 36 | /// - Returns: `Self` if no error for optional chaining, nil otherwise 37 | /// 38 | func update(from buffer: UnsafeRawPointer, byteCount: size_t) -> Self? 39 | } 40 | 41 | /// 42 | /// Factors out common update code from Digest, HMAC and Cryptor. 43 | /// 44 | extension Updatable { 45 | /// 46 | /// Updates the current calculation with data contained in an `NSData` object. 47 | /// 48 | /// - Parameter data: The `NSData` object 49 | /// 50 | /// - Returns: Optional `Self` or nil 51 | /// 52 | public func update(data: NSData) -> Self? { 53 | 54 | _ = update(from: data.bytes, byteCount: size_t(data.length)) 55 | return self.status == .success ? self : nil 56 | } 57 | 58 | /// 59 | /// Updates the current calculation with data contained in an `Data` object. 60 | /// 61 | /// - Parameters data: The `Data` object 62 | /// 63 | /// - Returns: Optional `Self` or nil 64 | /// 65 | public func update(data: Data) -> Self? { 66 | 67 | _ = data.withUnsafeBytes() { (buffer: UnsafePointer) in 68 | 69 | _ = update(from: buffer, byteCount: size_t(data.count)) 70 | } 71 | return self.status == .success ? self : nil 72 | } 73 | 74 | /// 75 | /// Updates the current calculation with data contained in a byte array. 76 | /// 77 | /// - Parameter byteArray: The byte array 78 | /// 79 | /// - Returns: Optional `Self` or nil 80 | /// 81 | public func update(byteArray: [UInt8]) -> Self? { 82 | 83 | _ = update(from: byteArray, byteCount: size_t(byteArray.count)) 84 | return self.status == .success ? self : nil 85 | } 86 | 87 | /// 88 | /// Updates the current calculation with data contained in a String. 89 | /// The corresponding data will be generated using UTF8 encoding. 90 | /// 91 | /// - Parameter string: The string of data 92 | /// 93 | /// - Returns: Optional `Self` or nil 94 | /// 95 | public func update(string: String) -> Self? { 96 | 97 | _ = update(from: string, byteCount: size_t(string.utf8.count)) 98 | return self.status == .success ? self : nil 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Sources/web3swift/Encryption/PrivateKey.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PrivateKey.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 29/11/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import BigInt 11 | 12 | /** 13 | Secp256k1 private key. 14 | 15 | Used in ethereum accounts. You can get public key, address and sign some data 16 | 17 | ## Performance 18 | 19 | > Operations per second in debug and release build mode 20 | ``` 21 | Generate Private key: 22 | release debug 23 | 175772 160180 24 | 25 | PrivateKey -> Public Key: 26 | release debug 27 | 26642 9036 28 | 29 | PrivateKey -> Address: 30 | release debug 31 | 11894 2058 32 | ``` 33 | */ 34 | public class PrivateKey { 35 | /// Private key data 36 | public var privateKey: Data 37 | 38 | /// Singleton that generates public key from private key 39 | public lazy var publicKey: Data = try! SECP256K1.privateToPublic(privateKey: privateKey) 40 | 41 | /// Singleton that generates address from public key 42 | public lazy var address: Address = try! Web3Utils.publicToAddress(publicKey) 43 | 44 | /// Generates random private key. All generated keys are verified 45 | public init() { 46 | self.privateKey = .random(length: 32) 47 | } 48 | 49 | /// Init with private key data. run .verify() to verify it 50 | public init(_ privateKey: Data) { 51 | self.privateKey = privateKey 52 | } 53 | 54 | 55 | /// Signs hash with private key signature 56 | /// 57 | /// - Parameter hash: 32 bytes hash. To get hash call data.keccak256() 58 | /// - Returns: Signature that you can use in your transactions 59 | /// - Throws: If hash size invalid hash size or private key. Call privateKey.verify() 60 | public func sign(hash: Data) throws -> Signature { 61 | let signature = try SECP256K1.signForRecovery(hash: hash, privateKey: privateKey).serializedSignature 62 | return Signature(data: signature) 63 | } 64 | 65 | 66 | /// Verifies the private key. Also every 32 byte private keys are valid 67 | /// 68 | /// - Throws: SECP256K1Error.invalidPrivateKey 69 | public func verify() throws { 70 | try SECP256K1.verifyPrivateKey(privateKey: privateKey) 71 | } 72 | } 73 | 74 | 75 | /// Signature of some hash. You can get it by calling PrivateKey.sign(hash:) 76 | public class Signature { 77 | /// Signature data 78 | public let data: Data 79 | 80 | /// Init with data. Don't forget to call .check(compressed:) if you want to init with custom data 81 | /// 82 | /// - Parameter data: Signature data 83 | public init(data: Data) { 84 | self.data = data 85 | } 86 | 87 | 88 | /// Checks for signature 89 | /// 90 | /// - Parameter compressed: Checks for compressed signature (33 bytes long) 91 | /// - Throws: SECP256K1Error.invalidSignatureSize or SECP256DataError.signatureCorrupted 92 | public func check(compressed: Bool = false) throws { 93 | if compressed { 94 | guard data.count == 33 else { throw SECP256K1Error.invalidSignatureSize } 95 | } else { 96 | guard data.count == 65 else { throw SECP256K1Error.invalidSignatureSize } 97 | } 98 | guard v < 4 else { throw SECP256DataError.signatureCorrupted } 99 | } 100 | 101 | /// Signature first 32 bytes 102 | public lazy var r = BigUInt(data[0..<32]) 103 | /// Signature next 32 bytes 104 | public lazy var s = BigUInt(data[32..<64]) 105 | /// Last signature byte. Should be less than 4 106 | public lazy var v: UInt8 = { 107 | var v = data.last! 108 | if v >= 27 { 109 | v = v - 27 110 | } 111 | return v 112 | }() 113 | } 114 | -------------------------------------------------------------------------------- /Sources/web3swift/Encryption/keccak.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 05/12/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import keccak 11 | 12 | extension Data { 13 | var pointer: UnsafePointer! { return withUnsafeBytes { $0 } } 14 | mutating func mutablePointer() -> UnsafeMutablePointer! { 15 | return withUnsafeMutableBytes { $0 } 16 | } 17 | 18 | /// - Returns: kaccak256 hash of data 19 | public func keccak256() -> Data { 20 | var data = Data(count: 32) 21 | keccak_256(data.mutablePointer(), 32, pointer, count) 22 | return data 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/web3swift/Encryption/scrypt.swift: -------------------------------------------------------------------------------- 1 | // 2 | // scrypt.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 05/12/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import scrypt 11 | 12 | public func scrypt(password: String, salt: Data, length: Int, N: Int, R: Int, P: Int) -> Data? { 13 | let password = password.data 14 | var derivedKey = Data(count: length) 15 | let status = crypto_scrypt(password.pointer, password.count, salt.pointer, salt.count, UInt64(N), UInt32(R), UInt32(P), derivedKey.mutablePointer(), derivedKey.count) 16 | guard status == 0 else { return nil } 17 | return derivedKey 18 | } 19 | -------------------------------------------------------------------------------- /Sources/web3swift/Ethereum/InputParameters.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InputParameters.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 20/12/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public enum TopicFilter { 12 | case any, exact(Data), or(Data,Data) 13 | } 14 | 15 | open class TopicFilters: JEncodable { 16 | public var filters = [TopicFilter]() 17 | public init() {} 18 | 19 | open func append(_ filter: TopicFilter) { 20 | self.filters.append(filter) 21 | } 22 | open func jsonRpcValue(with network: NetworkProvider) -> Any { 23 | var mapped = [Any]() 24 | for filter in filters { 25 | switch filter { 26 | case .any: 27 | mapped.append(NSNull()) 28 | case .exact(let data): 29 | mapped.append(data.hex.withHex) 30 | case let .or(a, b): 31 | mapped.append([a.hex.withHex, b.hex.withHex]) 32 | } 33 | } 34 | return mapped 35 | } 36 | } 37 | 38 | 39 | 40 | open class FilterOptions: JEncodable { 41 | /// fromBlock: QUANTITY|TAG - (optional, default: "latest") Integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions. 42 | public var from: BlockNumber? 43 | 44 | /// toBlock: QUANTITY|TAG - (optional, default: "latest") Integer block number, or "latest" for the last mined block or "pending", "earliest" for not yet mined transactions. 45 | public var to: BlockNumber? 46 | 47 | /// address: DATA|Array, 20 Bytes - (optional) Contract address or a list of addresses from which logs should originate. 48 | public var address = [Address]() 49 | 50 | /// topics: Array of DATA, - (optional) Array of 32 Bytes DATA topics. Topics are order-dependent. Each topic can also be an array of DATA with "or" options. 51 | public var topics = TopicFilters() 52 | 53 | init() {} 54 | 55 | public var dictionary: JDictionary { 56 | return JDictionary() 57 | .set("from", from) 58 | .set("to", to) 59 | .set("address", JArray(address).nilIfEmpty()) 60 | .set("topics", topics) 61 | } 62 | 63 | public func jsonRpcValue(with network: NetworkProvider) -> Any { 64 | return dictionary 65 | } 66 | } 67 | 68 | open class FilterLogOptions: FilterOptions { 69 | /// blockhash: DATA, 32 Bytes - (optional) With the addition of EIP-234 (Geth >= v1.8.13 or Parity >= v2.1.0), blockHash is a new filter option which restricts the logs returned to the single block with the 32-byte hash blockHash. Using blockHash is equivalent to fromBlock = toBlock = the block number with hash blockHash. If blockHash is present in the filter criteria, then neither fromBlock nor toBlock are allowed. 70 | public var blockHash: Data? 71 | public override var dictionary: JDictionary { 72 | return super.dictionary.set("blockHash", blockHash) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Sources/web3swift/HookedFunctions/Web3+Wallet.swift: -------------------------------------------------------------------------------- 1 | // 2 | import BigInt 3 | // Web3+HookedWallet.swift 4 | // web3swift 5 | // 6 | // Created by Alexander Vlasov on 07.01.2018. 7 | // Copyright © 2018 Bankex Foundation. All rights reserved. 8 | // 9 | import Foundation 10 | 11 | /// Web3Wallet errors 12 | public enum Web3WalletError: Error { 13 | /// Wallet doesn't have any accounts 14 | case noAccounts 15 | /// Printable / user displayable description 16 | public var localizedDescription: String { 17 | switch self { 18 | case .noAccounts: 19 | return "Wallet doesn't have any accounts" 20 | } 21 | } 22 | } 23 | 24 | /// Wallet functions 25 | public class Web3Wallet { 26 | /// Provider for some functions 27 | var provider: Web3Provider 28 | unowned var web3: Web3 29 | 30 | /// Init with provider and web3 instance 31 | public init(provider prov: Web3Provider, web3 web3instance: Web3) { 32 | provider = prov 33 | web3 = web3instance 34 | } 35 | 36 | /// - Returns: All accounts in your keystoreManager 37 | public func getAccounts() -> [Address] { 38 | return web3.provider.attachedKeystoreManager.addresses 39 | } 40 | 41 | /// - Returns: Returns first account in your keystoreManager 42 | /// - Throws: 43 | /// Web3WalletError.noAccounts 44 | public func getCoinbase() throws -> Address { 45 | guard let account = getAccounts().first else { throw Web3WalletError.noAccounts } 46 | return account 47 | } 48 | 49 | /// Signs transaction with account 50 | /// - Parameter transaction: Transaction to sign 51 | /// - Parameter account: Address that signs message 52 | /// - Parameter password: Password to decrypt account's private key 53 | /// - Throws: 54 | /// AbstractKeystoreError 55 | /// Error 56 | public func signTX(transaction: inout EthereumTransaction, account: Address, password: String = "BANKEXFOUNDATION") throws { 57 | let keystoreManager = self.web3.provider.attachedKeystoreManager 58 | try Web3Signer.signTX(transaction: &transaction, keystore: keystoreManager, account: account, password: password) 59 | } 60 | 61 | 62 | /// Signs personalMessage with account 63 | /// - Parameter personalMessage: Message to sign 64 | /// - Parameter account: Address that signs message 65 | /// - Parameter password: Password to decrypt account's private key 66 | /// - Returns: Signed message 67 | /// - Throws: SECP256K1Error 68 | /// DataError.hexStringCorrupted(String) 69 | public func signPersonalMessage(_ personalMessage: String, account: Address, password: String = "BANKEXFOUNDATION") throws -> Data { 70 | let data = try personalMessage.dataFromHex() 71 | return try signPersonalMessage(data, account: account, password: password) 72 | } 73 | 74 | /// Signs personalMessage with account 75 | /// - Parameter personalMessage: Message to sign 76 | /// - Parameter account: Address that signs message 77 | /// - Parameter password: Password to decrypt account's private key 78 | /// - Returns: Signed message 79 | /// - Throws: SECP256K1Error 80 | public func signPersonalMessage(_ personalMessage: Data, account: Address, password: String = "BANKEXFOUNDATION") throws -> Data { 81 | let keystoreManager = self.web3.provider.attachedKeystoreManager 82 | return try Web3Signer.signPersonalMessage(personalMessage, keystore: keystoreManager, account: account, password: password) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Sources/web3swift/KeystoreManager/AbstractKeystore.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AbstractKeystore.swift 3 | // web3swift 4 | // 5 | // Created by Alexander Vlasov on 10.01.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Keystore Protocol 12 | public protocol AbstractKeystore { 13 | /// Array for addresses 14 | var addresses: [Address] { get } 15 | /// Returns true if keystore is HDKeystore compatible 16 | var isHDKeystore: Bool { get } 17 | /// Decrypts account's private key with password 18 | func UNSAFE_getPrivateKeyData(password: String, account: Address) throws -> Data 19 | } 20 | 21 | /// Keystore Errors 22 | public enum AbstractKeystoreError: Error { 23 | /// Cannot get derived key using this password 24 | case keyDerivationError 25 | /// Invalid aes key or unsupported aes encryption type 26 | case aesError 27 | /// Private key doesn't match provided account 28 | case invalidAccountError 29 | /// Invalid password 30 | case invalidPasswordError 31 | /// Some other encryption errors 32 | case encryptionError(String) 33 | 34 | /// Printable / user displayable description 35 | public var localizedDescription: String { 36 | switch self { 37 | case .keyDerivationError: 38 | return "Cannot get derived key using this password" 39 | case .aesError: 40 | return "Invalid aes key or unsupported aes encryption type" 41 | case .invalidAccountError: 42 | return "Private key doesn't match provided account" 43 | case .invalidPasswordError: 44 | return "Invalid password" 45 | case let .encryptionError(string): 46 | return "Encryption error: \(string)" 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Sources/web3swift/KeystoreManager/PlainKeystore.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PlainKeystore.swift 3 | // web3swift 4 | // 5 | // Created by Alexander Vlasov on 06.04.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Keystore that contains private key 12 | public class PlainKeystore: AbstractKeystore { 13 | private var privateKey: Data 14 | 15 | /// Always returns array with one address 16 | public var addresses: [Address] 17 | 18 | /// Default: false 19 | public var isHDKeystore: Bool = false 20 | 21 | /// Returns keystore private key. 22 | /// - Parameter password: We already have unencrypted private. So password doing nothing here 23 | /// - Parameter address: We have only one address. So account will be ignored too 24 | public func UNSAFE_getPrivateKeyData(password _: String = "", account _: Address) throws -> Data { 25 | return privateKey 26 | } 27 | 28 | /// Init with private key hex string 29 | public convenience init(privateKey: String) throws { 30 | try self.init(privateKey: privateKey.dataFromHex()) 31 | } 32 | 33 | /// Init with private key data 34 | public init(privateKey: Data) throws { 35 | try SECP256K1.verifyPrivateKey(privateKey: privateKey) 36 | 37 | let publicKey = try Web3Utils.privateToPublic(privateKey, compressed: false) 38 | let address = try Web3Utils.publicToAddress(publicKey) 39 | addresses = [address] 40 | self.privateKey = privateKey 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Sources/web3swift/Migration-iOS.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Migration-iOS.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 22/11/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | #if canImport(CIImage) 10 | import Foundation 11 | import CIImage 12 | 13 | extension Web3 { 14 | @available (*, deprecated: 2.1, message: "Use EIP67Code, not Web3.EIP67Code") 15 | public typealias EIP67Code = web3swift.EIP67Code 16 | @available (*, deprecated: 2.1, message: "Use EIP67Code") 17 | public typealias EIP67CodeGenerator = web3swift.EIP67CodeGenerator 18 | @available (*, deprecated: 2.1, message: "Use EIP67Code") 19 | public typealias EIP67CodeParser = web3swift.EIP67CodeParser 20 | } 21 | public struct EIP67CodeGenerator { 22 | @available (*, deprecated: 2.1, message: "Use EIP67Code.toImage(scale:)") 23 | public static func createImage(from: EIP67Code, scale: Double = 1.0) -> CIImage { 24 | return from.toImage(scale: scale) 25 | } 26 | } 27 | public struct EIP67CodeParser { 28 | @available(*, deprecated: 2.1, message: "Use EIP67Code.init(string:)") 29 | public static func parse(_ data: Data) -> EIP67Code? { 30 | guard let string = String(data: data, encoding: .utf8) else { return nil } 31 | return parse(string) 32 | } 33 | @available(*, deprecated: 2.1, message: "Use EIP67Code.init(string:)") 34 | public static func parse(_ string: String) -> EIP67Code? { 35 | return EIP67Code(string: string) 36 | } 37 | } 38 | 39 | extension EIP67Code { 40 | @available (*, deprecated: 2.0, message: "Use init with address") 41 | public init(address: String) { 42 | self.init(address: Address(address)) 43 | } 44 | } 45 | #endif 46 | -------------------------------------------------------------------------------- /Sources/web3swift/Network/JEncodable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JEncodable.swift 3 | // Tests 4 | // 5 | // Created by Dmitry on 18/12/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import PromiseKit 11 | import BigInt 12 | 13 | public protocol JEncodable { 14 | func jsonRpcValue(with network: NetworkProvider) -> Any 15 | } 16 | 17 | extension Int: JEncodable { 18 | public func jsonRpcValue(with network: NetworkProvider) -> Any { 19 | return self 20 | } 21 | } 22 | extension BigUInt: JEncodable { 23 | public func jsonRpcValue(with network: NetworkProvider) -> Any { 24 | return "0x" + String(self, radix: 16, uppercase: false) 25 | } 26 | } 27 | extension Address: JEncodable { 28 | public func jsonRpcValue(with network: NetworkProvider) -> Any { 29 | return address 30 | } 31 | } 32 | extension Bool: JEncodable { 33 | public func jsonRpcValue(with network: NetworkProvider) -> Any { 34 | return self 35 | } 36 | } 37 | extension String: JEncodable { 38 | public func jsonRpcValue(with network: NetworkProvider) -> Any { 39 | return self 40 | } 41 | } 42 | extension BlockNumber: JEncodable { 43 | public func jsonRpcValue(with network: NetworkProvider) -> Any { 44 | return promise(network: network).jsonRpcValue(with: network) 45 | } 46 | } 47 | extension Data: JEncodable { 48 | public func jsonRpcValue(with network: NetworkProvider) -> Any { 49 | return hex.withHex 50 | } 51 | } 52 | extension Promise: JEncodable where T: JEncodable { 53 | public func jsonRpcValue(with network: NetworkProvider) -> Any { 54 | return map { $0 as Any } 55 | } 56 | } 57 | extension Dictionary: JEncodable where Value: JEncodable { 58 | public func jsonRpcValue(with network: NetworkProvider) -> Any { 59 | return mapValues { $0.jsonRpcValue(with: network) } 60 | } 61 | } 62 | open class JDictionary: JEncodable { 63 | public var dictionary = [String: JEncodable]() 64 | 65 | public init() {} 66 | open func at(_ key: String) -> JsonRpcDictionaryKey { 67 | return JsonRpcDictionaryKey(parent: self, key: key) 68 | } 69 | open func set(_ key: String, _ value: JEncodable?) -> Self { 70 | return self 71 | } 72 | open func set(_ key: String, _ value: JEncodable) -> Self { 73 | dictionary[key] = value 74 | return self 75 | } 76 | public func jsonRpcValue(with network: NetworkProvider) -> Any { 77 | return dictionary.mapValues { $0.jsonRpcValue(with: network) } 78 | } 79 | } 80 | open class JArray: JEncodable { 81 | public var array = [JEncodable]() 82 | 83 | public init() {} 84 | public init(_ array: [JEncodable]) { 85 | guard !array.isEmpty else { return } 86 | self.array = array 87 | } 88 | open func nilIfEmpty() -> Self? { 89 | return array.isEmpty ? nil : self 90 | } 91 | open func append(_ element: JEncodable) -> Self { 92 | array.append(element) 93 | return self 94 | } 95 | public func jsonRpcValue(with network: NetworkProvider) -> Any { 96 | return array.map { $0.jsonRpcValue(with: network) } 97 | } 98 | } 99 | public struct JsonRpcDictionaryKey { 100 | public var parent: JDictionary 101 | public var key: String 102 | public func set(_ value: JEncodable) { 103 | parent.dictionary[key] = value 104 | } 105 | // do nothing 106 | public func set(_ value: JEncodable?) {} 107 | public func dictionary(_ build: (JDictionary)->()) { 108 | let dictionary = JDictionary() 109 | build(dictionary) 110 | set(dictionary) 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /Sources/web3swift/Network/NetworkPromises.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkPromises.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 14/12/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import PromiseKit 11 | 12 | /// Work in progress. Will be released in 2.2 13 | public protocol NetworkProtocol { 14 | /// Sends request to url. To get 15 | func send(request: Request, to url: URL) 16 | } 17 | 18 | /// Work in progress. Will be released in 2.2 19 | extension DispatchQueue { 20 | public static var web3 = DispatchQueue(label: "web3swift.queue") 21 | func promise(_ execute: @escaping ()throws->(T)) -> Promise { 22 | let (promise, resolver) = Promise.pending() 23 | async { 24 | do { 25 | try resolver.fulfill(execute()) 26 | } catch { 27 | resolver.reject(error) 28 | } 29 | } 30 | return promise 31 | } 32 | func resolver(_ execute: @escaping (Resolver)throws->()) -> Promise { 33 | let (promise, resolver) = Promise.pending() 34 | async { 35 | do { 36 | try execute(resolver) 37 | } catch { 38 | resolver.reject(error) 39 | } 40 | } 41 | return promise 42 | } 43 | 44 | func run(_ resolver: Resolver, _ code: @escaping ()throws->(T)) { 45 | async { 46 | do { 47 | try resolver.fulfill(code()) 48 | } catch { 49 | resolver.reject(error) 50 | } 51 | } 52 | } 53 | } 54 | 55 | /// Work in progress. Will be released in 2.2 56 | class PromiseOperation: Operation { 57 | let resolver: Resolver 58 | let execute: ()throws->(T) 59 | init(resolver: Resolver, execute: @escaping ()throws->(T)) { 60 | self.resolver = resolver 61 | self.execute = execute 62 | } 63 | override func main() { 64 | do { 65 | let result = try execute() 66 | resolver.fulfill(result) 67 | } catch { 68 | resolver.reject(error) 69 | } 70 | } 71 | } 72 | 73 | extension URLSession: NetworkProtocol { 74 | public func send(request: Request, to url: URL) { 75 | send(request: request, to: url).done(on: .web3) { data in 76 | print("response: \(data.string)") 77 | let response = try AnyReader(json: data) 78 | do { 79 | try request._response(data: response) 80 | } catch { 81 | request._failed(error: error) 82 | } 83 | }.catch(request._failed) 84 | } 85 | private func send(request: Request, to url: URL) -> Promise { 86 | return DispatchQueue.web3.promise { 87 | try request.request(url: url) 88 | }.then(on: .web3) { request in 89 | self.send(request: request) 90 | } 91 | } 92 | private func send(request: URLRequest) -> Promise { 93 | let (promise, resolver) = Promise.pending() 94 | print("request: \(request.httpBody!.string)") 95 | dataTask(with: request) { data, response, error in 96 | if let error = error { 97 | resolver.reject(error) 98 | } else if let data = data, data.count > 0 { 99 | resolver.fulfill(data) 100 | } else { 101 | resolver.reject(Web3Error.nodeError("Node response is empty")) 102 | } 103 | }.resume() 104 | return promise 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Sources/web3swift/ObjectiveC/Bridging.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Bridging.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 09/11/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | // This protocol allows you to init objc class with its original swift class 13 | public protocol SwiftContainer: SwiftBridgeable { 14 | init(_ swift: SwiftType) 15 | } 16 | 17 | public protocol SwiftBridgeable: SwiftBridgeableHack { 18 | associatedtype SwiftType 19 | var swift: SwiftType { get } 20 | } 21 | 22 | // This protocol allows you to get swift value as Any. 23 | // Without this protocol .toSwift() function cannot convert Any to SwiftBridgeable 24 | // because it contains associatedtype 25 | public protocol SwiftBridgeableHack { 26 | var __swift: Any { get } 27 | } 28 | extension SwiftBridgeable { 29 | public var __swift: Any { return swift } 30 | } 31 | func toSwift(_ any: Any) -> Any { 32 | if let string = any as? String { 33 | return string 34 | } else if let objc = any as? SwiftBridgeableHack { 35 | return objc.__swift 36 | } else { 37 | return any 38 | } 39 | } 40 | 41 | extension Array where Element: Any { 42 | var swift: [Any] { 43 | return map(toSwift) 44 | } 45 | } 46 | 47 | 48 | //public extension _ObjectiveCBridgeable where _ObjectiveCType: SwiftBridgeable, _ObjectiveCType.SwiftType == Self { 49 | // static func _forceBridgeFromObjectiveC(_ source: _ObjectiveCType, result: inout Self?) { 50 | // result = source.swift 51 | // } 52 | // 53 | // static func _conditionallyBridgeFromObjectiveC(_ source: _ObjectiveCType, result: inout Self?) -> Bool { 54 | // result = source.swift 55 | // return true 56 | // } 57 | // 58 | // static func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectiveCType?) -> Self { 59 | // return source!.swift 60 | // } 61 | //} 62 | 63 | //extension _ObjectiveCBridgeable { 64 | // var objc: _ObjectiveCType { 65 | // return _bridgeToObjectiveC() 66 | // } 67 | //} 68 | -------------------------------------------------------------------------------- /Sources/web3swift/ObjectiveC/W3Contract.swift: -------------------------------------------------------------------------------- 1 | // 2 | // W3Contract.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 10/11/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension ContractV2.EventFilter { 12 | public var objc: W3ContractEventFilter { 13 | return W3ContractEventFilter(self) 14 | } 15 | } 16 | @objc public class W3ContractEventFilter: NSObject, SwiftContainer { 17 | public var swift: ContractV2.EventFilter 18 | public required init(_ swift: ContractV2.EventFilter) { 19 | self.swift = swift 20 | } 21 | 22 | @objc public var parameterName: String { 23 | get { return swift.parameterName } 24 | set { swift.parameterName = newValue } 25 | } 26 | @objc public var parameterValues: [AnyObject] { 27 | get { return swift.parameterValues } 28 | set { swift.parameterValues = newValue } 29 | } 30 | } 31 | @objc public class W3ContractParsedEvent: NSObject { 32 | @objc public let eventName: String? 33 | @objc public let eventData: [String: Any]? 34 | init(eventName: String?, eventData: [String: Any]?) { 35 | self.eventName = eventName 36 | self.eventData = eventData 37 | } 38 | } 39 | 40 | extension ContractProtocol { 41 | public var objc: W3Contract { 42 | return W3Contract(self as! ContractV2) 43 | } 44 | } 45 | 46 | @objc public class W3Contract: NSObject, W3OptionsInheritable, SwiftContainer { 47 | public var swift: ContractV2 48 | var _swiftOptions: Web3Options { 49 | get { return swift.options } 50 | set { swift.options = newValue } 51 | } 52 | public required init(_ swift: ContractV2) { 53 | self.swift = swift 54 | super.init() 55 | options = W3Options(object: self) 56 | } 57 | 58 | @objc public var allEvents: [String] { 59 | return swift.allEvents 60 | } 61 | 62 | @objc public var allMethods: [String] { 63 | return swift.allMethods 64 | } 65 | 66 | @objc public var address: W3Address? { 67 | get { return swift.address?.objc } 68 | set { swift.address = newValue?.swift } 69 | } 70 | 71 | @objc public var options: W3Options! 72 | 73 | @objc public init(_ abiString: String, at address: W3Address? = nil) throws { 74 | swift = try ContractV2(abiString, at: address?.swift) 75 | } 76 | 77 | @objc public func deploy(bytecode: Data, parameters: [Any], extraData: Data?, options: W3Options?) throws -> W3EthereumTransaction { 78 | let extraData = extraData ?? Data() 79 | return try swift.deploy(bytecode: bytecode, parameters: parameters.swift, extraData: extraData, options: options?.swift).objc 80 | } 81 | 82 | @objc public func method(_ method: String, parameters: [Any], extraData: Data?, options: W3Options?) throws -> W3EthereumTransaction { 83 | let extraData = extraData ?? Data() 84 | return try swift.method(method, parameters: parameters.swift, extraData: extraData, options: options?.swift).objc 85 | } 86 | 87 | @objc public func parseEvent(_ eventLog: W3EventLog) -> W3ContractParsedEvent { 88 | let (name,data) = swift.parseEvent(eventLog.swift) 89 | return W3ContractParsedEvent(eventName: name, eventData: data) 90 | } 91 | 92 | @objc public func testBloomForEventPrecence(eventName: String, bloom: W3EthereumBloomFilter) -> Bool { 93 | return swift.testBloomForEventPrecence(eventName: eventName, bloom: bloom.swift) ?? false 94 | } 95 | 96 | @objc public func decodeReturnData(_ method: String, data: Data) -> [String: Any]? { 97 | return swift.decodeReturnData(method, data: data) 98 | } 99 | 100 | @objc public func decodeInputData(_ method: String, data: Data) -> [String: Any]? { 101 | return swift.decodeInputData(method, data: data) 102 | } 103 | 104 | @objc public func decodeInputData(_ data: Data) -> [String: Any]? { 105 | return swift.decodeInputData(data) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Sources/web3swift/ObjectiveC/W3Personal.swift: -------------------------------------------------------------------------------- 1 | // 2 | // W3Personal.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 10/11/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | @objc public class W3Personal: NSObject { 12 | public var swift: Web3Personal { 13 | return web3.swift.personal 14 | } 15 | unowned var web3: W3Web3 16 | @objc public init(web3: W3Web3) { 17 | self.web3 = web3 18 | } 19 | /** 20 | *Locally or remotely sign a message (arbitrary data) with the private key. To avoid potential signing of a transaction the message is first prepended by a special header and then hashed.* 21 | 22 | - Parameter message: Message Data 23 | - Parameter from: Use a private key that corresponds to this account 24 | - Parameter password: Password for account if signing locally 25 | - Returns: signed message data 26 | - Important: This call is synchronous 27 | 28 | */ 29 | @objc public func signPersonalMessage(message: Data, from: W3Address, password: String = "BANKEXFOUNDATION") throws -> Data { 30 | return try swift.signPersonalMessage(message: message, from: from.swift, password: password) 31 | } 32 | 33 | /** 34 | *Unlock an account on the remote node to be able to send transactions and sign messages.* 35 | 36 | - Parameter account: W3Address of the account to unlock 37 | - Parameter password: Password to use for the account 38 | - Parameter seconds: Time inteval before automatic account lock by Ethereum node 39 | - Returns: isUnlocked 40 | - Important: This call is synchronous. Does nothing if private keys are stored locally. 41 | 42 | */ 43 | @objc public func unlockAccount(account: W3Address, password: String = "BANKEXFOUNDATION", seconds: UInt64 = 300, error pointer: ErrorPointer) -> Bool { 44 | do { 45 | return try swift.unlockAccount(account: account.swift, password: password, seconds: seconds) 46 | } catch { 47 | pointer?.pointee = error as NSError 48 | return false 49 | } 50 | } 51 | 52 | /** 53 | *Recovers a signer of some message. Message is first prepended by special prefix (check the "signPersonalMessage" method description) and then hashed.* 54 | 55 | - Parameter personalMessage: Message Data 56 | - Parameter signature: Serialized signature, 65 bytes 57 | - Returns: signer address 58 | 59 | */ 60 | @objc public func ecrecover(personalMessage: Data, signature: Data) throws -> W3Address { 61 | return try swift.ecrecover(personalMessage: personalMessage, signature: signature).objc 62 | } 63 | 64 | /** 65 | *Recovers a signer of some hash. Checking what is under this hash is on behalf of the user.* 66 | 67 | - Parameter hash: Signed hash 68 | - Parameter signature: Serialized signature, 65 bytes 69 | - Returns: signer address 70 | 71 | */ 72 | @objc public func ecrecover(hash: Data, signature: Data) throws -> W3Address { 73 | return try swift.ecrecover(hash: hash, signature: signature).objc 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Sources/web3swift/ObjectiveC/W3Provider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // W3Provider.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 11/9/18. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Web3HttpProvider { 12 | public var objc: W3Web3HttpProvider { 13 | return W3Web3HttpProvider(self) 14 | } 15 | } 16 | @objc public class W3Web3HttpProvider: NSObject, SwiftContainer { 17 | public let swift: Web3HttpProvider 18 | public required init(_ swift: Web3HttpProvider) { 19 | self.swift = swift 20 | } 21 | 22 | @objc public var url: URL { 23 | get { return swift.url } 24 | set { swift.url = newValue } 25 | } 26 | 27 | @objc public var network: W3NetworkId? { 28 | get { return swift.network?.objc } 29 | set { swift.network = newValue?.swift } 30 | } 31 | 32 | @objc public var attachedKeystoreManager: W3KeystoreManager { 33 | get { return swift.attachedKeystoreManager.objc } 34 | set { swift.attachedKeystoreManager = newValue.swift } 35 | } 36 | 37 | @objc public var session: URLSession { 38 | get { return swift.session } 39 | set { swift.session = newValue } 40 | } 41 | 42 | @objc public init?(_ httpProviderURL: URL, network net: W3NetworkId? = nil, keystoreManager manager: W3KeystoreManager = W3KeystoreManager()) { 43 | guard let swift = Web3HttpProvider(httpProviderURL, network: net?.swift, keystoreManager: manager.swift) else { return nil } 44 | self.swift = swift 45 | } 46 | } 47 | 48 | 49 | @objc public class W3InfuraProvider: W3Web3HttpProvider { 50 | @objc public init?(_ net: W3NetworkId, accessToken token: String? = nil, keystoreManager manager: W3KeystoreManager = W3KeystoreManager()) { 51 | guard let swift = InfuraProvider(net.swift, accessToken: token, keystoreManager: manager.swift) else { return nil } 52 | super.init(swift) 53 | } 54 | 55 | public required init(_ swift: Web3HttpProvider) { 56 | super.init(swift) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Sources/web3swift/ObjectiveC/W3Wallet.swift: -------------------------------------------------------------------------------- 1 | // 2 | // W3Wallet.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 10/11/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Wallet functions 12 | @objc public class W3Wallet: NSObject { 13 | public var swift: Web3Wallet { 14 | return web3.swift.wallet 15 | } 16 | unowned var web3: W3Web3 17 | @objc public init(web3: W3Web3) { 18 | self.web3 = web3 19 | } 20 | 21 | /// - Throws: Web3WalletError.attachadKeystoreNotFound 22 | @objc public func getAccounts() -> [W3Address] { 23 | return swift.getAccounts().map { $0.objc } 24 | } 25 | 26 | /// - Throws: 27 | /// Web3WalletError.attachadKeystoreNotFound 28 | /// Web3WalletError.noAccounts 29 | @objc public func getCoinbase() throws -> W3Address { 30 | return try swift.getCoinbase().objc 31 | } 32 | 33 | /// - Throws: 34 | /// Web3WalletError.attachadKeystoreNotFound 35 | /// AbstractKeystoreError 36 | /// Error 37 | @objc public func sign(transaction: W3EthereumTransaction, account: W3Address, password: String = "BANKEXFOUNDATION") throws { 38 | try swift.signTX(transaction: &transaction.swift, account: account.swift, password: password) 39 | } 40 | 41 | /// - Throws: SECP256K1Error 42 | @objc public func sign(personalMessageData: Data, account: W3Address, password: String = "BANKEXFOUNDATION") throws -> Data { 43 | return try swift.signPersonalMessage(personalMessageData, account: account.swift, password: password) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Sources/web3swift/ObjectiveC/W3Web3.swift: -------------------------------------------------------------------------------- 1 | // 2 | // W3Web3.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 11/9/18. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Web3Provider { 12 | public var objc: W3Web3HttpProvider { 13 | guard let provider = self as? Web3HttpProvider else { fatalError("\(self) is not convertible to objective-c W3Web3HttpProvider") } 14 | return provider.objc 15 | } 16 | } 17 | 18 | extension Web3 { 19 | public var objc: W3Web3 { 20 | return W3Web3(self) 21 | } 22 | } 23 | 24 | @objc public class W3Web3: NSObject, W3OptionsInheritable, SwiftContainer { 25 | public var swift: Web3 26 | var _swiftOptions: Web3Options { 27 | get { return swift.options } 28 | set { swift.options = newValue } 29 | } 30 | public required init(_ swift: Web3) { 31 | self.swift = swift 32 | super.init() 33 | options = W3Options(object: self) 34 | } 35 | 36 | @objc public static var `default`: W3Web3 { 37 | get { return Web3.default.objc } 38 | set { Web3.default = newValue.swift } 39 | } 40 | @objc public var provider: W3Web3HttpProvider { 41 | get { return swift.provider.objc } 42 | set { swift.provider = newValue.swift } 43 | } 44 | @objc public var options: W3Options! 45 | @objc public var defaultBlock: String { 46 | get { return swift.defaultBlock } 47 | set { swift.defaultBlock = newValue } 48 | } 49 | @objc public var requestDispatcher: W3JsonRpcRequestDispatcher { 50 | get { return swift.requestDispatcher.objc } 51 | set { swift.requestDispatcher = newValue.swift } 52 | } 53 | @objc public var keystoreManager: W3KeystoreManager { 54 | get { return swift.provider.attachedKeystoreManager.objc } 55 | set { swift.provider.attachedKeystoreManager = newValue.swift } 56 | } 57 | @objc public var txpool: W3TxPool { 58 | return W3TxPool(web3: self) 59 | } 60 | 61 | @objc public func dispatch(_ request: W3JsonRpcRequest, completion: @escaping (W3JsonRpcResponse?,Error?)->()) { 62 | swift.dispatch(request.swift).done { 63 | completion($0.objc,nil) 64 | }.catch { 65 | completion(nil,$0) 66 | } 67 | } 68 | 69 | @objc public init(provider prov: W3Web3HttpProvider, queue: OperationQueue? = nil) { 70 | swift = Web3(provider: prov.swift, queue: queue) 71 | super.init() 72 | options = W3Options(object: self) 73 | } 74 | 75 | @objc public lazy var eth = W3Eth(web3: self) 76 | @objc public lazy var personal = W3Personal(web3: self) 77 | @objc public lazy var wallet = W3Wallet(web3: self) 78 | 79 | @objc public init(infura networkId: W3NetworkId) { 80 | swift = Web3(infura: networkId.swift) 81 | super.init() 82 | options = W3Options(object: self) 83 | } 84 | 85 | @objc public init(infura networkId: W3NetworkId, accessToken: String) { 86 | swift = Web3(infura: networkId.swift, accessToken: accessToken) 87 | super.init() 88 | options = W3Options(object: self) 89 | } 90 | 91 | @objc public init?(url: URL) { 92 | guard let swift = Web3(url: url) else { return nil } 93 | self.swift = swift 94 | super.init() 95 | options = W3Options(object: self) 96 | } 97 | 98 | @objc public func addAccount(mnemonics: String, password: String) throws -> W3Address { 99 | let mnemonics = try Mnemonics(mnemonics) 100 | let keystore = try BIP32Keystore(mnemonics: mnemonics, password: password) 101 | keystoreManager.swift.append(keystore) 102 | return keystore.addresses.first!.objc 103 | } 104 | 105 | @objc public func addAccount(privateKey: Data, password: String) throws -> W3Address { 106 | guard let keystore = try EthereumKeystoreV3(privateKey: privateKey, password: password) 107 | else { throw SECP256K1Error.invalidPrivateKeySize } 108 | keystoreManager.swift.append(keystore) 109 | return keystore.addresses.first!.objc 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Sources/web3swift/ObjectiveC/web3swift.h: -------------------------------------------------------------------------------- 1 | // 2 | // web3swift.h 3 | // web3swift 4 | // 5 | // Created by Dmitry on 08/11/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for web3swift. 12 | FOUNDATION_EXPORT double web3swiftVersionNumber; 13 | 14 | //! Project version string for web3swift. 15 | FOUNDATION_EXPORT const unsigned char web3swiftVersionString[]; 16 | -------------------------------------------------------------------------------- /Sources/web3swift/Transaction/BloomFilter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BloomFilter.swift 3 | // web3swift 4 | // 5 | // Created by Alexander Vlasov on 02.03.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import BigInt 10 | import Foundation 11 | 12 | /// Ethereum bloom filter 13 | public struct EthereumBloomFilter { 14 | /// Bloom data 15 | public var bytes = Data(count: 256) 16 | 17 | /// Init with number 18 | public init?(_ biguint: BigUInt) { 19 | guard let data = biguint.serialize().setLengthLeft(256) else { return nil } 20 | bytes = data 21 | } 22 | 23 | /// Init with empty data 24 | public init() {} 25 | 26 | /// Init with data 27 | public init(_ data: Data) { 28 | let padding = Data(count: 256 - data.count) 29 | bytes = padding + data 30 | } 31 | /// Serialize to uint256 32 | public func asBigUInt() -> BigUInt { 33 | return BigUInt(bytes) 34 | } 35 | 36 | static func bloom9(_ biguint: BigUInt) -> BigUInt { 37 | return EthereumBloomFilter.bloom9(biguint.serialize()) 38 | } 39 | 40 | static func bloom9(_ data: Data) -> BigUInt { 41 | var b = data.keccak256() 42 | var r = BigUInt(0) 43 | let mask = BigUInt(2047) 44 | for i in stride(from: 0, to: 6, by: 2) { 45 | var t = BigUInt(1) 46 | let num = (BigUInt(b[i + 1]) + (BigUInt(b[i]) << 8)) & mask 47 | // b = num.serialize().setLengthLeft(8)! 48 | t = t << num 49 | r = r | t 50 | } 51 | return r 52 | } 53 | 54 | static func logsToBloom(_ logs: [EventLog]) -> BigUInt { 55 | var bin = BigUInt(0) 56 | for log in logs { 57 | bin = bin | bloom9(log.address.addressData) 58 | for topic in log.topics { 59 | bin = bin | bloom9(topic) 60 | } 61 | } 62 | return bin 63 | } 64 | 65 | /// Creates bloom filter for transaction receipts 66 | public static func createBloom(_ receipts: [TransactionReceipt]) -> EthereumBloomFilter? { 67 | var bin = BigUInt(0) 68 | for receipt in receipts { 69 | bin = bin | EthereumBloomFilter.logsToBloom(receipt.logs) 70 | } 71 | return EthereumBloomFilter(bin) 72 | } 73 | 74 | /// Tests topic 75 | public func test(topic: Data) -> Bool { 76 | let bin = asBigUInt() 77 | let comparison = EthereumBloomFilter.bloom9(topic) 78 | return bin & comparison == comparison 79 | } 80 | 81 | /// Tests topic 82 | public func test(topic: BigUInt) -> Bool { 83 | return test(topic: topic.serialize()) 84 | } 85 | 86 | /// Adds number to bloom 87 | public mutating func add(_ biguint: BigUInt) { 88 | var bin = BigUInt(bytes) 89 | bin = bin | EthereumBloomFilter.bloom9(biguint) 90 | setBytes(bin.serialize()) 91 | } 92 | 93 | /// Adds data to bloom 94 | public mutating func add(_ data: Data) { 95 | var bin = BigUInt(bytes) 96 | bin = bin | EthereumBloomFilter.bloom9(data) 97 | setBytes(bin.serialize()) 98 | } 99 | 100 | 101 | mutating func setBytes(_ data: Data) { 102 | if bytes.count < data.count { 103 | fatalError("bloom bytes are too big") 104 | } 105 | bytes = bytes[0 ..< data.count] + data 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Sources/web3swift/Transactions/SolidityDataWriter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SolidityDataWriter.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 25/10/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import BigInt 11 | 12 | private struct SolidityDataPointer { 13 | var data: Data 14 | var position: Int 15 | var arraySize: Int 16 | } 17 | private extension Data { 18 | mutating func write(data: Data, at position: Int) { 19 | replaceSubrange(position.. size { 23 | replaceSubrange(size..., with: Data()) 24 | } else if count < size { 25 | append(Data(count: size-count)) 26 | } 27 | } 28 | mutating func append(count: Int) { 29 | append(Data(count: count)) 30 | } 31 | mutating func normalizeSize() { 32 | let expectedSize = (count-1) / 0x20 * 0x20 + 0x20 33 | guard count < expectedSize else { return } 34 | append(count: expectedSize - count) 35 | } 36 | } 37 | class SolidityDataWriter { 38 | private(set) var data: Data 39 | private var dynamicData = [SolidityDataPointer]() 40 | var offset = 0 41 | init() { 42 | self.data = Data() 43 | } 44 | init(data: Data) { 45 | self.data = data 46 | } 47 | init(count: Int) { 48 | data = Data(count: count) 49 | } 50 | func write(header: Data) { 51 | data.append(header) 52 | offset += header.count 53 | } 54 | func write(type: SolidityType) { 55 | var data = type.default 56 | data.extend(to: type.memoryUsage) 57 | if !type.isStatic { 58 | let arraySize = ceil(Double(data.count) / Double(type.memoryUsage)) 59 | let pointer = SolidityDataPointer(data: data, position: self.data.count, arraySize: Int(arraySize)) 60 | self.data.append(count: 32) 61 | dynamicData.append(pointer) 62 | } else { 63 | self.data.append(data) 64 | } 65 | } 66 | func write(value: SolidityDataRepresentable, type: SolidityType) { 67 | var data = value.solidityData 68 | if type.memoryUsage > 0 { 69 | data.extend(to: type.memoryUsage) 70 | } 71 | if !type.isStatic { 72 | let arraySize = value.isSolidityBinaryType ? data.count : data.count / 32 73 | data.normalizeSize() 74 | let pointer = SolidityDataPointer(data: data, position: self.data.count, arraySize: Int(arraySize)) 75 | self.data.append(count: 32) 76 | dynamicData.append(pointer) 77 | } else { 78 | self.data.append(data) 79 | } 80 | } 81 | func setLength() { 82 | data.replaceSubrange(0..<0, with: length(data.count, offset: 0xc0)) 83 | } 84 | 85 | private func length(_ l: Int, offset: Int) -> Data { 86 | func byte(_ value: Int) -> Data { return Data([UInt8(value)]) } 87 | guard l + offset > 0xf7 else { return byte(l+offset) } 88 | let serialized = BigUInt(l).serialize() 89 | return byte(0xf7+serialized.count) + serialized 90 | } 91 | 92 | func done() -> Data { 93 | guard !dynamicData.isEmpty else { return data } 94 | for pointer in dynamicData { 95 | data.write(data: (data.count - offset).solidityData, at: pointer.position) 96 | if pointer.data.count == 0 { 97 | data.append(0.solidityData) 98 | } else { 99 | data.append(pointer.arraySize.solidityData) 100 | data.append(pointer.data) 101 | } 102 | } 103 | dynamicData.removeAll() 104 | return data 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Sources/web3swift/Transactions/SolidityDataWriter.swift~HEAD: -------------------------------------------------------------------------------- 1 | // 2 | // SolidityDataWriter.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 25/10/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import BigInt 11 | 12 | private struct SolidityDataPointer { 13 | var data: Data 14 | var position: Int 15 | var arraySize: Int 16 | } 17 | private extension Data { 18 | mutating func write(data: Data, at position: Int) { 19 | replaceSubrange(position.. size { 23 | replaceSubrange(size..., with: Data()) 24 | } else if count < size { 25 | append(Data(count: size-count)) 26 | } 27 | } 28 | mutating func append(count: Int) { 29 | append(Data(count: count)) 30 | } 31 | mutating func normalizeSize() { 32 | let expectedSize = (count-1) / 0x20 * 0x20 + 0x20 33 | guard count < expectedSize else { return } 34 | append(count: expectedSize - count) 35 | } 36 | } 37 | class SolidityDataWriter { 38 | private(set) var data: Data 39 | private var dynamicData = [SolidityDataPointer]() 40 | var offset = 0 41 | init() { 42 | self.data = Data() 43 | } 44 | init(data: Data) { 45 | self.data = data 46 | } 47 | init(count: Int) { 48 | data = Data(count: count) 49 | } 50 | func write(header: Data) { 51 | data.append(header) 52 | offset += header.count 53 | } 54 | func write(type: SolidityType) { 55 | var data = type.default 56 | data.extend(to: type.memoryUsage) 57 | if !type.isStatic { 58 | let arraySize = ceil(Double(data.count) / Double(type.memoryUsage)) 59 | let pointer = SolidityDataPointer(data: data, position: self.data.count, arraySize: Int(arraySize)) 60 | self.data.append(count: 32) 61 | dynamicData.append(pointer) 62 | } else { 63 | self.data.append(data) 64 | } 65 | } 66 | func write(value: SolidityDataRepresentable, type: SolidityType) { 67 | var data = value.solidityData 68 | if type.memoryUsage > 0 { 69 | data.extend(to: type.memoryUsage) 70 | } 71 | if !type.isStatic { 72 | let arraySize = value.isSolidityBinaryType ? data.count : data.count / 32 73 | data.normalizeSize() 74 | let pointer = SolidityDataPointer(data: data, position: self.data.count, arraySize: Int(arraySize)) 75 | self.data.append(count: 32) 76 | dynamicData.append(pointer) 77 | } else { 78 | self.data.append(data) 79 | } 80 | } 81 | func setLength() { 82 | data.replaceSubrange(0..<0, with: length(data.count, offset: 0xc0)) 83 | } 84 | 85 | private func length(_ l: Int, offset: Int) -> Data { 86 | func byte(_ value: Int) -> Data { return Data([UInt8(value)]) } 87 | guard l + offset > 0xf7 else { return byte(l+offset) } 88 | let serialized = BigUInt(l).serialize() 89 | return byte(0xf7+serialized.count) + serialized 90 | } 91 | 92 | func done() -> Data { 93 | guard !dynamicData.isEmpty else { return data } 94 | for pointer in dynamicData { 95 | data.write(data: (data.count - offset).solidityData, at: pointer.position) 96 | if pointer.data.count == 0 { 97 | data.append(0.solidityData) 98 | } else { 99 | data.append(pointer.arraySize.solidityData) 100 | data.append(pointer.data) 101 | } 102 | } 103 | dynamicData.removeAll() 104 | return data 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Sources/web3swift/TxPool/DecoderExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DecoderExtensions.swift 3 | // web3swift-iOS 4 | // 5 | // Created by Dmitry on 28/10/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // Inspired by https://gist.github.com/mbuchetics/c9bc6c22033014aa0c550d3b4324411a 12 | 13 | struct JSONCodingKeys: CodingKey { 14 | var stringValue: String 15 | 16 | init?(stringValue: String) { 17 | self.stringValue = stringValue 18 | } 19 | 20 | var intValue: Int? 21 | 22 | init?(intValue: Int) { 23 | self.init(stringValue: "\(intValue)") 24 | self.intValue = intValue 25 | } 26 | } 27 | 28 | 29 | extension KeyedDecodingContainer { 30 | 31 | func decode(_ type: Dictionary.Type, forKey key: K) throws -> Dictionary { 32 | let container = try self.nestedContainer(keyedBy: JSONCodingKeys.self, forKey: key) 33 | return try container.decode(type) 34 | } 35 | 36 | func decodeIfPresent(_ type: Dictionary.Type, forKey key: K) throws -> Dictionary? { 37 | guard contains(key) else { 38 | return nil 39 | } 40 | return try decode(type, forKey: key) 41 | } 42 | 43 | func decode(_ type: Array.Type, forKey key: K) throws -> Array { 44 | var container = try self.nestedUnkeyedContainer(forKey: key) 45 | return try container.decode(type) 46 | } 47 | 48 | func decodeIfPresent(_ type: Array.Type, forKey key: K) throws -> Array? { 49 | guard contains(key) else { 50 | return nil 51 | } 52 | return try decode(type, forKey: key) 53 | } 54 | 55 | func decode(_ type: Dictionary.Type) throws -> Dictionary { 56 | var dictionary = Dictionary() 57 | 58 | for key in allKeys { 59 | if let boolValue = try? decode(Bool.self, forKey: key) { 60 | dictionary[key.stringValue] = boolValue 61 | } else if let stringValue = try? decode(String.self, forKey: key) { 62 | dictionary[key.stringValue] = stringValue 63 | } else if let intValue = try? decode(Int.self, forKey: key) { 64 | dictionary[key.stringValue] = intValue 65 | } else if let doubleValue = try? decode(Double.self, forKey: key) { 66 | dictionary[key.stringValue] = doubleValue 67 | } else if let nestedDictionary = try? decode(Dictionary.self, forKey: key) { 68 | dictionary[key.stringValue] = nestedDictionary 69 | } else if let nestedArray = try? decode(Array.self, forKey: key) { 70 | dictionary[key.stringValue] = nestedArray 71 | } 72 | } 73 | return dictionary 74 | } 75 | } 76 | 77 | extension UnkeyedDecodingContainer { 78 | 79 | mutating func decode(_ type: Array.Type) throws -> Array { 80 | var array: [Any] = [] 81 | while isAtEnd == false { 82 | if let value = try? decode(Bool.self) { 83 | array.append(value) 84 | } else if let value = try? decode(Double.self) { 85 | array.append(value) 86 | } else if let value = try? decode(String.self) { 87 | array.append(value) 88 | } else if let nestedDictionary = try? decode(Dictionary.self) { 89 | array.append(nestedDictionary) 90 | } else if let nestedArray = try? decode(Array.self) { 91 | array.append(nestedArray) 92 | } 93 | } 94 | return array 95 | } 96 | 97 | mutating func decode(_ type: Dictionary.Type) throws -> Dictionary { 98 | 99 | let nestedContainer = try self.nestedContainer(keyedBy: JSONCodingKeys.self) 100 | return try nestedContainer.decode(type) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Sources/web3swift/Web3/Web3+Infura.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Web3+Provider.swift 3 | // web3swift 4 | // 5 | // Created by Alexander Vlasov on 19.12.2017. 6 | // Copyright © 2017 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import BigInt 10 | import Foundation 11 | 12 | extension URL { 13 | static func infura(_ network: NetworkId, token: String? = nil) -> URL { 14 | var url = URL(string: "https://\(network).infura.io/")! 15 | if let token = token { 16 | url.appendPathComponent(token) 17 | } 18 | return url 19 | } 20 | } 21 | 22 | /** 23 | Custom Web3 HTTP provider of Infura nodes. 24 | web3swift uses Infura mainnet as default provider 25 | */ 26 | public final class InfuraProvider: Web3HttpProvider { 27 | /** 28 | - Parameter net: Defines network id. applies to address "https://\(net).infura.io/" 29 | - Parameter token: Your infura token. appends to url address 30 | - Parameter manager: KeystoreManager for this provider 31 | */ 32 | public init?(_ net: NetworkId, accessToken token: String? = nil, keystoreManager manager: KeystoreManager = KeystoreManager()) { 33 | super.init(.infura(net, token: token), network: net, keystoreManager: manager) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Sources/web3swift/Web3/Web3+Instance.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Web3+Instance.swift 3 | // web3swift 4 | // 5 | // Created by Alexander Vlasov on 19.12.2017. 6 | // Copyright © 2017 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import BigInt 10 | import Foundation 11 | import PromiseKit 12 | 13 | /// A web3 instance bound to provider. All further functionality is provided under web.*. namespaces. 14 | public class Web3: Web3OptionsInheritable { 15 | /** 16 | Default Web3 instance. 17 | 18 | Uses as default Web3 in blockchain if you didn't provide any. 19 | 20 | default: `Web3(infura: .mainnet)` 21 | */ 22 | public static var `default`: Web3 = Web3(infura: .mainnet) 23 | /// Web3 provider. Contains Keystore Manager, node URL and Network id 24 | public var provider: Web3Provider 25 | /// Default options. Merges with provided options in every transaction 26 | public var options: Web3Options = .default 27 | /// default block. default: "latest" 28 | public var defaultBlock = "latest" 29 | /** 30 | request dispatcher. 31 | 32 | by default on sending request, waits 0.1 second for another request to combine them in one 33 | then sends up to 10 requests as one 34 | 35 | you can setup here request options 36 | */ 37 | public var requestDispatcher: JsonRpcRequestDispatcher 38 | 39 | /// Keystore manager which actually is a setter/getter for provider.attachedKeystoreManager 40 | public var keystoreManager: KeystoreManager { 41 | get { return provider.attachedKeystoreManager } 42 | set { provider.attachedKeystoreManager = newValue } 43 | } 44 | 45 | /// Contains transaction pool requests 46 | public var txpool: TxPool { 47 | return TxPool(web3: self) 48 | } 49 | 50 | /// Public web3.eth.* namespace. 51 | public lazy var eth = Web3Eth(provider: self.provider, web3: self) 52 | 53 | /// Public web3.personal.* namespace. 54 | public lazy var personal = Web3Personal(provider: self.provider, web3: self) 55 | 56 | /// Public web3.wallet.* namespace. 57 | public lazy var wallet = Web3Wallet(provider: self.provider, web3: self) 58 | 59 | /// Public web3.browserFunctions.* namespace. 60 | public lazy var browserFunctions = Web3BrowserFunctions(provider: self.provider, web3: self) 61 | 62 | /// Add a provider request to the dispatch queue. 63 | public func dispatch(_ request: JsonRpcRequest) -> Promise { 64 | return requestDispatcher.addToQueue(request: request) 65 | } 66 | 67 | /// Raw initializer using a Web3Provider protocol object, dispatch queue and request dispatcher. 68 | public init(provider prov: Web3Provider, queue _: OperationQueue? = nil, requestDispatcher: JsonRpcRequestDispatcher? = nil) { 69 | provider = prov 70 | if requestDispatcher == nil { 71 | self.requestDispatcher = JsonRpcRequestDispatcher(provider: provider, queue: DispatchQueue.global(qos: .userInteractive), policy: .Batch(32)) 72 | } else { 73 | self.requestDispatcher = requestDispatcher! 74 | } 75 | } 76 | 77 | /** 78 | Keystore manager can be bound to Web3 instance. 79 | If some manager is bound all further account related functions, such 80 | as account listing, transaction signing, etc. 81 | are done locally using private keys and accounts found in a manager. 82 | */ 83 | public func addKeystoreManager(_ manager: KeystoreManager) { 84 | provider.attachedKeystoreManager = manager 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Sources/web3swift/Web3/Web3+Methods.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Web3+Methods.swift 3 | // web3swift 4 | // 5 | // Created by Alexander Vlasov on 21.12.2017. 6 | // Copyright © 2017 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Contains JsonRpc api methods and required number of parameters 12 | public struct JsonRpcMethod: Encodable, Equatable { 13 | /// Method name 14 | public var api: String 15 | /// Required number of parameters 16 | public var parameters: Int 17 | 18 | /// init with api and parameters. Used for custom api methods 19 | public init(api: String, parameters: Int) { 20 | self.api = api 21 | self.parameters = parameters 22 | } 23 | 24 | /// eth_gasPrice method 25 | public static let gasPrice = JsonRpcMethod(api: "eth_gasPrice", parameters: 0) 26 | /// eth_blockNumber method 27 | public static let blockNumber = JsonRpcMethod(api: "eth_blockNumber", parameters: 0) 28 | /// net_version method 29 | public static let getNetwork = JsonRpcMethod(api: "net_version", parameters: 0) 30 | /// eth_sendRawTransaction method 31 | public static let sendRawTransaction = JsonRpcMethod(api: "eth_sendRawTransaction", parameters: 1) 32 | /// eth_sendTransaction method 33 | public static let sendTransaction = JsonRpcMethod(api: "eth_sendTransaction", parameters: 1) 34 | /// eth_estimateGas method 35 | public static let estimateGas = JsonRpcMethod(api: "eth_estimateGas", parameters: 1) 36 | /// eth_call method 37 | public static let call = JsonRpcMethod(api: "eth_call", parameters: 2) 38 | /// eth_getTransactionCount method 39 | public static let getTransactionCount = JsonRpcMethod(api: "eth_getTransactionCount", parameters: 2) 40 | /// eth_getBalance method 41 | public static let getBalance = JsonRpcMethod(api: "eth_getBalance", parameters: 2) 42 | /// eth_getCode method 43 | public static let getCode = JsonRpcMethod(api: "eth_getCode", parameters: 2) 44 | /// eth_getStorageAt method 45 | public static let getStorageAt = JsonRpcMethod(api: "eth_getStorageAt", parameters: 2) 46 | /// eth_getTransactionByHash method 47 | public static let getTransactionByHash = JsonRpcMethod(api: "eth_getTransactionByHash", parameters: 1) 48 | /// eth_getTransactionReceipt method 49 | public static let getTransactionReceipt = JsonRpcMethod(api: "eth_getTransactionReceipt", parameters: 1) 50 | /// eth_accounts method 51 | public static let getAccounts = JsonRpcMethod(api: "eth_accounts", parameters: 0) 52 | /// eth_getBlockByHash method 53 | public static let getBlockByHash = JsonRpcMethod(api: "eth_getBlockByHash", parameters: 2) 54 | /// eth_getBlockByNumber method 55 | public static let getBlockByNumber = JsonRpcMethod(api: "eth_getBlockByNumber", parameters: 2) 56 | /// eth_sign method 57 | public static let personalSign = JsonRpcMethod(api: "eth_sign", parameters: 1) 58 | /// personal_unlockAccount method 59 | public static let unlockAccount = JsonRpcMethod(api: "personal_unlockAccount", parameters: 1) 60 | /// eth_getLogs method 61 | public static let getLogs = JsonRpcMethod(api: "eth_getLogs", parameters: 1) 62 | /// txpool_status method 63 | public static let txPoolStatus = JsonRpcMethod(api: "txpool_status", parameters: 0) 64 | /// txpool_inspect method 65 | public static let txPoolInspect = JsonRpcMethod(api: "txpool_inspect", parameters: 0) 66 | /// txpool_content method 67 | public static let txPoolContent = JsonRpcMethod(api: "txpool_content", parameters: 0) 68 | } 69 | -------------------------------------------------------------------------------- /Sources/web3swift/Web3/Web3.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Web3.swift 3 | // web3swift 4 | // 5 | // Created by Alexander Vlasov on 11.12.2017. 6 | // Copyright © 2017 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Web3 errors 12 | public enum Web3Error: Error { 13 | /// Transaction serialization failed 14 | case transactionSerializationError 15 | /// Cannot connect to local node 16 | case connectionError 17 | /// Cannot decode data 18 | case dataError 19 | /// Input error: \(string) 20 | case inputError(String) 21 | /// Node error: \(string) 22 | case nodeError(String) 23 | /// Processing error: \(string) 24 | case processingError(String) 25 | /// Printable / user displayable description 26 | public var localizedDescription: String { 27 | switch self { 28 | case .transactionSerializationError: 29 | return "Transaction serialization failed" 30 | case .connectionError: 31 | return "Cannot connect to local node" 32 | case .dataError: 33 | return "Cannot decode data" 34 | case let .inputError(string): 35 | return "Input error: \(string)" 36 | case let .nodeError(string): 37 | return "Node error: \(string)" 38 | case let .processingError(string): 39 | return "Processing error: \(string)" 40 | } 41 | } 42 | } 43 | 44 | /// An arbitary Web3 object. Is used only to construct provider bound fully functional object by either supplying provider URL 45 | /// or using pre-coded Infura nodes 46 | public extension Web3 { 47 | /// Returns web3 to work with local node at 127.0.0.1 48 | /// - Parameter port: Node port, default: 8545 49 | public static func local(port: Int = 8545) throws -> Web3 { 50 | guard let web3 = Web3(url: URL(string: "http://127.0.0.1:\(port)")!) else { throw Web3Error.connectionError } 51 | return web3 52 | } 53 | /// Returns web3 infura provider 54 | /// - Parameter networkId: Blockchain network id. like .mainnet / .ropsten 55 | convenience init(infura networkId: NetworkId) { 56 | let infura = InfuraProvider(networkId, accessToken: nil)! 57 | self.init(provider: infura) 58 | } 59 | /// returns web3 infura provider 60 | /// - Parameter networkId: blockchain network id. like .mainnet / .ropsten 61 | /// - Parameter accessToken: your infura access token 62 | convenience init(infura networkId: NetworkId, accessToken: String) { 63 | let infura = InfuraProvider(networkId, accessToken: accessToken)! 64 | self.init(provider: infura) 65 | } 66 | /// Initialized provider-bound Web3 instance using a provider's URL. Under the hood it performs a synchronous call to get 67 | /// the Network ID for EIP155 purposes 68 | convenience init?(url: URL) { 69 | guard let provider = Web3HttpProvider(url) else { return nil } 70 | self.init(provider: provider) 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /Tests/web3swiftTests/BetterABI/BetterERC20Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BetterERC20Tests.swift 3 | // web3swift-iOS_Tests 4 | // 5 | // Created by Dmitry on 17/10/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import BigInt 11 | @testable import web3swift 12 | 13 | class BetterERC20Tests: XCTestCase { 14 | let contract: Address = "0x45245bc59219eeaaf6cd3f382e078a461ff9de7b" 15 | let user: Address = "0x6a6a0b4aaa60E97386F94c5414522159b45DEdE8" 16 | 17 | override func setUp() { 18 | Web3.default.options.from = "0x6a6a0b4aaa60E97386F94c5414522159b45DEdE8" 19 | } 20 | override func tearDown() { 21 | Web3.default.options.from = nil 22 | } 23 | func testERC20EncodeUsingABIv2() throws { 24 | let amount = BigUInt(10).power(18) 25 | let arguments: [SolidityDataRepresentable] = [user, amount] 26 | let request = arguments.data(function: "transfer(address,uint256)") 27 | XCTAssertEqual(request.hex, "a9059cbb0000000000000000000000006a6a0b4aaa60e97386f94c5414522159b45dede80000000000000000000000000000000000000000000000000de0b6b3a7640000") 28 | 29 | let response = BigUInt(1).solidityData 30 | let success = try SolidityDataReader(response).bool() 31 | XCTAssertTrue(success) 32 | } 33 | 34 | func testERC20BalanceResponse() throws { 35 | let options = Web3Options.default 36 | let address = "0xd0a6e6c54dbc68db5db3a091b171a77407ff7ccf" 37 | let arguments: [SolidityDataRepresentable] = [address] 38 | let transaction = EthereumTransaction(to: contract, data: arguments.data(function: "balanceOf(address)"), options: options) 39 | let requestDictionary = transaction.encodeAsDictionary(from: "0xE6877A4d8806e9A9F12eB2e8561EA6c1db19978d") 40 | XCTAssertNotNil(requestDictionary, "Can't read ERC20 balance") 41 | } 42 | 43 | func testERC20NameResponse() throws { 44 | let response = "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a534f4e4d20546f6b656e00000000000000000000000000000000000000000000".hex 45 | let name = try SolidityDataReader(response).string() 46 | XCTAssertEqual(name, "SONM Token") 47 | } 48 | 49 | func testERC20Name() throws { 50 | let name = try contract.call("name()").wait().string() 51 | XCTAssertEqual(name, "\"BANKEX\" project utility token") 52 | } 53 | 54 | func testERC20Balance() throws { 55 | XCTAssertNoThrow(try contract.call("balanceOf(address)",user).wait().uint256()) 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Tests/web3swiftTests/ContractV2Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // web3swift_contractV2_Tests.swift 3 | // web3swift-iOS_Tests 4 | // 5 | // Created by Антон Григорьев on 02.07.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import BigInt 10 | //import CryptoSwift 11 | import XCTest 12 | 13 | @testable import web3swift 14 | 15 | class ContractV2Tests: XCTestCase { 16 | func testDecodeInputData() throws { 17 | let contract = try ContractV2(Web3Utils.erc20ABI) 18 | let dataToDecode = Data.fromHex("0xa9059cbb000000000000000000000000cdd45864e794fe5e3e1b0045b77e62f4c43b8bd9000000000000000000000000000000000000000000000224b5f018c3e30142d5")! 19 | let decoded = contract.decodeInputData("transfer", data: dataToDecode) 20 | XCTAssert(decoded!["_to"] as? Address == "0xcdd45864e794fe5e3e1b0045b77e62f4c43b8bd9") 21 | } 22 | 23 | func testDecodeInputDataWithoutMethodName() throws { 24 | let contract = try ContractV2(Web3Utils.erc20ABI) 25 | let dataToDecode = Data.fromHex("0xa9059cbb000000000000000000000000cdd45864e794fe5e3e1b0045b77e62f4c43b8bd9000000000000000000000000000000000000000000000224b5f018c3e30142d5")! 26 | let decoded = contract.decodeInputData(dataToDecode) 27 | XCTAssert(decoded!["_to"] as? Address == "0xcdd45864e794fe5e3e1b0045b77e62f4c43b8bd9") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tests/web3swiftTests/EIP67Tests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // web3swift_EIP67_Tests.swift 3 | // web3swift-iOS_Tests 4 | // 5 | // Created by Anton Grigoriev on 02.07.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | #if canImport(CIImage) 10 | import BigInt 11 | //import CryptoSwift 12 | import XCTest 13 | 14 | @testable import web3swift 15 | 16 | class EIP67Tests: XCTestCase { 17 | let address: Address = "0x6a6a0b4aaa60E97386F94c5414522159b45DEdE8" 18 | func testEIP67encoding() { 19 | var eip67Data = EIP67Code(address: address) 20 | eip67Data.gasLimit = BigUInt(21000) 21 | eip67Data.amount = BigUInt("1000000000000000000") 22 | // eip67Data.data = 23 | let encoding = eip67Data.toString() 24 | print(encoding) 25 | } 26 | 27 | func testEIP67codeGeneration() { 28 | var eip67Data = EIP67Code(address: address) 29 | eip67Data.gasLimit = BigUInt(21000) 30 | eip67Data.amount = BigUInt("1000000000000000000") 31 | // eip67Data.data = 32 | let encoding = eip67Data.toImage(scale: 5.0) 33 | XCTAssert(encoding != CIImage()) 34 | } 35 | 36 | func testEIP67decoding() { 37 | var eip67Data = EIP67Code(address: address) 38 | eip67Data.gasLimit = BigUInt(21000) 39 | eip67Data.amount = BigUInt("1000000000000000000") 40 | // eip67Data.data = 41 | let encoding = eip67Data.toString() 42 | guard let code = EIP67Code(string: encoding) else { return XCTFail() } 43 | XCTAssert(code.address == eip67Data.address) 44 | XCTAssert(code.gasLimit == eip67Data.gasLimit) 45 | XCTAssert(code.amount == eip67Data.amount) 46 | } 47 | } 48 | #endif 49 | -------------------------------------------------------------------------------- /Tests/web3swiftTests/InfuraTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // web3swiftInfuraTests.swift 3 | // web3swift-iOS_Tests 4 | // 5 | // Created by Георгий Фесенко on 02/07/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | @testable import web3swift 12 | class InfuraTests: XCTestCase { 13 | func testGetBalance() throws { 14 | let web3 = Web3(infura: .mainnet) 15 | let address = Address("0x6a6a0b4aaa60E97386F94c5414522159b45DEdE8") 16 | let balance = try web3.eth.getBalance(address: address) 17 | let balString = balance.string(units: .eth, decimals: 3) 18 | print(balString) 19 | } 20 | 21 | func testGetBlockByHash() throws { 22 | let web3 = Web3(infura: .mainnet) 23 | let result = try web3.eth.getBlockByHash("0x6d05ba24da6b7a1af22dc6cc2a1fe42f58b2a5ea4c406b19c8cf672ed8ec0695", fullTransactions: true) 24 | print(result) 25 | } 26 | 27 | func testGetBlockByNumber1() throws { 28 | let web3 = Web3(infura: .mainnet) 29 | let result = try web3.eth.getBlockByNumber("latest", fullTransactions: true) 30 | print(result) 31 | } 32 | 33 | func testGetBlockByNumber2() throws { 34 | let web3 = Web3(infura: .mainnet) 35 | let result = try web3.eth.getBlockByNumber(UInt64(5_184_323), fullTransactions: true) 36 | print(result) 37 | let transactions = result.transactions 38 | for transaction in transactions { 39 | switch transaction { 40 | case let .transaction(tx): 41 | print(String(describing: tx)) 42 | default: 43 | break 44 | } 45 | } 46 | } 47 | 48 | func testGetBlockByNumber3() { 49 | let web3 = Web3(infura: .mainnet) 50 | XCTAssertNoThrow(try web3.eth.getBlockByNumber(UInt64(0x5BAD55), fullTransactions: true)) 51 | } 52 | 53 | func testGasPrice() throws { 54 | let web3 = Web3(infura: .mainnet) 55 | let gasPrice = try web3.eth.getGasPrice() 56 | print(gasPrice) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Tests/web3swiftTests/NetworkTests/EthereumApiTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EthereumApiTests.swift 3 | // Tests 4 | // 5 | // Created by Dmitry on 20/12/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | @testable import web3swift 12 | 13 | //class EthereumApiTests: XCTestCase { 14 | // func testNet() throws { 15 | // eth = .localhost(port: 8545) 16 | // try XCTAssertNoThrow(eth.version().wait()) 17 | // try XCTAssertNoThrow(eth.peerCount().wait()) 18 | // try XCTAssertEqual(eth.listening().wait(), true) 19 | // XCTAssertEqual(try eth.sha3("0x68656c6c6f20776f726c64".hex).wait(), "0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad".hex) 20 | // } 21 | // func testShh() throws { 22 | // try XCTAssertThrowsError(eth.shh.version().wait()) 23 | // } 24 | //} 25 | -------------------------------------------------------------------------------- /Tests/web3swiftTests/NetworkTests/JsonRpcTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JsonRpcTests.swift 3 | // Tests 4 | // 5 | // Created by Dmitry on 17/12/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | import PromiseKit 12 | import BigInt 13 | @testable import web3swift 14 | 15 | class TestCallRequest: Request { 16 | init() { 17 | super.init(method: "eth_call") 18 | } 19 | override func request() -> [Any] { 20 | return [[ 21 | "data": "0x06fdde03", 22 | "to":"0x45245bc59219eeaaf6cd3f382e078a461ff9de7b", 23 | "value":"0x0", 24 | "gasPrice":"0x0" 25 | ], "latest"] 26 | } 27 | override func response(data: DictionaryReader) throws { 28 | let expected = "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001e2242414e4b4558222070726f6a656374207574696c69747920746f6b656e0000" 29 | try data.string().equals(expected) 30 | } 31 | } 32 | 33 | class JsonRpcTests: XCTestCase { 34 | func testRequest() throws { 35 | let request = TestCallRequest() 36 | URLSession.shared.send(request: request, to: .infura(.mainnet)) 37 | _ = try! request.promise.wait() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Tests/web3swiftTests/NumberFormattingUtilTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // web3swift_numberFormattingUtil_Tests.swift 3 | // web3swift-iOS_Tests 4 | // 5 | // Created by Антон Григорьев on 02.07.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import BigInt 10 | //import CryptoSwift 11 | import XCTest 12 | 13 | @testable import web3swift 14 | 15 | class NumberFormattingUtilTests: XCTestCase { 16 | func testNumberFormattingUtil() { 17 | let balance = BigInt("-1000000000000000000")! 18 | let formatted = balance.string(unitDecimals: 18, decimals: 4, decimalSeparator: ",") 19 | XCTAssertEqual(formatted, "-1") 20 | } 21 | 22 | func testNumberFormattingUtil2() { 23 | let balance = BigInt("-1000000000000000")! 24 | let formatted = balance.string(unitDecimals: 18, decimals: 4, decimalSeparator: ",") 25 | XCTAssertEqual(formatted, "-0,001") 26 | } 27 | 28 | func testNumberFormattingUtil3() { 29 | let balance = BigInt("-1000000000000")! 30 | let formatted = balance.string(unitDecimals: 18, decimals: 4, decimalSeparator: ",") 31 | XCTAssertEqual(formatted, "-0") 32 | } 33 | 34 | func testNumberFormattingUtil4() { 35 | let balance = BigInt("-1000000000000")! 36 | let formatted = balance.string(unitDecimals: 18, decimals: 9, decimalSeparator: ",") 37 | XCTAssertEqual(formatted, "-0,000001") 38 | } 39 | 40 | func testNumberFormattingUtil5() { 41 | let balance = BigInt("-1")! 42 | let formatted = balance.string(unitDecimals: 18, decimals: 9, decimalSeparator: ",", options: [.stripZeroes,.fallbackToScientific]) 43 | XCTAssertEqual(formatted, "-1e-18") 44 | } 45 | 46 | func testNumberFormattingUtil6() { 47 | let balance = BigInt("0")! 48 | let formatted = balance.string(unitDecimals: 18, decimals: 9, decimalSeparator: ",") 49 | XCTAssertEqual(formatted, "0") 50 | } 51 | 52 | func testNumberFormattingUtil7() { 53 | let balance = BigInt("-1100000000000000000")! 54 | let formatted = balance.string(unitDecimals: 18, decimals: 4, decimalSeparator: ",") 55 | XCTAssertEqual(formatted, "-1,1") 56 | } 57 | 58 | func testNumberFormattingUtil8() { 59 | let balance = BigInt("100")! 60 | let formatted = balance.string(unitDecimals: 18, decimals: 4, decimalSeparator: ",", options: [.stripZeroes,.fallbackToScientific]) 61 | XCTAssertEqual(formatted, "1,00e-16") 62 | } 63 | 64 | func testNumberFormattingUtil9() { 65 | let balance = BigInt("1000000")! 66 | let formatted = balance.string(unitDecimals: 18, decimals: 4, decimalSeparator: ",", options: [.stripZeroes,.fallbackToScientific]) 67 | XCTAssertEqual(formatted, "1,0000e-12") 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Tests/web3swiftTests/RinkebyPersonalSignatureTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // web3swift_personal_signature_Tests.swift 3 | // web3swift-iOS_Tests 4 | // 5 | // Created by Anton Grigoriev on 02.07.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import BigInt 10 | //import CryptoSwift 11 | import XCTest 12 | 13 | @testable import web3swift 14 | 15 | class RinkebyPersonalSignatureTests: XCTestCase { 16 | func testPersonalSignature() throws { 17 | let web3 = Web3(infura: .rinkeby) 18 | let tempKeystore = try! EthereumKeystoreV3(password: "") 19 | let keystoreManager = KeystoreManager([tempKeystore!]) 20 | web3.addKeystoreManager(keystoreManager) 21 | let message = "Hello World".data 22 | let expectedAddress = keystoreManager.addresses[0] 23 | print(expectedAddress) 24 | let signature = try web3.personal.signPersonalMessage(message: message, from: expectedAddress, password: "") 25 | let unmarshalledSignature = try SECP256K1.unmarshalSignature(signatureData: signature) 26 | print("V = " + String(unmarshalledSignature.v)) 27 | print("R = " + Data(unmarshalledSignature.r).hex) 28 | print("S = " + Data(unmarshalledSignature.s).hex) 29 | try! print("Personal hash = " + Web3Utils.hashPersonalMessage(message).hex) 30 | let signer = try web3.personal.ecrecover(personalMessage: message, signature: signature) 31 | XCTAssert(expectedAddress == signer, "Failed to sign personal message") 32 | } 33 | 34 | func testPersonalSignatureOnContract() throws { 35 | let web3 = Web3(infura: .rinkeby) 36 | let tempKeystore = try! EthereumKeystoreV3(password: "") 37 | let keystoreManager = KeystoreManager([tempKeystore!]) 38 | web3.addKeystoreManager(keystoreManager) 39 | let message = "Hello World" 40 | let messageData = message.data 41 | let expectedAddress = keystoreManager.addresses[0] 42 | print(expectedAddress) 43 | let signature = try web3.personal.signPersonalMessage(message: messageData, from: expectedAddress, password: "") 44 | let unmarshalledSignature = try SECP256K1.unmarshalSignature(signatureData: signature) 45 | print("V = " + String(unmarshalledSignature.v)) 46 | print("R = " + Data(unmarshalledSignature.r).hex) 47 | print("S = " + Data(unmarshalledSignature.s).hex) 48 | try print("Personal hash = " + Web3Utils.hashPersonalMessage(messageData).hex) 49 | let jsonString = "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"constant\":true,\"inputs\":[{\"name\":\"_message\",\"type\":\"string\"}],\"name\":\"hashPersonalMessage\",\"outputs\":[{\"name\":\"hash\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_message\",\"type\":\"string\"},{\"name\":\"v\",\"type\":\"uint8\"},{\"name\":\"r\",\"type\":\"bytes32\"},{\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"recoverSigner\",\"outputs\":[{\"name\":\"signer\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"}]" 50 | let contract = try web3.contract(jsonString, at: "0x6f1745a39059268e8e4572e97897b50e4aab62a8") 51 | var options = Web3Options.default 52 | options.from = expectedAddress 53 | var intermediate = try contract.method("hashPersonalMessage", args: message, options: options) 54 | var res = try intermediate.call(options: nil) 55 | guard let hash = res["hash"]! as? Data else { return XCTFail() } 56 | let hash2 = try Web3Utils.hashPersonalMessage(messageData) 57 | XCTAssert(hash2 == hash) 58 | 59 | intermediate = try contract.method("recoverSigner", args: message, unmarshalledSignature.v, Data(unmarshalledSignature.r), Data(unmarshalledSignature.s), options: options) 60 | res = try intermediate.call(options: nil) 61 | guard let signer = res["signer"]! as? Address else { return XCTFail() } 62 | print(signer) 63 | XCTAssert(signer == expectedAddress) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Tests/web3swiftTests/ScryptTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // scrypt_Tests.swift 3 | // web3swift-iOS_Tests 4 | // 5 | // Created by Alexander Vlasov on 10.08.2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | 12 | @testable import web3swift 13 | 14 | class ScryptTests: XCTestCase { 15 | func testScrypt() { 16 | let password = "password" 17 | let salt = "NaCl".data 18 | let derived = scrypt(password: password, salt: salt, length: 64, N: 1024, R: 8, P: 16)! 19 | let expected = """ 20 | fd ba be 1c 9d 34 72 00 78 56 e7 19 0d 01 e9 fe 21 | 7c 6a d7 cb c8 23 78 30 e7 73 76 63 4b 37 31 62 22 | 2e af 30 d9 2e 22 a3 88 6f f1 09 27 9d 98 30 da 23 | c7 27 af b9 4a 83 ee 6d 83 60 cb df a2 cc 06 40 24 | """.replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "\n", with: "").replacingOccurrences(of: "\t", with: "").hex 25 | XCTAssertEqual(derived, expected) 26 | } 27 | 28 | func testProfilerRun() { 29 | // N: Int = 4096, R: Int = 6, P: Int = 1 30 | let password = "BANKEXFOUNDATION" 31 | let salt = Data.random(length: 32) 32 | XCTAssertNotNil(scrypt(password: password, salt: salt, length: 32, N: 4096, R: 6, P: 1)) 33 | } 34 | 35 | // func testLibsodiumPerformance() { 36 | // let password = "BANKEXFOUNDATION" 37 | // let salt = Data.random(length: 32) 38 | // measure { 39 | // _ = scrypt(password: password, salt: salt, length: 32, N: 4096, R: 6, P: 1) 40 | // } 41 | // } 42 | } 43 | -------------------------------------------------------------------------------- /Tests/web3swiftTests/Support.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // web3swift 4 | // 5 | // Created by Dmitry on 15/10/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension String { 12 | var data: Data { 13 | return Data(utf8) 14 | } 15 | func json(_ type: T.Type) throws -> T { 16 | return try JSONDecoder().decode(type, from: data) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Tests/web3swiftTests/TxPoolTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TxPoolTests.swift 3 | // web3swift-iOS_Tests 4 | // 5 | // Created by Dmitry on 28/10/2018. 6 | // Copyright © 2018 Bankex Foundation. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import web3swift 11 | import BigInt 12 | 13 | class TxPoolTests: XCTestCase { 14 | var localNodeFound = false 15 | override func setUp() { 16 | let url = URL(string: "http://127.0.0.1:8545")! 17 | if let provider = Web3HttpProvider(url, network: nil) { 18 | localNodeFound = true 19 | Web3.default = Web3(provider: provider) 20 | } else { 21 | localNodeFound = false 22 | } 23 | } 24 | func testTxPoolStatus() throws { 25 | 26 | guard localNodeFound else { return } 27 | try XCTAssertNoThrow(TxPool.default.status().wait()) 28 | } 29 | 30 | func testTxPoolInspect() throws { 31 | guard localNodeFound else { return } 32 | try XCTAssertNoThrow(TxPool.default.inspect().wait()) 33 | 34 | } 35 | func testTxPoolContent() throws { 36 | guard localNodeFound else { return } 37 | try XCTAssertNoThrow(TxPool.default.content().wait()) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /index.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | `You can find web3swift documentation here `_ 3 | ============ 4 | -------------------------------------------------------------------------------- /web3swift.pod.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'web3swift.pod' 3 | spec.version = '2.1.10' 4 | spec.ios.deployment_target = "8.0" 5 | spec.osx.deployment_target = "10.10" 6 | spec.tvos.deployment_target = "9.0" 7 | spec.watchos.deployment_target = "2.0" 8 | spec.license = { :type => 'Apache License 2.0', :file => 'LICENSE.md' } 9 | spec.summary = 'Web3 implementation in pure Swift for iOS, macOS, tvOS, watchOS and Linux' 10 | spec.homepage = 'https://github.com/bankex/web3swift' 11 | spec.author = 'Bankex Foundation' 12 | spec.source = { :git => 'https://github.com/bankex/web3swift.git', :tag => spec.version } 13 | spec.source_files = 'Sources/web3swift/**/*.swift' 14 | spec.swift_version = '4.2' 15 | spec.module_name = 'web3swift' 16 | spec.dependency 'PromiseKit', '~> 6.4' 17 | spec.dependency 'BigInt', '~> 3.1' 18 | spec.dependency 'secp256k1.c', '~> 0.1' 19 | spec.dependency 'keccak.c', '~> 0.1' 20 | spec.dependency 'scrypt.c', '~> 0.1' 21 | end 22 | -------------------------------------------------------------------------------- /web3swift.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'web3swift' 3 | spec.version = '2.1.10' 4 | spec.ios.deployment_target = "8.0" 5 | spec.osx.deployment_target = "10.10" 6 | spec.tvos.deployment_target = "9.0" 7 | spec.watchos.deployment_target = "2.0" 8 | spec.license = { :type => 'Apache License 2.0', :file => 'LICENSE.md' } 9 | spec.summary = 'Web3 implementation in pure Swift for iOS, macOS, tvOS, watchOS and Linux' 10 | spec.homepage = 'https://github.com/bankex/web3swift' 11 | spec.author = 'Bankex Foundation' 12 | spec.source = { :git => 'https://github.com/bankex/web3swift.git', :tag => spec.version } 13 | spec.source_files = 'Sources/web3swift/**/*.swift' 14 | spec.swift_version = '4.2' 15 | spec.dependency 'PromiseKit', '~> 6.4' 16 | spec.dependency 'BigInt', '~> 3.1' 17 | spec.dependency 'secp256k1.c', '~> 0.1' 18 | spec.dependency 'keccak.c', '~> 0.1' 19 | spec.dependency 'scrypt.c', '~> 0.1' 20 | end 21 | -------------------------------------------------------------------------------- /web3swift.xcodeproj/Before Release.md: -------------------------------------------------------------------------------- 1 | ## Minor release 2 | Update version in: 3 | * web3swift.podspec 4 | * web3swift.pod.podspec 5 | ``` 6 | pod trunk push web3swift.pod.podspec 7 | ``` 8 | 9 | 10 | ## Major release 11 | Update version in: 12 | * Readme.md 13 | * web3swift.podspec 14 | * web3swift.pod.podspec 15 | ``` 16 | pod trunk push web3swift.pod.podspec 17 | ``` 18 | -------------------------------------------------------------------------------- /web3swift.xcodeproj/How to build.md: -------------------------------------------------------------------------------- 1 | 2 | 1. Install carthage 3 | ``` 4 | brew install carthage 5 | ``` 6 | 2. Run: 7 | ``` 8 | carthage update --platform iOS 9 | # Available platforms: `iOS, macOS, tvOS, watchOS` 10 | ``` 11 | 3. Build project. 12 | 13 | 14 | 15 | 16 | 17 | ## You can also build web3swift into .framework by running: 18 | ``` 19 | carthage build --no-skip-current --platform iOS 20 | ``` 21 | -------------------------------------------------------------------------------- /web3swift.xcodeproj/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /web3swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /web3swift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /web3swift.xcodeproj/xcshareddata/xcschemes/keccak.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /web3swift.xcodeproj/xcshareddata/xcschemes/scrypt.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /web3swift.xcodeproj/xcshareddata/xcschemes/secp256k1.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /web3swift.xcodeproj/xcshareddata/xcschemes/web3swift.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | --------------------------------------------------------------------------------