├── .gitignore ├── .idea ├── clion.iml ├── codeStyles │ └── Project.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── modules.xml ├── platformio.iml ├── serialmonitor_settings.xml ├── vcs.xml └── watcherTasks.xml ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── examples ├── basic_eth │ └── basic_eth.ino ├── basic_net │ └── basic_net.ino ├── basic_web3 │ └── basic_web3.ino ├── eth_call │ └── eth_call.ino ├── eth_send │ └── eth_send.ino └── sample.sol ├── keywords.txt ├── library.json ├── library.properties ├── platformio.ini └── src ├── CaCert.h ├── Conf.h.example ├── Contract.cpp ├── Contract.h ├── Log.cpp ├── Log.h ├── Util.cpp ├── Util.h ├── Web3.cpp ├── Web3.h ├── cJSON ├── cJSON.c └── cJSON.h ├── examples └── example.cpp └── secp256k1 ├── include ├── secp256k1.h ├── secp256k1_ecdh.h └── secp256k1_recovery.h └── src ├── basic-config.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 ├── ecmult_static_context.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 ├── libsecp256k1-config.h ├── module └── recovery │ └── main_impl.h ├── num.h ├── num_gmp.h ├── num_gmp_impl.h ├── num_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 ├── secp256k1_c.h └── util.h /.gitignore: -------------------------------------------------------------------------------- 1 | src/Conf.h 2 | src/example/* 3 | src/examples/* 4 | readme_for_me.md 5 | tools/ 6 | lib/ 7 | 8 | .pioenvs 9 | .piolibdeps 10 | CMakeListsPrivate.txt 11 | 12 | 13 | # Created by https://www.gitignore.io/api/clion 14 | 15 | ### CLion ### 16 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 17 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 18 | 19 | # User-specific stuff: 20 | .idea/**/workspace.xml 21 | .idea/**/tasks.xml 22 | .idea/dictionaries 23 | 24 | # Sensitive or high-churn files: 25 | .idea/**/dataSources/ 26 | .idea/**/dataSources.ids 27 | .idea/**/dataSources.xml 28 | .idea/**/dataSources.local.xml 29 | .idea/**/sqlDataSources.xml 30 | .idea/**/dynamic.xml 31 | .idea/**/uiDesigner.xml 32 | 33 | # Gradle: 34 | .idea/**/gradle.xml 35 | .idea/**/libraries 36 | 37 | # CMake 38 | cmake-build-debug/ 39 | 40 | # Mongo Explorer plugin: 41 | .idea/**/mongoSettings.xml 42 | 43 | ## File-based project format: 44 | *.iws 45 | 46 | ## Plugin-specific files: 47 | 48 | # IntelliJ 49 | /out/ 50 | 51 | # mpeltonen/sbt-idea plugin 52 | .idea_modules/ 53 | 54 | # JIRA plugin 55 | atlassian-ide-plugin.xml 56 | 57 | # Cursive Clojure plugin 58 | .idea/replstate.xml 59 | 60 | # Ruby plugin and RubyMine 61 | /.rakeTasks 62 | 63 | # Crashlytics plugin (for Android Studio and IntelliJ) 64 | com_crashlytics_export_strings.xml 65 | crashlytics.properties 66 | crashlytics-build.properties 67 | fabric.properties 68 | 69 | ### CLion Patch ### 70 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 71 | 72 | # *.iml 73 | # modules.xml 74 | # .idea/misc.xml 75 | # *.ipr 76 | 77 | # Sonarlint plugin 78 | .idea/sonarlint 79 | 80 | 81 | # End of https://www.gitignore.io/api/clion -------------------------------------------------------------------------------- /.idea/clion.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/platformio.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.idea/serialmonitor_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/watcherTasks.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 22 | 29 | 30 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Continuous Integration (CI) is the practice, in software 2 | # engineering, of merging all developer working copies with a shared mainline 3 | # several times a day < http://docs.platformio.org/page/ci/index.html > 4 | # 5 | # Documentation: 6 | # 7 | # * Travis CI Embedded Builds with PlatformIO 8 | # < https://docs.travis-ci.com/user/integration/platformio/ > 9 | # 10 | # * PlatformIO integration with Travis CI 11 | # < http://docs.platformio.org/page/ci/travis.html > 12 | # 13 | # * User Guide for `platformio ci` command 14 | # < http://docs.platformio.org/page/userguide/cmd_ci.html > 15 | # 16 | # 17 | # Please choice one of the following templates (proposed below) and uncomment 18 | # it (remove "# " before each line) or use own configuration according to the 19 | # Travis CI documentation (see above). 20 | # 21 | 22 | 23 | # 24 | # Template #1: General project. Test it using existing `platformio.ini`. 25 | # 26 | 27 | # language: python 28 | # python: 29 | # - "2.7" 30 | # 31 | # sudo: false 32 | # cache: 33 | # directories: 34 | # - "~/.platformio" 35 | # 36 | # install: 37 | # - pip install -U platformio 38 | # 39 | # script: 40 | # - platformio run 41 | 42 | 43 | # 44 | # Template #2: The project is intended to by used as a library with examples 45 | # 46 | 47 | # language: python 48 | # python: 49 | # - "2.7" 50 | # 51 | # sudo: false 52 | # cache: 53 | # directories: 54 | # - "~/.platformio" 55 | # 56 | # env: 57 | # - PLATFORMIO_CI_SRC=path/to/test/file.c 58 | # - PLATFORMIO_CI_SRC=examples/file.ino 59 | # - PLATFORMIO_CI_SRC=path/to/test/directory 60 | # 61 | # install: 62 | # - pip install -U platformio 63 | # 64 | # script: 65 | # - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N 66 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2) 2 | project(web3-arduino) 3 | 4 | include(CMakeListsPrivate.txt) 5 | 6 | add_custom_target( 7 | PLATFORMIO_BUILD ALL 8 | COMMAND ${PLATFORMIO_CMD} -f -c clion run 9 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 10 | ) 11 | 12 | add_custom_target( 13 | PLATFORMIO_UPLOAD ALL 14 | COMMAND ${PLATFORMIO_CMD} -f -c clion run --target upload 15 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 16 | ) 17 | 18 | add_custom_target( 19 | PLATFORMIO_CLEAN ALL 20 | COMMAND ${PLATFORMIO_CMD} -f -c clion run --target clean 21 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 22 | ) 23 | 24 | add_custom_target( 25 | PLATFORMIO_TEST ALL 26 | COMMAND ${PLATFORMIO_CMD} -f -c clion test 27 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 28 | ) 29 | 30 | add_custom_target( 31 | PLATFORMIO_PROGRAM ALL 32 | COMMAND ${PLATFORMIO_CMD} -f -c clion run --target program 33 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 34 | ) 35 | 36 | add_custom_target( 37 | PLATFORMIO_UPLOADFS ALL 38 | COMMAND ${PLATFORMIO_CMD} -f -c clion run --target uploadfs 39 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 40 | ) 41 | 42 | add_custom_target( 43 | PLATFORMIO_UPDATE_ALL ALL 44 | COMMAND ${PLATFORMIO_CMD} -f -c clion update 45 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 46 | ) 47 | 48 | add_custom_target( 49 | PLATFORMIO_REBUILD_PROJECT_INDEX ALL 50 | COMMAND ${PLATFORMIO_CMD} -f -c clion init --ide clion 51 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 52 | ) 53 | 54 | add_executable(${PROJECT_NAME} ${SRC_LIST} src/examples/example.cpp src/Conf.h src/Web3.cpp src/Web3.h src/Log.cpp src/Log.h src/web3/Contract.cpp src/web3/Contract.h) 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017, Takahiro Okada 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## unmaintained 2 | 3 | Sorry but I cannot take time to maintain the library now... 4 | 5 | ## web3-arduino 6 | 7 | ![img](https://user-images.githubusercontent.com/891384/36104056-4994f600-1054-11e8-94f4-9f067610a6bf.png) 8 | 9 | - What is this library? 10 | - This is an Arduino (or ESP32) library to use web3 on Ethereum platform. 11 | 12 | - What is Arduino? 13 | - Arduino is an open source computer hardware and software. 14 | - https://www.arduino.cc/ 15 | - What is ESP32? 16 | - ESP32 is a series of low cost, low power system on a chip microcontrollers with integrated Wi-Fi and dual-mode Bluetooth. 17 | - https://www.espressif.com/en/products/hardware/esp32/overview 18 | - What is web3? 19 | - Web3 is the Ethereum compatible API which implements the Generic JSON RPC spec. Originally Javascript version is developed. 20 | - https://github.com/ethereum/web3.js/ 21 | - What is Ethereum? 22 | - Ethereum is a decentralized platform for applications that run exactly as programmed without any chance of fraud, censorship or third-party interference. 23 | - https://www.ethereum.org/ 24 | 25 | ## Environment 26 | 27 | - Confirmed device 28 | - ESP-WROOM-32 29 | - Used Ethereum client 30 | - INFURA (https://infura.io) 31 | 32 | ## Installation 33 | 34 | 1. download the zip file from `Clone or download` button on Github. 35 | 2. launch Arduino IDE. 36 | 3. `Sketch` -> `Include Library` -> `Add .ZIP file` -> select downloaded zip file. 37 | 4. Then you can use this from Arduino IDE. 38 | 39 | ## Example 40 | 41 | Please refer `examples` directory. 42 | 43 | ### setup 44 | 45 | ```C++ 46 | #define INFURA_HOST "rinkeby.infura.io" 47 | #define INFURA_PATH "/" 48 | 49 | Web3 web3(INFURA_HOST, INFURA_PATH); 50 | ``` 51 | 52 | ### call web3 methods 53 | 54 | ```C++ 55 | char result[128]; 56 | 57 | web3.Web3ClientVersion(result); 58 | USE_SERIAL.println(result); 59 | 60 | web3.Web3Sha3("0x68656c6c6f20776f726c64", result); 61 | USE_SERIAL.println(result); 62 | ``` 63 | 64 | ### `call` to Contract 65 | 66 | ```C++ 67 | Contract contract(&web3, CONTRACT_ADDRESS); 68 | strcpy(contract.options.from, MY_ADDRESS); 69 | strcpy(contract.options.gasPrice,"2000000000000"); 70 | contract.options.gas = 5000000; 71 | contract.SetupContractData(result, "get()"); 72 | contract.Call(result); 73 | USE_SERIAL.println(result); 74 | ``` 75 | 76 | ### `sendTransaction` to Contract 77 | 78 | ```C++ 79 | Contract contract(&web3, CONTRACT_ADDRESS); 80 | contract.SetPrivateKey((uint8_t*)PRIVATE_KEY); 81 | uint32_t nonceVal = (uint32_t)web3.EthGetTransactionCount((char *)MY_ADDRESS); 82 | 83 | uint32_t gasPriceVal = 141006540; 84 | uint32_t gasLimitVal = 3000000; 85 | uint8_t toStr[] = CONTRACT_ADDRESS; 86 | uint8_t valueStr[] = "0x00"; 87 | uint8_t dataStr[100]; 88 | memset(dataStr, 0, 100); 89 | contract.SetupContractData((char*)dataStr, "set(uint256)", 123); 90 | contract.SendTransaction((uint8_t *) result, 91 | nonceVal, gasPriceVal, gasLimitVal, toStr, valueStr, dataStr); 92 | 93 | USE_SERIAL.println(result); 94 | ``` 95 | 96 | ## Dependency 97 | 98 | - [cJSON](https://github.com/DaveGamble/cJSON) 99 | - [secp256k1](https://github.com/bitcoin-core/secp256k1) 100 | - [ESP32-Arduino](https://github.com/espressif/arduino-esp32) 101 | 102 | -------------------------------------------------------------------------------- /examples/basic_eth/basic_eth.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define USE_SERIAL Serial 5 | 6 | #define ENV_SSID "" 7 | #define ENV_WIFI_KEY "" 8 | #define INFURA_HOST "rinkeby.infura.io" 9 | #define INFURA_PATH "/" 10 | #define ADDRESS "0x" 11 | 12 | Web3 web3(INFURA_HOST, INFURA_PATH); 13 | 14 | void eth_example(); 15 | 16 | void setup() { 17 | USE_SERIAL.begin(115200); 18 | 19 | for(uint8_t t = 4; t > 0; t--) { 20 | USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); 21 | USE_SERIAL.flush(); 22 | delay(1000); 23 | } 24 | 25 | WiFi.begin(ENV_SSID, ENV_WIFI_KEY); 26 | 27 | // attempt to connect to Wifi network: 28 | while (WiFi.status() != WL_CONNECTED) { 29 | Serial.print("."); 30 | // wait 1 second for re-trying 31 | delay(1000); 32 | } 33 | 34 | USE_SERIAL.println("Connected"); 35 | 36 | eth_example(); 37 | } 38 | 39 | void loop() { 40 | // put your main code here, to run repeatedly: 41 | } 42 | 43 | void eth_example() { 44 | char tmp[32]; 45 | 46 | double version = web3.EthProtocolVersion(); 47 | USE_SERIAL.println("eth_protocolVersion"); 48 | USE_SERIAL.println(version); 49 | 50 | bool listening = web3.EthSyncing(); 51 | USE_SERIAL.println("eth_syncing"); 52 | if (listening) { 53 | USE_SERIAL.println("syncing"); 54 | } else{ 55 | USE_SERIAL.println("not syncing"); 56 | } 57 | 58 | bool mining = web3.EthMining(); 59 | USE_SERIAL.println("eth_mining"); 60 | if (mining) { 61 | USE_SERIAL.println("mining"); 62 | } else{ 63 | USE_SERIAL.println("not mining"); 64 | } 65 | 66 | double hashrate = web3.EthHashrate(); 67 | USE_SERIAL.println("eth_hashrate"); 68 | USE_SERIAL.println(hashrate); 69 | 70 | long long int gasPrice = web3.EthGasPrice(); 71 | USE_SERIAL.println("eth_gasPrice"); 72 | memset(tmp, 0, 32); 73 | sprintf(tmp, "%lld", gasPrice); 74 | USE_SERIAL.println(tmp); 75 | 76 | int blockNumber = web3.EthBlockNumber(); 77 | USE_SERIAL.println("eth_blockNumber"); 78 | memset(tmp, 0, 32); 79 | sprintf(tmp, "%d", blockNumber); 80 | USE_SERIAL.println(tmp); 81 | 82 | string address = "0xd7049ea6f47ef848C0Ad570dbA618A9f6e4Eb25C"; 83 | long long int balance = web3.EthGetBalance(&address); 84 | USE_SERIAL.println("eth_getBalance"); 85 | memset(tmp, 0, 32); 86 | sprintf(tmp, "%lld", balance); 87 | USE_SERIAL.println(tmp); 88 | 89 | int txcount = web3.EthGetTransactionCount(&address); 90 | USE_SERIAL.println("eth_getTransactionCount"); 91 | memset(tmp, 0, 32); 92 | sprintf(tmp, "%d", txcount); 93 | USE_SERIAL.println(tmp); 94 | } 95 | -------------------------------------------------------------------------------- /examples/basic_net/basic_net.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define USE_SERIAL Serial 5 | 6 | #define ENV_SSID "" 7 | #define ENV_WIFI_KEY "" 8 | #define INFURA_HOST "rinkeby.infura.io" 9 | #define INFURA_PATH "/" 10 | 11 | Web3 web3(INFURA_HOST, INFURA_PATH); 12 | 13 | void net_example(); 14 | 15 | void setup() { 16 | USE_SERIAL.begin(115200); 17 | 18 | for(uint8_t t = 4; t > 0; t--) { 19 | USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); 20 | USE_SERIAL.flush(); 21 | delay(1000); 22 | } 23 | 24 | WiFi.begin(ENV_SSID, ENV_WIFI_KEY); 25 | 26 | // attempt to connect to Wifi network: 27 | while (WiFi.status() != WL_CONNECTED) { 28 | Serial.print("."); 29 | // wait 1 second for re-trying 30 | delay(1000); 31 | } 32 | 33 | USE_SERIAL.println("Connected"); 34 | 35 | net_example(); 36 | } 37 | 38 | void loop() { 39 | // put your main code here, to run repeatedly: 40 | } 41 | 42 | void net_example() { 43 | int version = web3.NetVersion(); 44 | USE_SERIAL.println("net_version"); 45 | USE_SERIAL.println(version); // 4 46 | 47 | bool listening = web3.NetListening(); 48 | USE_SERIAL.println("net_listening"); 49 | if (listening) { 50 | USE_SERIAL.println("listening"); 51 | } else{ 52 | USE_SERIAL.println("not listening"); 53 | } 54 | 55 | int peerCount = web3.NetPeerCount(); 56 | USE_SERIAL.println("net_peerCount"); 57 | USE_SERIAL.println(peerCount); 58 | } 59 | 60 | -------------------------------------------------------------------------------- /examples/basic_web3/basic_web3.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define USE_SERIAL Serial 5 | 6 | #define ENV_SSID "" 7 | #define ENV_WIFI_KEY "" 8 | #define INFURA_HOST "rinkeby.infura.io" 9 | #define INFURA_PATH "/" 10 | 11 | Web3 web3(INFURA_HOST, INFURA_PATH); 12 | 13 | void web3_example(); 14 | 15 | void setup() { 16 | USE_SERIAL.begin(115200); 17 | 18 | for(uint8_t t = 4; t > 0; t--) { 19 | USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); 20 | USE_SERIAL.flush(); 21 | delay(1000); 22 | } 23 | 24 | WiFi.begin(ENV_SSID, ENV_WIFI_KEY); 25 | 26 | // attempt to connect to Wifi network: 27 | while (WiFi.status() != WL_CONNECTED) { 28 | Serial.print("."); 29 | // wait 1 second for re-trying 30 | delay(1000); 31 | } 32 | 33 | USE_SERIAL.println("Connected"); 34 | 35 | web3_example(); 36 | } 37 | 38 | void loop() { 39 | // put your main code here, to run repeatedly: 40 | } 41 | 42 | void web3_example() { 43 | string result = web3.Web3ClientVersion(); 44 | USE_SERIAL.println("web3_ClientVersion"); 45 | USE_SERIAL.println(result.c_str()); 46 | 47 | string src = "0x68656c6c6f20776f726c64"; 48 | result = web3.Web3Sha3(&src); 49 | USE_SERIAL.println("web3_sha3"); 50 | USE_SERIAL.println(result.c_str()); // 0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad 51 | } 52 | -------------------------------------------------------------------------------- /examples/eth_call/eth_call.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define USE_SERIAL Serial 6 | 7 | #define ENV_SSID "" 8 | #define ENV_WIFI_KEY "" 9 | #define MY_ADDRESS "0x" 10 | #define CONTRACT_ADDRESS "0x" 11 | #define INFURA_HOST "rinkeby.infura.io" 12 | #define INFURA_PATH "/" 13 | 14 | Web3 web3(INFURA_HOST, INFURA_PATH); 15 | 16 | void eth_call_example(); 17 | 18 | void setup() { 19 | USE_SERIAL.begin(115200); 20 | 21 | for(uint8_t t = 4; t > 0; t--) { 22 | USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); 23 | USE_SERIAL.flush(); 24 | delay(1000); 25 | } 26 | 27 | WiFi.begin(ENV_SSID, ENV_WIFI_KEY); 28 | 29 | // attempt to connect to Wifi network: 30 | while (WiFi.status() != WL_CONNECTED) { 31 | Serial.print("."); 32 | // wait 1 second for re-trying 33 | delay(1000); 34 | } 35 | 36 | USE_SERIAL.println("Connected"); 37 | 38 | eth_call_example(); 39 | } 40 | 41 | void loop() { 42 | // put your main code here, to run repeatedly: 43 | } 44 | 45 | void eth_call_example() { 46 | Contract contract(&web3, CONTRACT_ADDRESS); 47 | strcpy(contract.options.from, MY_ADDRESS); 48 | strcpy(contract.options.gasPrice,"2000000000000"); 49 | contract.options.gas = 5000000; 50 | string func = "buyCoin()"; 51 | string param = contract.SetupContractData(&func); 52 | string result = contract.Call(¶m); 53 | USE_SERIAL.println(result.c_str()); 54 | } 55 | -------------------------------------------------------------------------------- /examples/eth_send/eth_send.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define USE_SERIAL Serial 6 | 7 | #define ENV_SSID "" 8 | #define ENV_WIFI_KEY "" 9 | #define MY_ADDRESS "0x" 10 | #define CONTRACT_ADDRESS "0x" 11 | #define INFURA_HOST "rinkeby.infura.io" 12 | #define INFURA_PATH "/" 13 | 14 | const char PRIVATE_KEY[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 15 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 16 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 17 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; 18 | Web3 web3(INFURA_HOST, INFURA_PATH); 19 | 20 | void eth_send_example(); 21 | 22 | void setup() { 23 | USE_SERIAL.begin(115200); 24 | 25 | for(uint8_t t = 4; t > 0; t--) { 26 | USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); 27 | USE_SERIAL.flush(); 28 | delay(1000); 29 | } 30 | 31 | WiFi.begin(ENV_SSID, ENV_WIFI_KEY); 32 | 33 | // attempt to connect to Wifi network: 34 | while (WiFi.status() != WL_CONNECTED) { 35 | Serial.print("."); 36 | // wait 1 second for re-trying 37 | delay(1000); 38 | } 39 | 40 | USE_SERIAL.println("Connected"); 41 | 42 | eth_send_example(); 43 | } 44 | 45 | void loop() { 46 | // put your main code here, to run repeatedly: 47 | } 48 | 49 | void eth_send_example() { 50 | Contract contract(&web3, CONTRACT_ADDRESS); 51 | contract.SetPrivateKey((uint8_t*)PRIVATE_KEY); 52 | uint32_t nonceVal = (uint32_t)web3.EthGetTransactionCount((char *)MY_ADDRESS); 53 | 54 | uint32_t gasPriceVal = 141006540; 55 | uint32_t gasLimitVal = 3000000; 56 | uint8_t toStr[] = CONTRACT_ADDRESS; 57 | uint8_t valueStr[] = "0x00"; 58 | uint8_t dataStr[100]; 59 | memset(dataStr, 0, 100); 60 | string func = "set(uint256)"; 61 | string p = contract.SetupContractData(&func, 123); 62 | string result = contract.SendTransaction(nonceVal, gasPriceVal, gasLimitVal, &toStr, &valueStr, &p); 63 | 64 | USE_SERIAL.println(result); 65 | } 66 | -------------------------------------------------------------------------------- /examples/sample.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | contract Sample { 4 | uint data; 5 | 6 | function set(uint d) public{ 7 | data = d; 8 | } 9 | 10 | function get() public constant returns (uint retVal) { 11 | return data; 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ######################################################## 2 | # Class 3 | ################################################################### 4 | 5 | Web3 KEYWORD1 6 | Contract KEYWORD1 7 | 8 | ################################################################### 9 | # Methods and Functions 10 | ################################################################### 11 | 12 | Web3ClientVersion KEYWORD2 13 | Web3Sha3 KEYWORD2 14 | NetVersion KEYWORD2 15 | NetListening KEYWORD2 16 | NetPeerCount KEYWORD2 17 | EthProtocolVersion KEYWORD2 18 | EthSyncing KEYWORD2 19 | EthMining KEYWORD2 20 | EthHashrate KEYWORD2 21 | EthGasPrice KEYWORD2 22 | EthAccounts KEYWORD2 23 | EthBlockNumber KEYWORD2 24 | EthGetTransactionCount KEYWORD2 25 | EthCall KEYWORD2 26 | EthSendSignedTransaction KEYWORD2 27 | SetPrivateKey KEYWORD2 28 | SetupContractData KEYWORD2 29 | Call KEYWORD2 30 | SendTransaction KEYWORD2 31 | 32 | ################################################################### 33 | # Constants 34 | ################################################################### 35 | 36 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web3-arduino", 3 | "keywords": "blockchain, web3, ethereum, smartcontract", 4 | "description": "This is an Arduino (or ESP32) library to use web3 on Ethereum platform. You can call and send transactions to smart contract on Ethereum blockchain", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/kopanitsa/web3-arduino.git" 8 | }, 9 | "authors": 10 | { 11 | "name": "Takahiro Okada", 12 | "email": "okada.takahiro111@gmail.com" 13 | }, 14 | "version": "0.9", 15 | "examples": "examples/*/*.ino", 16 | "frameworks": "arduino", 17 | "platforms": [ 18 | "atmelavr", 19 | "espressif" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=web3-arduino 2 | version=0.9 3 | author=Takahiro Okada 4 | email=okada.takahiro111@gmail.com 5 | url=https://github.com/kopanitsa/web3-arduino.git 6 | sentence=Arduino (or ESP32) library to use web3 on Ethereum platform. 7 | paragraph=You can call and send transactions to smart contract on Ethereum blockchain. 8 | category=Communication 9 | architectures=* 10 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; http://docs.platformio.org/page/projectconf.html 10 | 11 | [env:esp32dev] 12 | platform = espressif32 13 | board = esp32dev 14 | framework = arduino 15 | -------------------------------------------------------------------------------- /src/CaCert.h: -------------------------------------------------------------------------------- 1 | const char* infura_ca_cert = \ 2 | "-----BEGIN CERTIFICATE-----\n" \ 3 | "MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx\n" \ 4 | "EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\n" \ 5 | "HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs\n" \ 6 | "ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5\n" \ 7 | "MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD\n" \ 8 | "VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy\n" \ 9 | "ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy\n" \ 10 | "dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI\n" \ 11 | "hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p\n" \ 12 | "OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2\n" \ 13 | "8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K\n" \ 14 | "Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe\n" \ 15 | "hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk\n" \ 16 | "6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw\n" \ 17 | "DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q\n" \ 18 | "AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI\n" \ 19 | "bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB\n" \ 20 | "ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z\n" \ 21 | "qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd\n" \ 22 | "iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn\n" \ 23 | "0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN\n" \ 24 | "sSi6\n" \ 25 | "-----END CERTIFICATE-----\n" \ 26 | ; 27 | -------------------------------------------------------------------------------- /src/Conf.h.example: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Okada, Takahiro on 2018/02/03. 3 | // 4 | 5 | #ifndef ARDUINO_WEB3_CONSTANTS_H 6 | #define ARDUINO_WEB3_CONSTANTS_H 7 | 8 | #define ENV_SSID "YOUR_SSID" 9 | #define ENV_WIFI_KEY "YOUR_PASSWORD" 10 | const char* INFURA_HOST = "rinkeby.infura.io"; 11 | const char* INFURA_PATH = "/YOUR_PATH"; 12 | const uint8_t privateKey[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 16 | #endif //ARDUINO_WEB3_CONSTANTS_H 17 | -------------------------------------------------------------------------------- /src/Contract.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Okada, Takahiro on 2018/02/05. 3 | // 4 | 5 | #ifndef ARDUINO_WEB3_CONTRACT_H 6 | #define ARDUINO_WEB3_CONTRACT_H 7 | 8 | #include "Arduino.h" 9 | #include "Log.h" 10 | #include "Web3.h" 11 | #include 12 | 13 | using namespace std; 14 | 15 | class Contract { 16 | 17 | public: 18 | typedef struct { 19 | char from[80]; 20 | char to[80]; 21 | char gasPrice[20]; 22 | long gas; 23 | } Options; 24 | Options options; 25 | 26 | public: 27 | Contract(Web3* _web3, const string* address); 28 | void SetPrivateKey(const uint8_t *key); 29 | string SetupContractData(const string *func, ...); 30 | string Call(const string* param); 31 | string SendTransaction(uint32_t nonceVal, uint32_t gasPriceVal, uint32_t gasLimitVal, 32 | string *toStr, string *valueStr, string *dataStr); 33 | 34 | private: 35 | Log Debug; 36 | #define LOG(x) Debug.println(x) 37 | 38 | Web3* web3; 39 | const string * contractAddress; 40 | const uint8_t * privateKey; 41 | 42 | private: 43 | string GenerateContractBytes(const string *func); 44 | string GenerateBytesForInt(const int32_t value); 45 | string GenerateBytesForUint(const uint32_t value); 46 | string GenerateBytesForAddress(const string *value); 47 | string GenerateBytesForString(const string *value); 48 | string GenerateBytesForBytes(const char* value, const int len); 49 | 50 | void GenerateSignature(uint8_t* signature, int* recid, uint32_t nonceVal, uint32_t gasPriceVal, uint32_t gasLimitVal, 51 | string* toStr, string* valueStr, string* dataStr); 52 | vector RlpEncode( 53 | uint32_t nonceVal, uint32_t gasPriceVal, uint32_t gasLimitVal, 54 | string* toStr, string* valueStr, string* dataStr); 55 | vector RlpEncodeForRawTransaction( 56 | uint32_t nonceVal, uint32_t gasPriceVal, uint32_t gasLimitVal, 57 | string* toStr, string* valueStr, string* dataStr, uint8_t* sig, uint8_t recid); 58 | void Sign(uint8_t* hash, uint8_t* sig, int* recid); 59 | }; 60 | 61 | 62 | #endif //ARDUINO_WEB3_CONTRACT_H 63 | -------------------------------------------------------------------------------- /src/Log.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Okada, Takahiro on 2018/02/04. 3 | // 4 | 5 | #include "Log.h" 6 | #include 7 | #define USE_SERIAL Serial 8 | 9 | void Log::print(const char* s) { 10 | #ifdef DEBUGLOG 11 | USE_SERIAL.print(s); 12 | #endif 13 | } 14 | void Log::println(const char* s) { 15 | #ifdef DEBUGLOG 16 | USE_SERIAL.println(s); 17 | #endif 18 | } -------------------------------------------------------------------------------- /src/Log.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Okada, Takahiro on 2018/02/04. 3 | // 4 | 5 | #ifndef ARDUINO_WEB3_LOG_H 6 | #define ARDUINO_WEB3_LOG_H 7 | 8 | #define DEBUGLOG 9 | 10 | class Log { 11 | public: 12 | void print(const char* s); 13 | void println(const char* s); 14 | }; 15 | 16 | #endif //ARDUINO_WEB3_LOG_H 17 | -------------------------------------------------------------------------------- /src/Util.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Okada, Takahiro on 2018/02/11. 3 | // 4 | 5 | #include "Util.h" 6 | #include "Arduino.h" 7 | #include 8 | #include 9 | #include 10 | 11 | // returns output (header) length 12 | uint32_t Util::RlpEncodeWholeHeader(uint8_t* header_output, uint32_t total_len) { 13 | if (total_len < 55) { 14 | header_output[0] = (uint8_t)0xc0 + (uint8_t)total_len; 15 | return 1; 16 | } else { 17 | uint8_t tmp_header[8]; 18 | memset(tmp_header, 0, 8); 19 | uint32_t hexdigit = 1; 20 | uint32_t tmp = total_len; 21 | while ((uint32_t)(tmp / 256) > 0) { 22 | tmp_header[hexdigit] = (uint8_t)(tmp % 256); 23 | tmp = (uint32_t)(tmp / 256); 24 | hexdigit++; 25 | } 26 | tmp_header[hexdigit] = (uint8_t)(tmp); 27 | tmp_header[0] = (uint8_t)0xf7 + (uint8_t)hexdigit; 28 | 29 | // fix direction for header 30 | uint8_t header[8]; 31 | memset(header, 0, 8); 32 | header[0] = tmp_header[0]; 33 | for (int i=0; i Util::RlpEncodeWholeHeaderWithVector(uint32_t total_len) { 43 | vector header_output; 44 | if (total_len < 55) { 45 | header_output.push_back((uint8_t)0xc0 + (uint8_t)total_len); 46 | } else { 47 | vector tmp_header; 48 | uint32_t hexdigit = 1; 49 | uint32_t tmp = total_len; 50 | while ((uint32_t)(tmp / 256) > 0) { 51 | tmp_header.push_back((uint8_t)(tmp % 256)); 52 | tmp = (uint32_t)(tmp / 256); 53 | hexdigit++; 54 | } 55 | tmp_header.push_back((uint8_t)(tmp)); 56 | tmp_header.insert(tmp_header.begin(), 0xf7 + (uint8_t)hexdigit); 57 | 58 | // fix direction for header 59 | vector header; 60 | header.push_back(tmp_header[0]); 61 | for (int i=0; i 0) { 92 | tmp_header[hexdigit] = (uint8_t)(tmp % 256); 93 | tmp = (uint32_t)(tmp / 256); 94 | hexdigit++; 95 | } 96 | tmp_header[hexdigit] = (uint8_t)(tmp); 97 | tmp_header[0] = (uint8_t)0xb7 + (uint8_t)hexdigit; 98 | 99 | // fix direction for header 100 | uint8_t header[8]; 101 | memset(header, 0, 8); 102 | header[0] = tmp_header[0]; 103 | for (int i=0; i Util::RlpEncodeItemWithVector(const vector input) { 114 | vector output; 115 | uint16_t input_len = input.size(); 116 | 117 | if (input_len==1 && input[0] == 0x00) { 118 | output.push_back(0x80); 119 | } else if (input_len==1 && input[0] < 128) { 120 | output.insert(output.end(), input.begin(), input.end()); 121 | } else if (input_len <= 55) { 122 | uint8_t _ = (uint8_t)0x80 + (uint8_t)input_len; 123 | output.push_back(_); 124 | output.insert(output.end(), input.begin(), input.end()); 125 | } else { 126 | vector tmp_header; 127 | uint32_t tmp = input_len; 128 | while ((uint32_t)(tmp / 256) > 0) { 129 | tmp_header.push_back((uint8_t)(tmp % 256)); 130 | tmp = (uint32_t)(tmp / 256); 131 | } 132 | tmp_header.push_back((uint8_t)(tmp)); 133 | uint8_t len = tmp_header.size() + 1; 134 | tmp_header.insert(tmp_header.begin(), 0xb7 + len); 135 | 136 | // fix direction for header 137 | vector header; 138 | header.push_back(tmp_header[0]); 139 | uint8_t hexdigit = tmp_header.size() - 1; 140 | for (int i=0; i Util::ConvertNumberToVector(uint32_t val) { 151 | vector tmp; 152 | vector ret; 153 | if ((uint32_t)(val / 256) >= 0) { 154 | while ((uint32_t)(val / 256) > 0) { 155 | tmp.push_back((uint8_t)(val % 256)); 156 | val = (uint32_t)(val / 256); 157 | } 158 | tmp.push_back((uint8_t)(val % 256)); 159 | uint8_t len = tmp.size(); 160 | for (int i=0; i= 0) { 174 | while ((uint32_t)(val / 256) > 0) { 175 | tmp[ret] = (uint8_t)(val % 256); 176 | val = (uint32_t)(val / 256); 177 | ret++; 178 | } 179 | tmp[ret] = (uint8_t)(val % 256); 180 | for (int i=0; i Util::ConvertCharStrToVector(const uint8_t *in) { 191 | uint32_t ret = 0; 192 | uint8_t tmp[256]; 193 | strcpy((char *)tmp, (char *)in); 194 | vector out; 195 | 196 | // remove "0x" 197 | char * ptr = strtok((char*)tmp, "x"); 198 | if (strlen(ptr)!=1) { 199 | ptr = (char *)tmp; 200 | } else { 201 | ptr = strtok(NULL, "x"); 202 | } 203 | 204 | size_t lenstr = strlen(ptr); 205 | for (int i=0; i Util::ConvertStringToVector(const string* str) { 218 | return ConvertCharStrToVector((uint8_t*)(str->c_str())); 219 | } 220 | 221 | uint32_t Util::ConvertCharStrToUintArray(uint8_t *out, const uint8_t *in) { 222 | uint32_t ret = 0; 223 | uint8_t tmp[256]; 224 | strcpy((char *)tmp, (char *)in); 225 | 226 | // remove "0x" 227 | char * ptr = strtok((char*)tmp, "x"); 228 | if (strlen(ptr)!=1) { 229 | ptr = (char *)tmp; 230 | } else { 231 | ptr = strtok(NULL, "x"); 232 | } 233 | 234 | size_t lenstr = strlen(ptr); 235 | for (int i=0; i= '0' && s <= '9'){ 250 | ret = uint8_t(s - '0'); 251 | } else if(s >= 'a' && s <= 'f'){ 252 | ret = uint8_t(s - 'a' + 10); 253 | } else if(s >= 'A' && s <= 'F'){ 254 | ret = uint8_t(s - 'A' + 10); 255 | } 256 | return ret; 257 | } 258 | 259 | void Util::BufToCharStr(char* str, const uint8_t* buf, uint32_t len) { 260 | sprintf(str, "0x"); 261 | for (int i = 0; i < len; i++) { 262 | sprintf(str, "%s%02x", str, buf[i]); 263 | } 264 | } 265 | 266 | void Util::VectorToCharStr(char* str, const vector buf) { 267 | sprintf(str, "0x"); 268 | for (int i = 0; i < buf.size(); i++) { 269 | sprintf(str, "%s%02x", str, buf[i]); 270 | } 271 | } 272 | 273 | string Util::VectorToString(const vector buf) { 274 | string ret = "0x"; 275 | for (int i = 0; i < buf.size(); i++) { 276 | char v[3]; 277 | memset(v, 0, sizeof(v)); 278 | sprintf(v, "%02x", buf[i]); 279 | ret = ret + string(v); 280 | } 281 | return ret; 282 | } 283 | -------------------------------------------------------------------------------- /src/Util.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Okada, Takahiro on 2018/02/11. 3 | // 4 | 5 | #ifndef WEB3_UTIL_H 6 | #define WEB3_UTIL_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | class Util { 15 | public: 16 | // RLP implementation 17 | // reference: 18 | // https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP 19 | static uint32_t RlpEncodeWholeHeader(uint8_t *header_output, uint32_t total_len); 20 | static vector RlpEncodeWholeHeaderWithVector(uint32_t total_len); 21 | static uint32_t RlpEncodeItem(uint8_t* output, const uint8_t* input, uint32_t input_len); 22 | static vector RlpEncodeItemWithVector(const vector input); 23 | 24 | static uint32_t ConvertNumberToUintArray(uint8_t *str, uint32_t val); 25 | static vector ConvertNumberToVector(uint32_t val); 26 | static uint32_t ConvertCharStrToUintArray(uint8_t *out, const uint8_t *in); 27 | static vector ConvertCharStrToVector(const uint8_t *in); 28 | static vector ConvertStringToVector(const string* str); 29 | 30 | static uint8_t HexToInt(uint8_t s); 31 | static void BufToCharStr(char* str, const uint8_t* buf, uint32_t len); 32 | static void VectorToCharStr(char* str, const vector buf); 33 | static string VectorToString(const vector buf); 34 | 35 | }; 36 | 37 | #endif //WEB3_UTIL_H 38 | -------------------------------------------------------------------------------- /src/Web3.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Okada, Takahiro on 2018/02/04. 3 | // 4 | 5 | #include "Web3.h" 6 | #include 7 | #include "CaCert.h" 8 | #include "Log.h" 9 | #include "Util.h" 10 | #include "cJSON/cJSON.h" 11 | #include 12 | #include 13 | 14 | WiFiClientSecure client; 15 | Log debug; 16 | #define LOG(x) debug.println(x) 17 | 18 | Web3::Web3(const string* _host, const string* _path) { 19 | client.setCACert(infura_ca_cert); 20 | host = _host; 21 | path = _path; 22 | } 23 | 24 | string Web3::Web3ClientVersion() { 25 | string m = "web3_clientVersion"; 26 | string p = "[]"; 27 | string input = generateJson(&m, &p); 28 | string output = exec(&input); 29 | return getString(&output); 30 | } 31 | 32 | string Web3::Web3Sha3(const string* data) { 33 | string m = "web3_sha3"; 34 | string p = "[\"" + *data + "\"]"; 35 | string input = generateJson(&m, &p); 36 | string output = exec(&input); 37 | return getString(&output); 38 | } 39 | 40 | int Web3::NetVersion() { 41 | string m = "net_version"; 42 | string p = "[]"; 43 | string input = generateJson(&m, &p); 44 | string output = exec(&input); 45 | return getInt(&output); 46 | } 47 | 48 | bool Web3::NetListening() { 49 | string m = "net_listening"; 50 | string p = "[]"; 51 | string input = generateJson(&m, &p); 52 | string output = exec(&input); 53 | return getBool(&output); 54 | } 55 | 56 | int Web3::NetPeerCount() { 57 | string m = "net_peerCount"; 58 | string p = "[]"; 59 | string input = generateJson(&m, &p); 60 | string output = exec(&input); 61 | return getInt(&output); 62 | } 63 | 64 | double Web3::EthProtocolVersion() { 65 | string m = "eth_protocolVersion"; 66 | string p = "[]"; 67 | string input = generateJson(&m, &p); 68 | string output = exec(&input); 69 | return getDouble(&output); 70 | } 71 | 72 | bool Web3::EthSyncing() { 73 | string m = "eth_syncing"; 74 | string p = "[]"; 75 | string input = generateJson(&m, &p); 76 | string result = exec(&input); 77 | 78 | cJSON *root, *value; 79 | root = cJSON_Parse(result.c_str()); 80 | value = cJSON_GetObjectItem(root, "result"); 81 | bool ret; 82 | if (cJSON_IsBool(value)) { 83 | ret = false; 84 | } else{ 85 | ret = true; 86 | } 87 | cJSON_free(root); 88 | return ret; 89 | } 90 | 91 | bool Web3::EthMining() { 92 | string m = "eth_mining"; 93 | string p = "[]"; 94 | string input = generateJson(&m, &p); 95 | string output = exec(&input); 96 | return getBool(&output); 97 | } 98 | 99 | double Web3::EthHashrate() { 100 | string m = "eth_hashrate"; 101 | string p = "[]"; 102 | string input = generateJson(&m, &p); 103 | string output = exec(&input); 104 | return getDouble(&output); 105 | } 106 | 107 | long long int Web3::EthGasPrice() { 108 | string m = "eth_gasPrice"; 109 | string p = "[]"; 110 | string input = generateJson(&m, &p); 111 | string output = exec(&input); 112 | return getLongLong(&output); 113 | } 114 | 115 | void Web3::EthAccounts(char** array, int size) { 116 | // TODO 117 | } 118 | 119 | int Web3::EthBlockNumber() { 120 | string m = "eth_blockNumber"; 121 | string p = "[]"; 122 | string input = generateJson(&m, &p); 123 | string output = exec(&input); 124 | return getInt(&output); 125 | } 126 | 127 | long long int Web3::EthGetBalance(const string* address) { 128 | string m = "eth_getBalance"; 129 | string p = "[\"" + *address + "\",\"latest\"]"; 130 | string input = generateJson(&m, &p); 131 | string output = exec(&input); 132 | return getLongLong(&output); 133 | } 134 | 135 | int Web3::EthGetTransactionCount(const string* address) { 136 | string m = "eth_getTransactionCount"; 137 | string p = "[\"" + *address + "\",\"latest\"]"; 138 | string input = generateJson(&m, &p); 139 | string output = exec(&input); 140 | return getInt(&output); 141 | } 142 | 143 | string Web3::EthCall(const string* from, const string* to, long gas, long gasPrice, 144 | const string* value, const string* data) { 145 | // TODO use gas, gasprice and value 146 | string m = "eth_call"; 147 | string p = "[{\"from\":\"" + *from + "\",\"to\":\"" 148 | + *to + "\",\"data\":\"" + *data + "\"}, \"latest\"]"; 149 | string input = generateJson(&m, &p); 150 | return exec(&input); 151 | } 152 | 153 | string Web3::EthSendSignedTransaction(const string* data, const uint32_t dataLen) { 154 | string m = "eth_sendRawTransaction"; 155 | string p = "[\"" + *data + "\"]"; 156 | string input = generateJson(&m, &p); 157 | #if 0 158 | LOG(input); 159 | #endif 160 | return exec(&input); 161 | } 162 | 163 | // ------------------------------- 164 | // Private 165 | 166 | string Web3::generateJson(const string* method, const string* params) { 167 | return "{\"jsonrpc\":\"2.0\",\"method\":\"" + *method + "\",\"params\":" + *params + ",\"id\":0}"; 168 | } 169 | 170 | string Web3::exec(const string* data) { 171 | string result; 172 | 173 | // start connection 174 | LOG("\nStarting connection to server..."); 175 | int connected = client.connect(host->c_str(), 443); 176 | if (!connected) { 177 | return ""; 178 | } 179 | 180 | LOG("Connected to server!"); 181 | // Make a HTTP request: 182 | int l = data->size(); 183 | stringstream ss; 184 | ss << l; 185 | string lstr = ss.str(); 186 | 187 | string strPost = "POST " + *path + " HTTP/1.1"; 188 | string strHost = "Host: " + *host; 189 | string strContentLen = "Content-Length: " + lstr; 190 | 191 | client.println(strPost.c_str()); 192 | client.println(strHost.c_str()); 193 | client.println("Content-Type: application/json"); 194 | client.println(strContentLen.c_str()); 195 | client.println("Connection: close"); 196 | client.println(); 197 | client.println(data->c_str()); 198 | 199 | while (client.connected()) { 200 | String line = client.readStringUntil('\n'); 201 | LOG(line.c_str()); 202 | if (line == "\r") { 203 | break; 204 | } 205 | } 206 | // if there are incoming bytes available 207 | // from the server, read them and print them: 208 | while (client.available()) { 209 | char c = client.read(); 210 | result += c; 211 | } 212 | LOG(result.c_str()); 213 | 214 | client.stop(); 215 | 216 | return result; 217 | } 218 | 219 | int Web3::getInt(const string* json) { 220 | int ret = -1; 221 | cJSON *root, *value; 222 | root = cJSON_Parse(json->c_str()); 223 | value = cJSON_GetObjectItem(root, "result"); 224 | if (cJSON_IsString(value)) { 225 | ret = strtol(value->valuestring, nullptr, 16); 226 | } 227 | cJSON_free(root); 228 | return ret; 229 | } 230 | 231 | long Web3::getLong(const string* json) { 232 | long ret = -1; 233 | cJSON *root, *value; 234 | root = cJSON_Parse(json->c_str()); 235 | value = cJSON_GetObjectItem(root, "result"); 236 | if (cJSON_IsString(value)) { 237 | ret = strtol(value->valuestring, nullptr, 16); 238 | } 239 | cJSON_free(root); 240 | return ret; 241 | } 242 | 243 | long long int Web3::getLongLong(const string* json) { 244 | long long int ret = -1; 245 | cJSON *root, *value; 246 | root = cJSON_Parse(json->c_str()); 247 | value = cJSON_GetObjectItem(root, "result"); 248 | if (cJSON_IsString(value)) { 249 | ret = strtoll(value->valuestring, nullptr, 16); 250 | } 251 | cJSON_free(root); 252 | return ret; 253 | } 254 | 255 | double Web3::getDouble(const string* json) { 256 | double ret = -1; 257 | cJSON *root, *value; 258 | root = cJSON_Parse(json->c_str()); 259 | value = cJSON_GetObjectItem(root, "result"); 260 | if (cJSON_IsString(value)) { 261 | LOG(value->valuestring); 262 | ret = strtof(value->valuestring, nullptr); 263 | } 264 | cJSON_free(root); 265 | return ret; 266 | } 267 | 268 | bool Web3::getBool(const string* json) { 269 | bool ret = false; 270 | cJSON *root, *value; 271 | root = cJSON_Parse(json->c_str()); 272 | value = cJSON_GetObjectItem(root, "result"); 273 | if (cJSON_IsBool(value)) { 274 | ret = (bool)value->valueint; 275 | } 276 | cJSON_free(root); 277 | return ret; 278 | } 279 | 280 | string Web3::getString(const string* json) { 281 | cJSON *root, *value; 282 | root = cJSON_Parse(json->c_str()); 283 | value = cJSON_GetObjectItem(root, "result"); 284 | if (cJSON_IsString(value)) { 285 | cJSON_free(root); 286 | return string(value->valuestring); 287 | } 288 | cJSON_free(root); 289 | return nullptr; 290 | } 291 | -------------------------------------------------------------------------------- /src/Web3.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Okada, Takahiro on 2018/02/04. 3 | // 4 | 5 | #ifndef ARDUINO_WEB3_WEB3_H 6 | #define ARDUINO_WEB3_WEB3_H 7 | 8 | #include "stdint.h" 9 | #include 10 | 11 | using namespace std; 12 | 13 | class Web3 { 14 | public: 15 | Web3(const string* _host, const string* _path); 16 | string Web3ClientVersion(); 17 | string Web3Sha3(const string* data); 18 | int NetVersion(); 19 | bool NetListening(); 20 | int NetPeerCount(); 21 | double EthProtocolVersion(); 22 | bool EthSyncing(); 23 | bool EthMining(); 24 | double EthHashrate(); 25 | long long int EthGasPrice(); 26 | void EthAccounts(char** array, int size); 27 | int EthBlockNumber(); 28 | long long int EthGetBalance(const string* address); 29 | int EthGetTransactionCount(const string* address); 30 | 31 | string EthCall(const string* from, const string* to, long gas, long gasPrice, const string* value, const string* data); 32 | string EthSendSignedTransaction(const string* data, const uint32_t dataLen); 33 | 34 | private: 35 | string exec(const string* data); 36 | string generateJson(const string* method, const string* params); 37 | int getInt(const string* json); 38 | long getLong(const string* json); 39 | long long int getLongLong(const string* json); 40 | double getDouble(const string* json); 41 | bool getBool(const string* json); 42 | string getString(const string* json); 43 | 44 | private: 45 | const string* host; 46 | const string* path; 47 | 48 | 49 | }; 50 | 51 | #endif //ARDUINO_WEB3_WEB3_H 52 | -------------------------------------------------------------------------------- /src/examples/example.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Okada, Takahiro on 2018/02/03. 3 | // 4 | // Reference: 5 | // Arduino sample code (WiFiClientSecure) 6 | // 7 | 8 | #include 9 | #include 10 | #include "../Contract.h" 11 | #include "../Conf.h" 12 | #include "../Web3.h" 13 | 14 | #define USE_SERIAL Serial 15 | 16 | string host = INFURA_HOST; 17 | string path = INFURA_PATH; 18 | Web3 web3(&host, &path); 19 | 20 | void testWeb3(); 21 | void testNet(); 22 | void testEth1(); 23 | void testEth2(); 24 | void testEth3(); 25 | 26 | void setup() { 27 | 28 | USE_SERIAL.begin(115200); 29 | 30 | USE_SERIAL.println(); 31 | USE_SERIAL.println(); 32 | USE_SERIAL.println(); 33 | 34 | for(uint8_t t = 4; t > 0; t--) { 35 | USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); 36 | USE_SERIAL.flush(); 37 | delay(1000); 38 | } 39 | 40 | WiFi.begin(ENV_SSID, ENV_WIFI_KEY); 41 | 42 | // attempt to connect to Wifi network: 43 | while (WiFi.status() != WL_CONNECTED) { 44 | Serial.print("."); 45 | // wait 1 second for re-trying 46 | delay(1000); 47 | } 48 | 49 | USE_SERIAL.println("Connected"); 50 | 51 | // testWeb3(); 52 | // testNet(); 53 | // testEth1(); 54 | testEth2(); 55 | testEth3(); 56 | } 57 | 58 | void testWeb3() { 59 | string result = web3.Web3ClientVersion(); 60 | USE_SERIAL.println("web3_ClientVersion"); 61 | USE_SERIAL.println(result.c_str()); 62 | 63 | string src = "0x68656c6c6f20776f726c64"; 64 | result = web3.Web3Sha3(&src); 65 | USE_SERIAL.println("web3_sha3"); 66 | USE_SERIAL.println(result.c_str()); // 0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad 67 | } 68 | 69 | void testNet() { 70 | int version = web3.NetVersion(); 71 | USE_SERIAL.println("net_version"); 72 | USE_SERIAL.println(version); // 4 73 | 74 | bool listening = web3.NetListening(); 75 | USE_SERIAL.println("net_listening"); 76 | if (listening) { 77 | USE_SERIAL.println("listening"); 78 | } else{ 79 | USE_SERIAL.println("not listening"); 80 | } 81 | 82 | int peerCount = web3.NetPeerCount(); 83 | USE_SERIAL.println("net_peerCount"); 84 | USE_SERIAL.println(peerCount); 85 | } 86 | 87 | void testEth1() { 88 | char tmp[32]; 89 | 90 | double version = web3.EthProtocolVersion(); 91 | USE_SERIAL.println("eth_protocolVersion"); 92 | USE_SERIAL.println(version); 93 | 94 | bool listening = web3.EthSyncing(); 95 | USE_SERIAL.println("eth_syncing"); 96 | if (listening) { 97 | USE_SERIAL.println("syncing"); 98 | } else{ 99 | USE_SERIAL.println("not syncing"); 100 | } 101 | 102 | bool mining = web3.EthMining(); 103 | USE_SERIAL.println("eth_mining"); 104 | if (mining) { 105 | USE_SERIAL.println("mining"); 106 | } else{ 107 | USE_SERIAL.println("not mining"); 108 | } 109 | 110 | double hashrate = web3.EthHashrate(); 111 | USE_SERIAL.println("eth_hashrate"); 112 | USE_SERIAL.println(hashrate); 113 | 114 | long long int gasPrice = web3.EthGasPrice(); 115 | USE_SERIAL.println("eth_gasPrice"); 116 | memset(tmp, 0, 32); 117 | sprintf(tmp, "%lld", gasPrice); 118 | USE_SERIAL.println(tmp); 119 | 120 | int blockNumber = web3.EthBlockNumber(); 121 | USE_SERIAL.println("eth_blockNumber"); 122 | memset(tmp, 0, 32); 123 | sprintf(tmp, "%d", blockNumber); 124 | USE_SERIAL.println(tmp); 125 | 126 | string address = "0xd7049ea6f47ef848C0Ad570dbA618A9f6e4Eb25C"; 127 | long long int balance = web3.EthGetBalance(&address); 128 | USE_SERIAL.println("eth_getBalance"); 129 | memset(tmp, 0, 32); 130 | sprintf(tmp, "%lld", balance); 131 | USE_SERIAL.println(tmp); 132 | 133 | int txcount = web3.EthGetTransactionCount(&address); 134 | USE_SERIAL.println("eth_getTransactionCount"); 135 | memset(tmp, 0, 32); 136 | sprintf(tmp, "%d", txcount); 137 | USE_SERIAL.println(tmp); 138 | 139 | } 140 | 141 | void testEth2() { 142 | string from = "0xd7049ea6f47ef848c0ad570dba618a9f6e4eb25c"; 143 | string to = "0x018968e41da1364e328499613a7e5a22904ad513"; 144 | string value = ""; 145 | string data = "0x30cc3597d7049ea6f47ef848c0ad570dba618a9f6e4eb25c"; 146 | string result = ""; 147 | result = web3.EthCall(&from, &to, 0, 0, &data, &data); 148 | USE_SERIAL.println("eth_call"); 149 | 150 | string contract_address = "0x018968e41da1364e328499613a7e5a22904ad513"; 151 | Contract contract(&web3, &contract_address); 152 | strcpy(contract.options.from,"0xd7049ea6f47ef848c0ad570dba618a9f6e4eb25c"); 153 | strcpy(contract.options.gasPrice,"20000000000000"); 154 | contract.options.gas = 5000000; 155 | string func = "buyCoin()"; 156 | string param = contract.SetupContractData(&func); 157 | result = contract.Call(¶m); 158 | USE_SERIAL.println(result.c_str()); 159 | 160 | func = "hogeuint(uint8,uint16,uint32,uint256,uint)"; 161 | param = contract.SetupContractData(&func, 1, 12345, 1003, 4, 5); 162 | result = contract.Call(¶m); 163 | USE_SERIAL.println(result.c_str()); 164 | 165 | func = "hogeint(int8,int16,int32,int256,int)"; 166 | param = contract.SetupContractData(&func, -1, 12345, -1003, 4, -5); 167 | result = contract.Call(¶m); 168 | USE_SERIAL.println(result.c_str()); 169 | 170 | string address = "0xd7049ea6f47ef848C0Ad570dbA618A9f6e4Eb25C"; 171 | func = "hogeaddress(address)"; 172 | param = contract.SetupContractData(&func, &address); 173 | result = contract.Call(&result); 174 | USE_SERIAL.println(result.c_str()); 175 | 176 | func = "hogebool(bool,bool)"; 177 | param = contract.SetupContractData(&func, true, false); 178 | 179 | result = contract.Call(&result); 180 | USE_SERIAL.println(result.c_str()); 181 | 182 | string strParam = "Hello, world!"; 183 | func = "hogestring(string)"; 184 | param = contract.SetupContractData(&func, &strParam); 185 | result = contract.Call(&result); 186 | USE_SERIAL.println(result.c_str()); 187 | 188 | func = "hogebytes(bytes5,bytes12)"; 189 | param = contract.SetupContractData(&func, "hello", "123456789012"); 190 | result = contract.Call(&result); 191 | USE_SERIAL.println(result.c_str()); 192 | 193 | } 194 | 195 | void testEth3() { 196 | // raw transaction 197 | string param = "0xf8885a84086796cc832dc6c094e759aab0343e7d4c9e23ac5760a12ed9d9af442180a460fe47b100000000000000000000000000000000000000000000000000000000000000641ca0278d62b5bf2440fe1c572931a60970cccbaa167425575bcef80bf93f6bda6e7fa031efdd7520f72dc1eb8b619c1cf5058d8cbdd3581c5e16a40787e8887e8be257"; 198 | string ret = web3.EthSendSignedTransaction(¶m, param.size()); 199 | USE_SERIAL.println("eth_sendRawTransaction"); 200 | USE_SERIAL.println(ret.c_str()); 201 | 202 | // transaction 203 | string contract_address = "0xe759aab0343e7d4c9e23ac5760a12ed9d9af4421"; 204 | Contract contract(&web3, &contract_address); 205 | contract.SetPrivateKey(privateKey); 206 | string address = "0xd7049ea6f47ef848C0Ad570dbA618A9f6e4Eb25C"; 207 | uint32_t nonceVal = (uint32_t)web3.EthGetTransactionCount(&address); 208 | 209 | uint32_t gasPriceVal = 141006540; 210 | uint32_t gasLimitVal = 3000000; 211 | string toStr = "0xe759aab0343e7d4c9e23ac5760a12ed9d9af4421"; 212 | string valueStr = "0x00"; 213 | 214 | string func = "set(uint256)"; 215 | string p = contract.SetupContractData(&func, 123); 216 | string result = contract.SendTransaction(nonceVal, gasPriceVal, gasLimitVal, &toStr, &valueStr, &p); 217 | 218 | } 219 | 220 | void loop() { 221 | delay(5000); 222 | } 223 | 224 | 225 | -------------------------------------------------------------------------------- /src/secp256k1/include/secp256k1_ecdh.h: -------------------------------------------------------------------------------- 1 | #ifndef SECP256K1_ECDH_H 2 | #define SECP256K1_ECDH_H 3 | 4 | #include "secp256k1.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /** Compute an EC Diffie-Hellman secret in constant time 11 | * Returns: 1: exponentiation was successful 12 | * 0: scalar was invalid (zero or overflow) 13 | * Args: ctx: pointer to a context object (cannot be NULL) 14 | * Out: result: a 32-byte array which will be populated by an ECDH 15 | * secret computed from the point and scalar 16 | * In: pubkey: a pointer to a secp256k1_pubkey containing an 17 | * initialized public key 18 | * privkey: a 32-byte scalar with which to multiply the point 19 | */ 20 | SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( 21 | const secp256k1_context* ctx, 22 | unsigned char *result, 23 | const secp256k1_pubkey *pubkey, 24 | const unsigned char *privkey 25 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif /* SECP256K1_ECDH_H */ 32 | -------------------------------------------------------------------------------- /src/secp256k1/include/secp256k1_recovery.h: -------------------------------------------------------------------------------- 1 | #ifndef SECP256K1_RECOVERY_H 2 | #define SECP256K1_RECOVERY_H 3 | 4 | #include "secp256k1.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /** Opaque data structured that holds a parsed ECDSA signature, 11 | * supporting pubkey recovery. 12 | * 13 | * The exact representation of data inside is implementation defined and not 14 | * guaranteed to be portable between different platforms or versions. It is 15 | * however guaranteed to be 65 bytes in size, and can be safely copied/moved. 16 | * If you need to convert to a format suitable for storage or transmission, use 17 | * the secp256k1_ecdsa_signature_serialize_* and 18 | * secp256k1_ecdsa_signature_parse_* functions. 19 | * 20 | * Furthermore, it is guaranteed that identical signatures (including their 21 | * recoverability) will have identical representation, so they can be 22 | * memcmp'ed. 23 | */ 24 | typedef struct { 25 | unsigned char data[65]; 26 | } secp256k1_ecdsa_recoverable_signature; 27 | 28 | /** Parse a compact ECDSA signature (64 bytes + recovery id). 29 | * 30 | * Returns: 1 when the signature could be parsed, 0 otherwise 31 | * Args: ctx: a secp256k1 context object 32 | * Out: sig: a pointer to a signature object 33 | * In: input64: a pointer to a 64-byte compact signature 34 | * recid: the recovery id (0, 1, 2 or 3) 35 | */ 36 | SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact( 37 | const secp256k1_context* ctx, 38 | secp256k1_ecdsa_recoverable_signature* sig, 39 | const unsigned char *input64, 40 | int recid 41 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 42 | 43 | /** Convert a recoverable signature into a normal signature. 44 | * 45 | * Returns: 1 46 | * Out: sig: a pointer to a normal signature (cannot be NULL). 47 | * In: sigin: a pointer to a recoverable signature (cannot be NULL). 48 | */ 49 | SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert( 50 | const secp256k1_context* ctx, 51 | secp256k1_ecdsa_signature* sig, 52 | const secp256k1_ecdsa_recoverable_signature* sigin 53 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 54 | 55 | /** Serialize an ECDSA signature in compact format (64 bytes + recovery id). 56 | * 57 | * Returns: 1 58 | * Args: ctx: a secp256k1 context object 59 | * Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL) 60 | * recid: a pointer to an integer to hold the recovery id (can be NULL). 61 | * In: sig: a pointer to an initialized signature object (cannot be NULL) 62 | */ 63 | SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact( 64 | const secp256k1_context* ctx, 65 | unsigned char *output64, 66 | int *recid, 67 | const secp256k1_ecdsa_recoverable_signature* sig 68 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 69 | 70 | /** Create a recoverable ECDSA signature. 71 | * 72 | * Returns: 1: signature created 73 | * 0: the nonce generation function failed, or the private key was invalid. 74 | * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) 75 | * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) 76 | * In: msg32: the 32-byte message hash being signed (cannot be NULL) 77 | * seckey: pointer to a 32-byte secret key (cannot be NULL) 78 | * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used 79 | * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) 80 | */ 81 | SECP256K1_API int secp256k1_ecdsa_sign_recoverable( 82 | const secp256k1_context* ctx, 83 | secp256k1_ecdsa_recoverable_signature *sig, 84 | const unsigned char *msg32, 85 | const unsigned char *seckey, 86 | secp256k1_nonce_function noncefp, 87 | const void *ndata 88 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 89 | 90 | /** Recover an ECDSA public key from a signature. 91 | * 92 | * Returns: 1: public key successfully recovered (which guarantees a correct signature). 93 | * 0: otherwise. 94 | * Args: ctx: pointer to a context object, initialized for verification (cannot be NULL) 95 | * Out: pubkey: pointer to the recovered public key (cannot be NULL) 96 | * In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL) 97 | * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) 98 | */ 99 | SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover( 100 | const secp256k1_context* ctx, 101 | secp256k1_pubkey *pubkey, 102 | const secp256k1_ecdsa_recoverable_signature *sig, 103 | const unsigned char *msg32 104 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 105 | 106 | #ifdef __cplusplus 107 | } 108 | #endif 109 | 110 | #endif /* SECP256K1_RECOVERY_H */ 111 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | #define USE_BASIC_CONFIG 11 | #ifdef USE_BASIC_CONFIG 12 | 13 | #undef USE_ASM_X86_64 14 | #undef USE_ENDOMORPHISM 15 | #define USE_FIELD_10X26 16 | #undef USE_FIELD_5X52 17 | #undef USE_FIELD_INV_BUILTIN 18 | #undef USE_FIELD_INV_NUM 19 | #define USE_NUM_GMP 20 | #undef USE_NUM_NONE 21 | #undef USE_SCALAR_4X64 22 | #undef USE_SCALAR_8X32 23 | #undef USE_SCALAR_INV_BUILTIN 24 | #undef USE_SCALAR_INV_NUM 25 | 26 | #define USE_NUM_NONE 1 27 | #define USE_FIELD_INV_BUILTIN 1 28 | #define USE_SCALAR_INV_BUILTIN 1 29 | #define USE_FIELD_10X26 1 30 | #define USE_SCALAR_8X32 1 31 | 32 | 33 | 34 | 35 | #endif /* USE_BASIC_CONFIG */ 36 | 37 | #endif /* SECP256K1_BASIC_CONFIG_H */ 38 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | #include "ecmult_gen.h" 16 | 17 | static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size); 18 | static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s); 19 | 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); 20 | 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); 21 | 22 | #endif /* SECP256K1_ECDSA_H */ 23 | -------------------------------------------------------------------------------- /src/secp256k1/src/ecdsa_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013-2015 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 | 8 | #ifndef SECP256K1_ECDSA_IMPL_H 9 | #define SECP256K1_ECDSA_IMPL_H 10 | 11 | #include "scalar.h" 12 | #include "field.h" 13 | #include "group.h" 14 | #include "ecmult.h" 15 | #include "ecmult_gen.h" 16 | #include "ecdsa.h" 17 | 18 | /** Group order for secp256k1 defined as 'n' in "Standards for Efficient Cryptography" (SEC2) 2.7.1 19 | * sage: for t in xrange(1023, -1, -1): 20 | * .. p = 2**256 - 2**32 - t 21 | * .. if p.is_prime(): 22 | * .. print '%x'%p 23 | * .. break 24 | * 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f' 25 | * sage: a = 0 26 | * sage: b = 7 27 | * sage: F = FiniteField (p) 28 | * sage: '%x' % (EllipticCurve ([F (a), F (b)]).order()) 29 | * 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141' 30 | */ 31 | static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST( 32 | 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 33 | 0xBAAEDCE6UL, 0xAF48A03BUL, 0xBFD25E8CUL, 0xD0364141UL 34 | ); 35 | 36 | /** Difference between field and order, values 'p' and 'n' values defined in 37 | * "Standards for Efficient Cryptography" (SEC2) 2.7.1. 38 | * sage: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F 39 | * sage: a = 0 40 | * sage: b = 7 41 | * sage: F = FiniteField (p) 42 | * sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order()) 43 | * '14551231950b75fc4402da1722fc9baee' 44 | */ 45 | static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( 46 | 0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL 47 | ); 48 | 49 | static int secp256k1_der_read_len(const unsigned char **sigp, const unsigned char *sigend) { 50 | int lenleft, b1; 51 | size_t ret = 0; 52 | if (*sigp >= sigend) { 53 | return -1; 54 | } 55 | b1 = *((*sigp)++); 56 | if (b1 == 0xFF) { 57 | /* X.690-0207 8.1.3.5.c the value 0xFF shall not be used. */ 58 | return -1; 59 | } 60 | if ((b1 & 0x80) == 0) { 61 | /* X.690-0207 8.1.3.4 short form length octets */ 62 | return b1; 63 | } 64 | if (b1 == 0x80) { 65 | /* Indefinite length is not allowed in DER. */ 66 | return -1; 67 | } 68 | /* X.690-207 8.1.3.5 long form length octets */ 69 | lenleft = b1 & 0x7F; 70 | if (lenleft > sigend - *sigp) { 71 | return -1; 72 | } 73 | if (**sigp == 0) { 74 | /* Not the shortest possible length encoding. */ 75 | return -1; 76 | } 77 | if ((size_t)lenleft > sizeof(size_t)) { 78 | /* The resulting length would exceed the range of a size_t, so 79 | * certainly longer than the passed array size. 80 | */ 81 | return -1; 82 | } 83 | while (lenleft > 0) { 84 | ret = (ret << 8) | **sigp; 85 | if (ret + lenleft > (size_t)(sigend - *sigp)) { 86 | /* Result exceeds the length of the passed array. */ 87 | return -1; 88 | } 89 | (*sigp)++; 90 | lenleft--; 91 | } 92 | if (ret < 128) { 93 | /* Not the shortest possible length encoding. */ 94 | return -1; 95 | } 96 | return ret; 97 | } 98 | 99 | static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char **sig, const unsigned char *sigend) { 100 | int overflow = 0; 101 | unsigned char ra[32] = {0}; 102 | int rlen; 103 | 104 | if (*sig == sigend || **sig != 0x02) { 105 | /* Not a primitive integer (X.690-0207 8.3.1). */ 106 | return 0; 107 | } 108 | (*sig)++; 109 | rlen = secp256k1_der_read_len(sig, sigend); 110 | if (rlen <= 0 || (*sig) + rlen > sigend) { 111 | /* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */ 112 | return 0; 113 | } 114 | if (**sig == 0x00 && rlen > 1 && (((*sig)[1]) & 0x80) == 0x00) { 115 | /* Excessive 0x00 padding. */ 116 | return 0; 117 | } 118 | if (**sig == 0xFF && rlen > 1 && (((*sig)[1]) & 0x80) == 0x80) { 119 | /* Excessive 0xFF padding. */ 120 | return 0; 121 | } 122 | if ((**sig & 0x80) == 0x80) { 123 | /* Negative. */ 124 | overflow = 1; 125 | } 126 | while (rlen > 0 && **sig == 0) { 127 | /* Skip leading zero bytes */ 128 | rlen--; 129 | (*sig)++; 130 | } 131 | if (rlen > 32) { 132 | overflow = 1; 133 | } 134 | if (!overflow) { 135 | memcpy(ra + 32 - rlen, *sig, rlen); 136 | secp256k1_scalar_set_b32(r, ra, &overflow); 137 | } 138 | if (overflow) { 139 | secp256k1_scalar_set_int(r, 0); 140 | } 141 | (*sig) += rlen; 142 | return 1; 143 | } 144 | 145 | static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *rr, secp256k1_scalar *rs, const unsigned char *sig, size_t size) { 146 | const unsigned char *sigend = sig + size; 147 | int rlen; 148 | if (sig == sigend || *(sig++) != 0x30) { 149 | /* The encoding doesn't start with a constructed sequence (X.690-0207 8.9.1). */ 150 | return 0; 151 | } 152 | rlen = secp256k1_der_read_len(&sig, sigend); 153 | if (rlen < 0 || sig + rlen > sigend) { 154 | /* Tuple exceeds bounds */ 155 | return 0; 156 | } 157 | if (sig + rlen != sigend) { 158 | /* Garbage after tuple. */ 159 | return 0; 160 | } 161 | 162 | if (!secp256k1_der_parse_integer(rr, &sig, sigend)) { 163 | return 0; 164 | } 165 | if (!secp256k1_der_parse_integer(rs, &sig, sigend)) { 166 | return 0; 167 | } 168 | 169 | if (sig != sigend) { 170 | /* Trailing garbage inside tuple. */ 171 | return 0; 172 | } 173 | 174 | return 1; 175 | } 176 | 177 | static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar* ar, const secp256k1_scalar* as) { 178 | unsigned char r[33] = {0}, s[33] = {0}; 179 | unsigned char *rp = r, *sp = s; 180 | size_t lenR = 33, lenS = 33; 181 | secp256k1_scalar_get_b32(&r[1], ar); 182 | secp256k1_scalar_get_b32(&s[1], as); 183 | while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; } 184 | while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; } 185 | if (*size < 6+lenS+lenR) { 186 | *size = 6 + lenS + lenR; 187 | return 0; 188 | } 189 | *size = 6 + lenS + lenR; 190 | sig[0] = 0x30; 191 | sig[1] = 4 + lenS + lenR; 192 | sig[2] = 0x02; 193 | sig[3] = lenR; 194 | memcpy(sig+4, rp, lenR); 195 | sig[4+lenR] = 0x02; 196 | sig[5+lenR] = lenS; 197 | memcpy(sig+lenR+6, sp, lenS); 198 | return 1; 199 | } 200 | 201 | static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) { 202 | unsigned char c[32]; 203 | secp256k1_scalar sn, u1, u2; 204 | #if !defined(EXHAUSTIVE_TEST_ORDER) 205 | secp256k1_fe xr; 206 | #endif 207 | secp256k1_gej pubkeyj; 208 | secp256k1_gej pr; 209 | 210 | if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { 211 | return 0; 212 | } 213 | 214 | secp256k1_scalar_inverse_var(&sn, sigs); 215 | secp256k1_scalar_mul(&u1, &sn, message); 216 | secp256k1_scalar_mul(&u2, &sn, sigr); 217 | secp256k1_gej_set_ge(&pubkeyj, pubkey); 218 | secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1); 219 | if (secp256k1_gej_is_infinity(&pr)) { 220 | return 0; 221 | } 222 | 223 | #if defined(EXHAUSTIVE_TEST_ORDER) 224 | { 225 | secp256k1_scalar computed_r; 226 | secp256k1_ge pr_ge; 227 | secp256k1_ge_set_gej(&pr_ge, &pr); 228 | secp256k1_fe_normalize(&pr_ge.x); 229 | 230 | secp256k1_fe_get_b32(c, &pr_ge.x); 231 | secp256k1_scalar_set_b32(&computed_r, c, NULL); 232 | return secp256k1_scalar_eq(sigr, &computed_r); 233 | } 234 | #else 235 | secp256k1_scalar_get_b32(c, sigr); 236 | secp256k1_fe_set_b32(&xr, c); 237 | 238 | /** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n) 239 | * in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p), 240 | * compute the remainder modulo n, and compare it to xr. However: 241 | * 242 | * xr == X(pr) mod n 243 | * <=> exists h. (xr + h * n < p && xr + h * n == X(pr)) 244 | * [Since 2 * n > p, h can only be 0 or 1] 245 | * <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr)) 246 | * [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p] 247 | * <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p) 248 | * [Multiplying both sides of the equations by pr.z^2 mod p] 249 | * <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x) 250 | * 251 | * Thus, we can avoid the inversion, but we have to check both cases separately. 252 | * secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test. 253 | */ 254 | if (secp256k1_gej_eq_x_var(&xr, &pr)) { 255 | /* xr * pr.z^2 mod p == pr.x, so the signature is valid. */ 256 | return 1; 257 | } 258 | if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_const_p_minus_order) >= 0) { 259 | /* xr + n >= p, so we can skip testing the second case. */ 260 | return 0; 261 | } 262 | secp256k1_fe_add(&xr, &secp256k1_ecdsa_const_order_as_fe); 263 | if (secp256k1_gej_eq_x_var(&xr, &pr)) { 264 | /* (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid. */ 265 | return 1; 266 | } 267 | return 0; 268 | #endif 269 | } 270 | 271 | static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid) { 272 | unsigned char b[32]; 273 | secp256k1_gej rp; 274 | secp256k1_ge r; 275 | secp256k1_scalar n; 276 | int overflow = 0; 277 | 278 | secp256k1_ecmult_gen(ctx, &rp, nonce); 279 | secp256k1_ge_set_gej(&r, &rp); 280 | secp256k1_fe_normalize(&r.x); 281 | secp256k1_fe_normalize(&r.y); 282 | secp256k1_fe_get_b32(b, &r.x); 283 | secp256k1_scalar_set_b32(sigr, b, &overflow); 284 | /* These two conditions should be checked before calling */ 285 | VERIFY_CHECK(!secp256k1_scalar_is_zero(sigr)); 286 | VERIFY_CHECK(overflow == 0); 287 | 288 | if (recid) { 289 | /* The overflow condition is cryptographically unreachable as hitting it requires finding the discrete log 290 | * of some P where P.x >= order, and only 1 in about 2^127 points meet this criteria. 291 | */ 292 | *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0); 293 | } 294 | secp256k1_scalar_mul(&n, sigr, seckey); 295 | secp256k1_scalar_add(&n, &n, message); 296 | secp256k1_scalar_inverse(sigs, nonce); 297 | secp256k1_scalar_mul(sigs, sigs, &n); 298 | secp256k1_scalar_clear(&n); 299 | secp256k1_gej_clear(&rp); 300 | secp256k1_ge_clear(&r); 301 | if (secp256k1_scalar_is_zero(sigs)) { 302 | return 0; 303 | } 304 | if (secp256k1_scalar_is_high(sigs)) { 305 | secp256k1_scalar_negate(sigs, sigs); 306 | if (recid) { 307 | *recid ^= 1; 308 | } 309 | } 310 | return 1; 311 | } 312 | 313 | #endif /* SECP256K1_ECDSA_IMPL_H */ 314 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | -------------------------------------------------------------------------------- /src/secp256k1/src/ecmult.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_H 8 | #define SECP256K1_ECMULT_H 9 | 10 | #include "num.h" 11 | #include "group.h" 12 | 13 | typedef struct { 14 | /* For accelerating the computation of a*P + b*G: */ 15 | secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */ 16 | #ifdef USE_ENDOMORPHISM 17 | secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */ 18 | #endif 19 | } secp256k1_ecmult_context; 20 | 21 | static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx); 22 | static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb); 23 | static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, 24 | const secp256k1_ecmult_context *src, const secp256k1_callback *cb); 25 | static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx); 26 | static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx); 27 | 28 | /** Double multiply: R = na*A + ng*G */ 29 | static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng); 30 | 31 | #endif /* SECP256K1_ECMULT_H */ 32 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q); 14 | 15 | #endif /* SECP256K1_ECMULT_CONST_H */ 16 | -------------------------------------------------------------------------------- /src/secp256k1/src/ecmult_const_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 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_CONST_IMPL_H 8 | #define SECP256K1_ECMULT_CONST_IMPL_H 9 | 10 | #include "scalar.h" 11 | #include "group.h" 12 | #include "ecmult_const.h" 13 | #include "ecmult_impl.h" 14 | 15 | #ifdef USE_ENDOMORPHISM 16 | #define WNAF_BITS 128 17 | #else 18 | #define WNAF_BITS 256 19 | #endif 20 | #define WNAF_SIZE(w) ((WNAF_BITS + (w) - 1) / (w)) 21 | 22 | /* This is like `ECMULT_TABLE_GET_GE` but is constant time */ 23 | #define ECMULT_CONST_TABLE_GET_GE(r,pre,n,w) do { \ 24 | int m; \ 25 | int abs_n = (n) * (((n) > 0) * 2 - 1); \ 26 | int idx_n = abs_n / 2; \ 27 | secp256k1_fe neg_y; \ 28 | VERIFY_CHECK(((n) & 1) == 1); \ 29 | VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ 30 | VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ 31 | VERIFY_SETUP(secp256k1_fe_clear(&(r)->x)); \ 32 | VERIFY_SETUP(secp256k1_fe_clear(&(r)->y)); \ 33 | for (m = 0; m < ECMULT_TABLE_SIZE(w); m++) { \ 34 | /* This loop is used to avoid secret data in array indices. See 35 | * the comment in ecmult_gen_impl.h for rationale. */ \ 36 | secp256k1_fe_cmov(&(r)->x, &(pre)[m].x, m == idx_n); \ 37 | secp256k1_fe_cmov(&(r)->y, &(pre)[m].y, m == idx_n); \ 38 | } \ 39 | (r)->infinity = 0; \ 40 | secp256k1_fe_negate(&neg_y, &(r)->y, 1); \ 41 | secp256k1_fe_cmov(&(r)->y, &neg_y, (n) != abs_n); \ 42 | } while(0) 43 | 44 | 45 | /** Convert a number to WNAF notation. 46 | * The number becomes represented by sum(2^{wi} * wnaf[i], i=0..WNAF_SIZE(w)+1) - return_val. 47 | * It has the following guarantees: 48 | * - each wnaf[i] an odd integer between -(1 << w) and (1 << w) 49 | * - each wnaf[i] is nonzero 50 | * - the number of words set is always WNAF_SIZE(w) + 1 51 | * 52 | * Adapted from `The Width-w NAF Method Provides Small Memory and Fast Elliptic Scalar 53 | * Multiplications Secure against Side Channel Attacks`, Okeya and Tagaki. M. Joye (Ed.) 54 | * CT-RSA 2003, LNCS 2612, pp. 328-443, 2003. Springer-Verlagy Berlin Heidelberg 2003 55 | * 56 | * Numbers reference steps of `Algorithm SPA-resistant Width-w NAF with Odd Scalar` on pp. 335 57 | */ 58 | static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) { 59 | int global_sign; 60 | int skew = 0; 61 | int word = 0; 62 | 63 | /* 1 2 3 */ 64 | int u_last; 65 | int u; 66 | 67 | int flip; 68 | int bit; 69 | secp256k1_scalar neg_s; 70 | int not_neg_one; 71 | /* Note that we cannot handle even numbers by negating them to be odd, as is 72 | * done in other implementations, since if our scalars were specified to have 73 | * width < 256 for performance reasons, their negations would have width 256 74 | * and we'd lose any performance benefit. Instead, we use a technique from 75 | * Section 4.2 of the Okeya/Tagaki paper, which is to add either 1 (for even) 76 | * or 2 (for odd) to the number we are encoding, returning a skew value indicating 77 | * this, and having the caller compensate after doing the multiplication. */ 78 | 79 | /* Negative numbers will be negated to keep their bit representation below the maximum width */ 80 | flip = secp256k1_scalar_is_high(&s); 81 | /* We add 1 to even numbers, 2 to odd ones, noting that negation flips parity */ 82 | bit = flip ^ !secp256k1_scalar_is_even(&s); 83 | /* We check for negative one, since adding 2 to it will cause an overflow */ 84 | secp256k1_scalar_negate(&neg_s, &s); 85 | not_neg_one = !secp256k1_scalar_is_one(&neg_s); 86 | secp256k1_scalar_cadd_bit(&s, bit, not_neg_one); 87 | /* If we had negative one, flip == 1, s.d[0] == 0, bit == 1, so caller expects 88 | * that we added two to it and flipped it. In fact for -1 these operations are 89 | * identical. We only flipped, but since skewing is required (in the sense that 90 | * the skew must be 1 or 2, never zero) and flipping is not, we need to change 91 | * our flags to claim that we only skewed. */ 92 | global_sign = secp256k1_scalar_cond_negate(&s, flip); 93 | global_sign *= not_neg_one * 2 - 1; 94 | skew = 1 << bit; 95 | 96 | /* 4 */ 97 | u_last = secp256k1_scalar_shr_int(&s, w); 98 | while (word * w < WNAF_BITS) { 99 | int sign; 100 | int even; 101 | 102 | /* 4.1 4.4 */ 103 | u = secp256k1_scalar_shr_int(&s, w); 104 | /* 4.2 */ 105 | even = ((u & 1) == 0); 106 | sign = 2 * (u_last > 0) - 1; 107 | u += sign * even; 108 | u_last -= sign * even * (1 << w); 109 | 110 | /* 4.3, adapted for global sign change */ 111 | wnaf[word++] = u_last * global_sign; 112 | 113 | u_last = u; 114 | } 115 | wnaf[word] = u * global_sign; 116 | 117 | VERIFY_CHECK(secp256k1_scalar_is_zero(&s)); 118 | VERIFY_CHECK(word == WNAF_SIZE(w)); 119 | return skew; 120 | } 121 | 122 | 123 | static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *scalar) { 124 | secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; 125 | secp256k1_ge tmpa; 126 | secp256k1_fe Z; 127 | 128 | int skew_1; 129 | int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)]; 130 | #ifdef USE_ENDOMORPHISM 131 | secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; 132 | int wnaf_lam[1 + WNAF_SIZE(WINDOW_A - 1)]; 133 | int skew_lam; 134 | secp256k1_scalar q_1, q_lam; 135 | #endif 136 | 137 | int i; 138 | secp256k1_scalar sc = *scalar; 139 | 140 | /* build wnaf representation for q. */ 141 | #ifdef USE_ENDOMORPHISM 142 | /* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */ 143 | secp256k1_scalar_split_lambda(&q_1, &q_lam, &sc); 144 | skew_1 = secp256k1_wnaf_const(wnaf_1, q_1, WINDOW_A - 1); 145 | skew_lam = secp256k1_wnaf_const(wnaf_lam, q_lam, WINDOW_A - 1); 146 | #else 147 | skew_1 = secp256k1_wnaf_const(wnaf_1, sc, WINDOW_A - 1); 148 | #endif 149 | 150 | /* Calculate odd multiples of a. 151 | * All multiples are brought to the same Z 'denominator', which is stored 152 | * in Z. Due to secp256k1' isomorphism we can do all operations pretending 153 | * that the Z coordinate was 1, use affine addition formulae, and correct 154 | * the Z coordinate of the result once at the end. 155 | */ 156 | secp256k1_gej_set_ge(r, a); 157 | secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, &Z, r); 158 | for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { 159 | secp256k1_fe_normalize_weak(&pre_a[i].y); 160 | } 161 | #ifdef USE_ENDOMORPHISM 162 | for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { 163 | secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]); 164 | } 165 | #endif 166 | 167 | /* first loop iteration (separated out so we can directly set r, rather 168 | * than having it start at infinity, get doubled several times, then have 169 | * its new value added to it) */ 170 | i = wnaf_1[WNAF_SIZE(WINDOW_A - 1)]; 171 | VERIFY_CHECK(i != 0); 172 | ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); 173 | secp256k1_gej_set_ge(r, &tmpa); 174 | #ifdef USE_ENDOMORPHISM 175 | i = wnaf_lam[WNAF_SIZE(WINDOW_A - 1)]; 176 | VERIFY_CHECK(i != 0); 177 | ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, i, WINDOW_A); 178 | secp256k1_gej_add_ge(r, r, &tmpa); 179 | #endif 180 | /* remaining loop iterations */ 181 | for (i = WNAF_SIZE(WINDOW_A - 1) - 1; i >= 0; i--) { 182 | int n; 183 | int j; 184 | for (j = 0; j < WINDOW_A - 1; ++j) { 185 | secp256k1_gej_double_nonzero(r, r, NULL); 186 | } 187 | 188 | n = wnaf_1[i]; 189 | ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); 190 | VERIFY_CHECK(n != 0); 191 | secp256k1_gej_add_ge(r, r, &tmpa); 192 | #ifdef USE_ENDOMORPHISM 193 | n = wnaf_lam[i]; 194 | ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); 195 | VERIFY_CHECK(n != 0); 196 | secp256k1_gej_add_ge(r, r, &tmpa); 197 | #endif 198 | } 199 | 200 | secp256k1_fe_mul(&r->z, &r->z, &Z); 201 | 202 | { 203 | /* Correct for wNAF skew */ 204 | secp256k1_ge correction = *a; 205 | secp256k1_ge_storage correction_1_stor; 206 | #ifdef USE_ENDOMORPHISM 207 | secp256k1_ge_storage correction_lam_stor; 208 | #endif 209 | secp256k1_ge_storage a2_stor; 210 | secp256k1_gej tmpj; 211 | secp256k1_gej_set_ge(&tmpj, &correction); 212 | secp256k1_gej_double_var(&tmpj, &tmpj, NULL); 213 | secp256k1_ge_set_gej(&correction, &tmpj); 214 | secp256k1_ge_to_storage(&correction_1_stor, a); 215 | #ifdef USE_ENDOMORPHISM 216 | secp256k1_ge_to_storage(&correction_lam_stor, a); 217 | #endif 218 | secp256k1_ge_to_storage(&a2_stor, &correction); 219 | 220 | /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */ 221 | secp256k1_ge_storage_cmov(&correction_1_stor, &a2_stor, skew_1 == 2); 222 | #ifdef USE_ENDOMORPHISM 223 | secp256k1_ge_storage_cmov(&correction_lam_stor, &a2_stor, skew_lam == 2); 224 | #endif 225 | 226 | /* Apply the correction */ 227 | secp256k1_ge_from_storage(&correction, &correction_1_stor); 228 | secp256k1_ge_neg(&correction, &correction); 229 | secp256k1_gej_add_ge(r, r, &correction); 230 | 231 | #ifdef USE_ENDOMORPHISM 232 | secp256k1_ge_from_storage(&correction, &correction_lam_stor); 233 | secp256k1_ge_neg(&correction, &correction); 234 | secp256k1_ge_mul_lambda(&correction, &correction); 235 | secp256k1_gej_add_ge(r, r, &correction); 236 | #endif 237 | } 238 | } 239 | 240 | #endif /* SECP256K1_ECMULT_CONST_IMPL_H */ 241 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | -------------------------------------------------------------------------------- /src/secp256k1/src/ecmult_gen_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * 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_IMPL_H 8 | #define SECP256K1_ECMULT_GEN_IMPL_H 9 | 10 | #include "scalar.h" 11 | #include "group.h" 12 | #include "ecmult_gen.h" 13 | #include "hash_impl.h" 14 | #define USE_ECMULT_STATIC_PRECOMPUTATION 15 | #ifdef USE_ECMULT_STATIC_PRECOMPUTATION 16 | #include "ecmult_static_context.h" 17 | #endif 18 | static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context *ctx) { 19 | ctx->prec = NULL; 20 | } 21 | 22 | static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx, const secp256k1_callback* cb) { 23 | #ifndef USE_ECMULT_STATIC_PRECOMPUTATION 24 | secp256k1_ge prec[1024]; 25 | secp256k1_gej gj; 26 | secp256k1_gej nums_gej; 27 | int i, j; 28 | #endif 29 | 30 | if (ctx->prec != NULL) { 31 | return; 32 | } 33 | #ifndef USE_ECMULT_STATIC_PRECOMPUTATION 34 | ctx->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*ctx->prec)); 35 | 36 | /* get the generator */ 37 | secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); 38 | 39 | /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ 40 | { 41 | static const unsigned char nums_b32[33] = "The scalar for this x is unknown"; 42 | secp256k1_fe nums_x; 43 | secp256k1_ge nums_ge; 44 | int r; 45 | r = secp256k1_fe_set_b32(&nums_x, nums_b32); 46 | (void)r; 47 | VERIFY_CHECK(r); 48 | r = secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0); 49 | (void)r; 50 | VERIFY_CHECK(r); 51 | secp256k1_gej_set_ge(&nums_gej, &nums_ge); 52 | /* Add G to make the bits in x uniformly distributed. */ 53 | secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g, NULL); 54 | } 55 | 56 | /* compute prec. */ 57 | { 58 | secp256k1_gej precj[1024]; /* Jacobian versions of prec. */ 59 | secp256k1_gej gbase; 60 | secp256k1_gej numsbase; 61 | gbase = gj; /* 16^j * G */ 62 | numsbase = nums_gej; /* 2^j * nums. */ 63 | for (j = 0; j < 64; j++) { 64 | /* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */ 65 | precj[j*16] = numsbase; 66 | for (i = 1; i < 16; i++) { 67 | secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase, NULL); 68 | } 69 | /* Multiply gbase by 16. */ 70 | for (i = 0; i < 4; i++) { 71 | secp256k1_gej_double_var(&gbase, &gbase, NULL); 72 | } 73 | /* Multiply numbase by 2. */ 74 | secp256k1_gej_double_var(&numsbase, &numsbase, NULL); 75 | if (j == 62) { 76 | /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ 77 | secp256k1_gej_neg(&numsbase, &numsbase); 78 | secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL); 79 | } 80 | } 81 | secp256k1_ge_set_all_gej_var(prec, precj, 1024, cb); 82 | } 83 | for (j = 0; j < 64; j++) { 84 | for (i = 0; i < 16; i++) { 85 | secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]); 86 | } 87 | } 88 | #else 89 | (void)cb; 90 | ctx->prec = (secp256k1_ge_storage (*)[64][16])secp256k1_ecmult_static_context; 91 | #endif 92 | secp256k1_ecmult_gen_blind(ctx, NULL); 93 | } 94 | 95 | static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx) { 96 | return ctx->prec != NULL; 97 | } 98 | 99 | static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, 100 | const secp256k1_ecmult_gen_context *src, const secp256k1_callback* cb) { 101 | if (src->prec == NULL) { 102 | dst->prec = NULL; 103 | } else { 104 | #ifndef USE_ECMULT_STATIC_PRECOMPUTATION 105 | dst->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*dst->prec)); 106 | memcpy(dst->prec, src->prec, sizeof(*dst->prec)); 107 | #else 108 | (void)cb; 109 | dst->prec = src->prec; 110 | #endif 111 | dst->initial = src->initial; 112 | dst->blind = src->blind; 113 | } 114 | } 115 | 116 | static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) { 117 | #ifndef USE_ECMULT_STATIC_PRECOMPUTATION 118 | free(ctx->prec); 119 | #endif 120 | secp256k1_scalar_clear(&ctx->blind); 121 | secp256k1_gej_clear(&ctx->initial); 122 | ctx->prec = NULL; 123 | } 124 | 125 | static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) { 126 | secp256k1_ge add; 127 | secp256k1_ge_storage adds; 128 | secp256k1_scalar gnb; 129 | int bits; 130 | int i, j; 131 | memset(&adds, 0, sizeof(adds)); 132 | *r = ctx->initial; 133 | /* Blind scalar/point multiplication by computing (n-b)G + bG instead of nG. */ 134 | secp256k1_scalar_add(&gnb, gn, &ctx->blind); 135 | add.infinity = 0; 136 | for (j = 0; j < 64; j++) { 137 | bits = secp256k1_scalar_get_bits(&gnb, j * 4, 4); 138 | for (i = 0; i < 16; i++) { 139 | /** This uses a conditional move to avoid any secret data in array indexes. 140 | * _Any_ use of secret indexes has been demonstrated to result in timing 141 | * sidechannels, even when the cache-line access patterns are uniform. 142 | * See also: 143 | * "A word of warning", CHES 2013 Rump Session, by Daniel J. Bernstein and Peter Schwabe 144 | * (https://cryptojedi.org/peter/data/chesrump-20130822.pdf) and 145 | * "Cache Attacks and Countermeasures: the Case of AES", RSA 2006, 146 | * by Dag Arne Osvik, Adi Shamir, and Eran Tromer 147 | * (http://www.tau.ac.il/~tromer/papers/cache.pdf) 148 | */ 149 | secp256k1_ge_storage_cmov(&adds, &(*ctx->prec)[j][i], i == bits); 150 | } 151 | secp256k1_ge_from_storage(&add, &adds); 152 | secp256k1_gej_add_ge(r, r, &add); 153 | } 154 | bits = 0; 155 | secp256k1_ge_clear(&add); 156 | secp256k1_scalar_clear(&gnb); 157 | } 158 | 159 | /* Setup blinding values for secp256k1_ecmult_gen. */ 160 | static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32) { 161 | secp256k1_scalar b; 162 | secp256k1_gej gb; 163 | secp256k1_fe s; 164 | unsigned char nonce32[32]; 165 | secp256k1_rfc6979_hmac_sha256_t rng; 166 | int retry; 167 | unsigned char keydata[64] = {0}; 168 | if (seed32 == NULL) { 169 | /* When seed is NULL, reset the initial point and blinding value. */ 170 | secp256k1_gej_set_ge(&ctx->initial, &secp256k1_ge_const_g); 171 | secp256k1_gej_neg(&ctx->initial, &ctx->initial); 172 | secp256k1_scalar_set_int(&ctx->blind, 1); 173 | } 174 | /* The prior blinding value (if not reset) is chained forward by including it in the hash. */ 175 | secp256k1_scalar_get_b32(nonce32, &ctx->blind); 176 | /** Using a CSPRNG allows a failure free interface, avoids needing large amounts of random data, 177 | * and guards against weak or adversarial seeds. This is a simpler and safer interface than 178 | * asking the caller for blinding values directly and expecting them to retry on failure. 179 | */ 180 | memcpy(keydata, nonce32, 32); 181 | if (seed32 != NULL) { 182 | memcpy(keydata + 32, seed32, 32); 183 | } 184 | secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, seed32 ? 64 : 32); 185 | memset(keydata, 0, sizeof(keydata)); 186 | /* Retry for out of range results to achieve uniformity. */ 187 | do { 188 | secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); 189 | retry = !secp256k1_fe_set_b32(&s, nonce32); 190 | retry |= secp256k1_fe_is_zero(&s); 191 | } while (retry); /* This branch true is cryptographically unreachable. Requires sha256_hmac output > Fp. */ 192 | /* Randomize the projection to defend against multiplier sidechannels. */ 193 | secp256k1_gej_rescale(&ctx->initial, &s); 194 | secp256k1_fe_clear(&s); 195 | do { 196 | secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); 197 | secp256k1_scalar_set_b32(&b, nonce32, &retry); 198 | /* A blinding value of 0 works, but would undermine the projection hardening. */ 199 | retry |= secp256k1_scalar_is_zero(&b); 200 | } while (retry); /* This branch true is cryptographically unreachable. Requires sha256_hmac output > order. */ 201 | secp256k1_rfc6979_hmac_sha256_finalize(&rng); 202 | memset(nonce32, 0, 32); 203 | secp256k1_ecmult_gen(ctx, &gb, &b); 204 | secp256k1_scalar_negate(&b, &b); 205 | ctx->blind = b; 206 | ctx->initial = gb; 207 | secp256k1_scalar_clear(&b); 208 | secp256k1_gej_clear(&gb); 209 | } 210 | 211 | #endif /* SECP256K1_ECMULT_GEN_IMPL_H */ 212 | -------------------------------------------------------------------------------- /src/secp256k1/src/field.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_H 8 | #define SECP256K1_FIELD_H 9 | 10 | /** Field element module. 11 | * 12 | * Field elements can be represented in several ways, but code accessing 13 | * it (and implementations) need to take certain properties into account: 14 | * - Each field element can be normalized or not. 15 | * - Each field element has a magnitude, which represents how far away 16 | * its representation is away from normalization. Normalized elements 17 | * always have a magnitude of 1, but a magnitude of 1 doesn't imply 18 | * normality. 19 | */ 20 | 21 | #if defined HAVE_CONFIG_H 22 | #include "libsecp256k1-config.h" 23 | #endif 24 | 25 | #define USE_FIELD_10X26 26 | #if defined(USE_FIELD_10X26) 27 | #include "field_10x26.h" 28 | #elif defined(USE_FIELD_5X52) 29 | #include "field_5x52.h" 30 | #else 31 | #error "Please select field implementation" 32 | #endif 33 | 34 | #include "util.h" 35 | 36 | /** Normalize a field element. */ 37 | static void secp256k1_fe_normalize(secp256k1_fe *r); 38 | 39 | /** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */ 40 | static void secp256k1_fe_normalize_weak(secp256k1_fe *r); 41 | 42 | /** Normalize a field element, without constant-time guarantee. */ 43 | static void secp256k1_fe_normalize_var(secp256k1_fe *r); 44 | 45 | /** Verify whether a field element represents zero i.e. would normalize to a zero value. The field 46 | * implementation may optionally normalize the input, but this should not be relied upon. */ 47 | static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r); 48 | 49 | /** Verify whether a field element represents zero i.e. would normalize to a zero value. The field 50 | * implementation may optionally normalize the input, but this should not be relied upon. */ 51 | static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r); 52 | 53 | /** Set a field element equal to a small integer. Resulting field element is normalized. */ 54 | static void secp256k1_fe_set_int(secp256k1_fe *r, int a); 55 | 56 | /** Sets a field element equal to zero, initializing all fields. */ 57 | static void secp256k1_fe_clear(secp256k1_fe *a); 58 | 59 | /** Verify whether a field element is zero. Requires the input to be normalized. */ 60 | static int secp256k1_fe_is_zero(const secp256k1_fe *a); 61 | 62 | /** Check the "oddness" of a field element. Requires the input to be normalized. */ 63 | static int secp256k1_fe_is_odd(const secp256k1_fe *a); 64 | 65 | /** Compare two field elements. Requires magnitude-1 inputs. */ 66 | static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b); 67 | 68 | /** Same as secp256k1_fe_equal, but may be variable time. */ 69 | static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b); 70 | 71 | /** Compare two field elements. Requires both inputs to be normalized */ 72 | static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b); 73 | 74 | /** Set a field element equal to 32-byte big endian value. If successful, the resulting field element is normalized. */ 75 | static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a); 76 | 77 | /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ 78 | static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a); 79 | 80 | /** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input 81 | * as an argument. The magnitude of the output is one higher. */ 82 | static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m); 83 | 84 | /** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that 85 | * small integer. */ 86 | static void secp256k1_fe_mul_int(secp256k1_fe *r, int a); 87 | 88 | /** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */ 89 | static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a); 90 | 91 | /** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8. 92 | * The output magnitude is 1 (but not guaranteed to be normalized). */ 93 | static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b); 94 | 95 | /** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8. 96 | * The output magnitude is 1 (but not guaranteed to be normalized). */ 97 | static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a); 98 | 99 | /** If a has a square root, it is computed in r and 1 is returned. If a does not 100 | * have a square root, the root of its negation is computed and 0 is returned. 101 | * The input's magnitude can be at most 8. The output magnitude is 1 (but not 102 | * guaranteed to be normalized). The result in r will always be a square 103 | * itself. */ 104 | static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a); 105 | 106 | /** Checks whether a field element is a quadratic residue. */ 107 | static int secp256k1_fe_is_quad_var(const secp256k1_fe *a); 108 | 109 | /** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be 110 | * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ 111 | static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a); 112 | 113 | /** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */ 114 | static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a); 115 | 116 | /** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be 117 | * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and 118 | * outputs must not overlap in memory. */ 119 | static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len); 120 | 121 | /** Convert a field element to the storage type. */ 122 | static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a); 123 | 124 | /** Convert a field element back from the storage type. */ 125 | static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a); 126 | 127 | /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ 128 | static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag); 129 | 130 | /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ 131 | static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); 132 | 133 | #endif /* SECP256K1_FIELD_H */ 134 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | -------------------------------------------------------------------------------- /src/secp256k1/src/field_5x52_int128_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_FIELD_INNER5X52_IMPL_H 8 | #define SECP256K1_FIELD_INNER5X52_IMPL_H 9 | 10 | #include 11 | 12 | #ifdef VERIFY 13 | #define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) 14 | #else 15 | #define VERIFY_BITS(x, n) do { } while(0) 16 | #endif 17 | 18 | SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { 19 | uint128_t c, d; 20 | uint64_t t3, t4, tx, u0; 21 | uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; 22 | const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; 23 | 24 | VERIFY_BITS(a[0], 56); 25 | VERIFY_BITS(a[1], 56); 26 | VERIFY_BITS(a[2], 56); 27 | VERIFY_BITS(a[3], 56); 28 | VERIFY_BITS(a[4], 52); 29 | VERIFY_BITS(b[0], 56); 30 | VERIFY_BITS(b[1], 56); 31 | VERIFY_BITS(b[2], 56); 32 | VERIFY_BITS(b[3], 56); 33 | VERIFY_BITS(b[4], 52); 34 | VERIFY_CHECK(r != b); 35 | 36 | /* [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n. 37 | * px is a shorthand for sum(a[i]*b[x-i], i=0..x). 38 | * Note that [x 0 0 0 0 0] = [x*R]. 39 | */ 40 | 41 | d = (uint128_t)a0 * b[3] 42 | + (uint128_t)a1 * b[2] 43 | + (uint128_t)a2 * b[1] 44 | + (uint128_t)a3 * b[0]; 45 | VERIFY_BITS(d, 114); 46 | /* [d 0 0 0] = [p3 0 0 0] */ 47 | c = (uint128_t)a4 * b[4]; 48 | VERIFY_BITS(c, 112); 49 | /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ 50 | d += (c & M) * R; c >>= 52; 51 | VERIFY_BITS(d, 115); 52 | VERIFY_BITS(c, 60); 53 | /* [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ 54 | t3 = d & M; d >>= 52; 55 | VERIFY_BITS(t3, 52); 56 | VERIFY_BITS(d, 63); 57 | /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ 58 | 59 | d += (uint128_t)a0 * b[4] 60 | + (uint128_t)a1 * b[3] 61 | + (uint128_t)a2 * b[2] 62 | + (uint128_t)a3 * b[1] 63 | + (uint128_t)a4 * b[0]; 64 | VERIFY_BITS(d, 115); 65 | /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ 66 | d += c * R; 67 | VERIFY_BITS(d, 116); 68 | /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ 69 | t4 = d & M; d >>= 52; 70 | VERIFY_BITS(t4, 52); 71 | VERIFY_BITS(d, 64); 72 | /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ 73 | tx = (t4 >> 48); t4 &= (M >> 4); 74 | VERIFY_BITS(tx, 4); 75 | VERIFY_BITS(t4, 48); 76 | /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ 77 | 78 | c = (uint128_t)a0 * b[0]; 79 | VERIFY_BITS(c, 112); 80 | /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */ 81 | d += (uint128_t)a1 * b[4] 82 | + (uint128_t)a2 * b[3] 83 | + (uint128_t)a3 * b[2] 84 | + (uint128_t)a4 * b[1]; 85 | VERIFY_BITS(d, 115); 86 | /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ 87 | u0 = d & M; d >>= 52; 88 | VERIFY_BITS(u0, 52); 89 | VERIFY_BITS(d, 63); 90 | /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ 91 | /* [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ 92 | u0 = (u0 << 4) | tx; 93 | VERIFY_BITS(u0, 56); 94 | /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ 95 | c += (uint128_t)u0 * (R >> 4); 96 | VERIFY_BITS(c, 115); 97 | /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ 98 | r[0] = c & M; c >>= 52; 99 | VERIFY_BITS(r[0], 52); 100 | VERIFY_BITS(c, 61); 101 | /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */ 102 | 103 | c += (uint128_t)a0 * b[1] 104 | + (uint128_t)a1 * b[0]; 105 | VERIFY_BITS(c, 114); 106 | /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */ 107 | d += (uint128_t)a2 * b[4] 108 | + (uint128_t)a3 * b[3] 109 | + (uint128_t)a4 * b[2]; 110 | VERIFY_BITS(d, 114); 111 | /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ 112 | c += (d & M) * R; d >>= 52; 113 | VERIFY_BITS(c, 115); 114 | VERIFY_BITS(d, 62); 115 | /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ 116 | r[1] = c & M; c >>= 52; 117 | VERIFY_BITS(r[1], 52); 118 | VERIFY_BITS(c, 63); 119 | /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ 120 | 121 | c += (uint128_t)a0 * b[2] 122 | + (uint128_t)a1 * b[1] 123 | + (uint128_t)a2 * b[0]; 124 | VERIFY_BITS(c, 114); 125 | /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */ 126 | d += (uint128_t)a3 * b[4] 127 | + (uint128_t)a4 * b[3]; 128 | VERIFY_BITS(d, 114); 129 | /* [d 0 0 t4 t3 c t1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 130 | c += (d & M) * R; d >>= 52; 131 | VERIFY_BITS(c, 115); 132 | VERIFY_BITS(d, 62); 133 | /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 134 | 135 | /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 136 | r[2] = c & M; c >>= 52; 137 | VERIFY_BITS(r[2], 52); 138 | VERIFY_BITS(c, 63); 139 | /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 140 | c += d * R + t3; 141 | VERIFY_BITS(c, 100); 142 | /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 143 | r[3] = c & M; c >>= 52; 144 | VERIFY_BITS(r[3], 52); 145 | VERIFY_BITS(c, 48); 146 | /* [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 147 | c += t4; 148 | VERIFY_BITS(c, 49); 149 | /* [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 150 | r[4] = c; 151 | VERIFY_BITS(r[4], 49); 152 | /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 153 | } 154 | 155 | SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) { 156 | uint128_t c, d; 157 | uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; 158 | int64_t t3, t4, tx, u0; 159 | const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; 160 | 161 | VERIFY_BITS(a[0], 56); 162 | VERIFY_BITS(a[1], 56); 163 | VERIFY_BITS(a[2], 56); 164 | VERIFY_BITS(a[3], 56); 165 | VERIFY_BITS(a[4], 52); 166 | 167 | /** [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n. 168 | * px is a shorthand for sum(a[i]*a[x-i], i=0..x). 169 | * Note that [x 0 0 0 0 0] = [x*R]. 170 | */ 171 | 172 | d = (uint128_t)(a0*2) * a3 173 | + (uint128_t)(a1*2) * a2; 174 | VERIFY_BITS(d, 114); 175 | /* [d 0 0 0] = [p3 0 0 0] */ 176 | c = (uint128_t)a4 * a4; 177 | VERIFY_BITS(c, 112); 178 | /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ 179 | d += (c & M) * R; c >>= 52; 180 | VERIFY_BITS(d, 115); 181 | VERIFY_BITS(c, 60); 182 | /* [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ 183 | t3 = d & M; d >>= 52; 184 | VERIFY_BITS(t3, 52); 185 | VERIFY_BITS(d, 63); 186 | /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ 187 | 188 | a4 *= 2; 189 | d += (uint128_t)a0 * a4 190 | + (uint128_t)(a1*2) * a3 191 | + (uint128_t)a2 * a2; 192 | VERIFY_BITS(d, 115); 193 | /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ 194 | d += c * R; 195 | VERIFY_BITS(d, 116); 196 | /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ 197 | t4 = d & M; d >>= 52; 198 | VERIFY_BITS(t4, 52); 199 | VERIFY_BITS(d, 64); 200 | /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ 201 | tx = (t4 >> 48); t4 &= (M >> 4); 202 | VERIFY_BITS(tx, 4); 203 | VERIFY_BITS(t4, 48); 204 | /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ 205 | 206 | c = (uint128_t)a0 * a0; 207 | VERIFY_BITS(c, 112); 208 | /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */ 209 | d += (uint128_t)a1 * a4 210 | + (uint128_t)(a2*2) * a3; 211 | VERIFY_BITS(d, 114); 212 | /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ 213 | u0 = d & M; d >>= 52; 214 | VERIFY_BITS(u0, 52); 215 | VERIFY_BITS(d, 62); 216 | /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ 217 | /* [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ 218 | u0 = (u0 << 4) | tx; 219 | VERIFY_BITS(u0, 56); 220 | /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ 221 | c += (uint128_t)u0 * (R >> 4); 222 | VERIFY_BITS(c, 113); 223 | /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ 224 | r[0] = c & M; c >>= 52; 225 | VERIFY_BITS(r[0], 52); 226 | VERIFY_BITS(c, 61); 227 | /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */ 228 | 229 | a0 *= 2; 230 | c += (uint128_t)a0 * a1; 231 | VERIFY_BITS(c, 114); 232 | /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */ 233 | d += (uint128_t)a2 * a4 234 | + (uint128_t)a3 * a3; 235 | VERIFY_BITS(d, 114); 236 | /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ 237 | c += (d & M) * R; d >>= 52; 238 | VERIFY_BITS(c, 115); 239 | VERIFY_BITS(d, 62); 240 | /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ 241 | r[1] = c & M; c >>= 52; 242 | VERIFY_BITS(r[1], 52); 243 | VERIFY_BITS(c, 63); 244 | /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ 245 | 246 | c += (uint128_t)a0 * a2 247 | + (uint128_t)a1 * a1; 248 | VERIFY_BITS(c, 114); 249 | /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */ 250 | d += (uint128_t)a3 * a4; 251 | VERIFY_BITS(d, 114); 252 | /* [d 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 253 | c += (d & M) * R; d >>= 52; 254 | VERIFY_BITS(c, 115); 255 | VERIFY_BITS(d, 62); 256 | /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 257 | r[2] = c & M; c >>= 52; 258 | VERIFY_BITS(r[2], 52); 259 | VERIFY_BITS(c, 63); 260 | /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 261 | 262 | c += d * R + t3; 263 | VERIFY_BITS(c, 100); 264 | /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 265 | r[3] = c & M; c >>= 52; 266 | VERIFY_BITS(r[3], 52); 267 | VERIFY_BITS(c, 48); 268 | /* [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 269 | c += t4; 270 | VERIFY_BITS(c, 49); 271 | /* [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 272 | r[4] = c; 273 | VERIFY_BITS(r[4], 49); 274 | /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ 275 | } 276 | 277 | #endif /* SECP256K1_FIELD_INNER5X52_IMPL_H */ 278 | -------------------------------------------------------------------------------- /src/secp256k1/src/field_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_FIELD_IMPL_H 8 | #define SECP256K1_FIELD_IMPL_H 9 | 10 | #if defined HAVE_CONFIG_H 11 | #include "libsecp256k1-config.h" 12 | #endif 13 | 14 | #include "util.h" 15 | 16 | #define USE_FIELD_10X26 17 | #if defined(USE_FIELD_10X26) 18 | #include "field_10x26_impl.h" 19 | #elif defined(USE_FIELD_5X52) 20 | #include "field_5x52_impl.h" 21 | #else 22 | #error "Please select field implementation" 23 | #endif 24 | 25 | SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { 26 | secp256k1_fe na; 27 | secp256k1_fe_negate(&na, a, 1); 28 | secp256k1_fe_add(&na, b); 29 | return secp256k1_fe_normalizes_to_zero(&na); 30 | } 31 | 32 | SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b) { 33 | secp256k1_fe na; 34 | secp256k1_fe_negate(&na, a, 1); 35 | secp256k1_fe_add(&na, b); 36 | return secp256k1_fe_normalizes_to_zero_var(&na); 37 | } 38 | 39 | static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) { 40 | /** Given that p is congruent to 3 mod 4, we can compute the square root of 41 | * a mod p as the (p+1)/4'th power of a. 42 | * 43 | * As (p+1)/4 is an even number, it will have the same result for a and for 44 | * (-a). Only one of these two numbers actually has a square root however, 45 | * so we test at the end by squaring and comparing to the input. 46 | * Also because (p+1)/4 is an even number, the computed square root is 47 | * itself always a square (a ** ((p+1)/4) is the square of a ** ((p+1)/8)). 48 | */ 49 | secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; 50 | int j; 51 | 52 | /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in 53 | * { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: 54 | * 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] 55 | */ 56 | 57 | secp256k1_fe_sqr(&x2, a); 58 | secp256k1_fe_mul(&x2, &x2, a); 59 | 60 | secp256k1_fe_sqr(&x3, &x2); 61 | secp256k1_fe_mul(&x3, &x3, a); 62 | 63 | x6 = x3; 64 | for (j=0; j<3; j++) { 65 | secp256k1_fe_sqr(&x6, &x6); 66 | } 67 | secp256k1_fe_mul(&x6, &x6, &x3); 68 | 69 | x9 = x6; 70 | for (j=0; j<3; j++) { 71 | secp256k1_fe_sqr(&x9, &x9); 72 | } 73 | secp256k1_fe_mul(&x9, &x9, &x3); 74 | 75 | x11 = x9; 76 | for (j=0; j<2; j++) { 77 | secp256k1_fe_sqr(&x11, &x11); 78 | } 79 | secp256k1_fe_mul(&x11, &x11, &x2); 80 | 81 | x22 = x11; 82 | for (j=0; j<11; j++) { 83 | secp256k1_fe_sqr(&x22, &x22); 84 | } 85 | secp256k1_fe_mul(&x22, &x22, &x11); 86 | 87 | x44 = x22; 88 | for (j=0; j<22; j++) { 89 | secp256k1_fe_sqr(&x44, &x44); 90 | } 91 | secp256k1_fe_mul(&x44, &x44, &x22); 92 | 93 | x88 = x44; 94 | for (j=0; j<44; j++) { 95 | secp256k1_fe_sqr(&x88, &x88); 96 | } 97 | secp256k1_fe_mul(&x88, &x88, &x44); 98 | 99 | x176 = x88; 100 | for (j=0; j<88; j++) { 101 | secp256k1_fe_sqr(&x176, &x176); 102 | } 103 | secp256k1_fe_mul(&x176, &x176, &x88); 104 | 105 | x220 = x176; 106 | for (j=0; j<44; j++) { 107 | secp256k1_fe_sqr(&x220, &x220); 108 | } 109 | secp256k1_fe_mul(&x220, &x220, &x44); 110 | 111 | x223 = x220; 112 | for (j=0; j<3; j++) { 113 | secp256k1_fe_sqr(&x223, &x223); 114 | } 115 | secp256k1_fe_mul(&x223, &x223, &x3); 116 | 117 | /* The final result is then assembled using a sliding window over the blocks. */ 118 | 119 | t1 = x223; 120 | for (j=0; j<23; j++) { 121 | secp256k1_fe_sqr(&t1, &t1); 122 | } 123 | secp256k1_fe_mul(&t1, &t1, &x22); 124 | for (j=0; j<6; j++) { 125 | secp256k1_fe_sqr(&t1, &t1); 126 | } 127 | secp256k1_fe_mul(&t1, &t1, &x2); 128 | secp256k1_fe_sqr(&t1, &t1); 129 | secp256k1_fe_sqr(r, &t1); 130 | 131 | /* Check that a square root was actually calculated */ 132 | 133 | secp256k1_fe_sqr(&t1, r); 134 | return secp256k1_fe_equal(&t1, a); 135 | } 136 | 137 | static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a) { 138 | secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; 139 | int j; 140 | 141 | /** The binary representation of (p - 2) has 5 blocks of 1s, with lengths in 142 | * { 1, 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: 143 | * [1], [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] 144 | */ 145 | 146 | secp256k1_fe_sqr(&x2, a); 147 | secp256k1_fe_mul(&x2, &x2, a); 148 | 149 | secp256k1_fe_sqr(&x3, &x2); 150 | secp256k1_fe_mul(&x3, &x3, a); 151 | 152 | x6 = x3; 153 | for (j=0; j<3; j++) { 154 | secp256k1_fe_sqr(&x6, &x6); 155 | } 156 | secp256k1_fe_mul(&x6, &x6, &x3); 157 | 158 | x9 = x6; 159 | for (j=0; j<3; j++) { 160 | secp256k1_fe_sqr(&x9, &x9); 161 | } 162 | secp256k1_fe_mul(&x9, &x9, &x3); 163 | 164 | x11 = x9; 165 | for (j=0; j<2; j++) { 166 | secp256k1_fe_sqr(&x11, &x11); 167 | } 168 | secp256k1_fe_mul(&x11, &x11, &x2); 169 | 170 | x22 = x11; 171 | for (j=0; j<11; j++) { 172 | secp256k1_fe_sqr(&x22, &x22); 173 | } 174 | secp256k1_fe_mul(&x22, &x22, &x11); 175 | 176 | x44 = x22; 177 | for (j=0; j<22; j++) { 178 | secp256k1_fe_sqr(&x44, &x44); 179 | } 180 | secp256k1_fe_mul(&x44, &x44, &x22); 181 | 182 | x88 = x44; 183 | for (j=0; j<44; j++) { 184 | secp256k1_fe_sqr(&x88, &x88); 185 | } 186 | secp256k1_fe_mul(&x88, &x88, &x44); 187 | 188 | x176 = x88; 189 | for (j=0; j<88; j++) { 190 | secp256k1_fe_sqr(&x176, &x176); 191 | } 192 | secp256k1_fe_mul(&x176, &x176, &x88); 193 | 194 | x220 = x176; 195 | for (j=0; j<44; j++) { 196 | secp256k1_fe_sqr(&x220, &x220); 197 | } 198 | secp256k1_fe_mul(&x220, &x220, &x44); 199 | 200 | x223 = x220; 201 | for (j=0; j<3; j++) { 202 | secp256k1_fe_sqr(&x223, &x223); 203 | } 204 | secp256k1_fe_mul(&x223, &x223, &x3); 205 | 206 | /* The final result is then assembled using a sliding window over the blocks. */ 207 | 208 | t1 = x223; 209 | for (j=0; j<23; j++) { 210 | secp256k1_fe_sqr(&t1, &t1); 211 | } 212 | secp256k1_fe_mul(&t1, &t1, &x22); 213 | for (j=0; j<5; j++) { 214 | secp256k1_fe_sqr(&t1, &t1); 215 | } 216 | secp256k1_fe_mul(&t1, &t1, a); 217 | for (j=0; j<3; j++) { 218 | secp256k1_fe_sqr(&t1, &t1); 219 | } 220 | secp256k1_fe_mul(&t1, &t1, &x2); 221 | for (j=0; j<2; j++) { 222 | secp256k1_fe_sqr(&t1, &t1); 223 | } 224 | secp256k1_fe_mul(r, a, &t1); 225 | } 226 | 227 | static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a) { 228 | #define USE_FIELD_INV_BUILTIN 229 | #if defined(USE_FIELD_INV_BUILTIN) 230 | secp256k1_fe_inv(r, a); 231 | #elif defined(USE_FIELD_INV_NUM) 232 | secp256k1_num n, m; 233 | static const secp256k1_fe negone = SECP256K1_FE_CONST( 234 | 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 235 | 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 0xFFFFFC2EUL 236 | ); 237 | /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ 238 | static const unsigned char prime[32] = { 239 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 240 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 241 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 242 | 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F 243 | }; 244 | unsigned char b[32]; 245 | int res; 246 | secp256k1_fe c = *a; 247 | secp256k1_fe_normalize_var(&c); 248 | secp256k1_fe_get_b32(b, &c); 249 | secp256k1_num_set_bin(&n, b, 32); 250 | secp256k1_num_set_bin(&m, prime, 32); 251 | secp256k1_num_mod_inverse(&n, &n, &m); 252 | secp256k1_num_get_bin(b, 32, &n); 253 | res = secp256k1_fe_set_b32(r, b); 254 | (void)res; 255 | VERIFY_CHECK(res); 256 | /* Verify the result is the (unique) valid inverse using non-GMP code. */ 257 | secp256k1_fe_mul(&c, &c, r); 258 | secp256k1_fe_add(&c, &negone); 259 | CHECK(secp256k1_fe_normalizes_to_zero_var(&c)); 260 | #else 261 | #error "Please select field inverse implementation" 262 | #endif 263 | } 264 | 265 | static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len) { 266 | secp256k1_fe u; 267 | size_t i; 268 | if (len < 1) { 269 | return; 270 | } 271 | 272 | VERIFY_CHECK((r + len <= a) || (a + len <= r)); 273 | 274 | r[0] = a[0]; 275 | 276 | i = 0; 277 | while (++i < len) { 278 | secp256k1_fe_mul(&r[i], &r[i - 1], &a[i]); 279 | } 280 | 281 | secp256k1_fe_inv_var(&u, &r[--i]); 282 | 283 | while (i > 0) { 284 | size_t j = i--; 285 | secp256k1_fe_mul(&r[j], &r[i], &u); 286 | secp256k1_fe_mul(&u, &u, &a[j]); 287 | } 288 | 289 | r[0] = u; 290 | } 291 | 292 | static int secp256k1_fe_is_quad_var(const secp256k1_fe *a) { 293 | #ifndef USE_NUM_NONE 294 | unsigned char b[32]; 295 | secp256k1_num n; 296 | secp256k1_num m; 297 | /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ 298 | static const unsigned char prime[32] = { 299 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 300 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 301 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 302 | 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F 303 | }; 304 | 305 | secp256k1_fe c = *a; 306 | secp256k1_fe_normalize_var(&c); 307 | secp256k1_fe_get_b32(b, &c); 308 | secp256k1_num_set_bin(&n, b, 32); 309 | secp256k1_num_set_bin(&m, prime, 32); 310 | return secp256k1_num_jacobi(&n, &m) >= 0; 311 | #else 312 | secp256k1_fe r; 313 | return secp256k1_fe_sqrt(&r, a); 314 | #endif 315 | } 316 | 317 | #endif /* SECP256K1_FIELD_IMPL_H */ 318 | -------------------------------------------------------------------------------- /src/secp256k1/src/group.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_GROUP_H 8 | #define SECP256K1_GROUP_H 9 | 10 | #include "num.h" 11 | #include "field.h" 12 | 13 | /** A group element of the secp256k1 curve, in affine coordinates. */ 14 | typedef struct { 15 | secp256k1_fe x; 16 | secp256k1_fe y; 17 | int infinity; /* whether this represents the point at infinity */ 18 | } secp256k1_ge; 19 | 20 | #define SECP256K1_GE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), 0} 21 | #define SECP256K1_GE_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} 22 | 23 | /** A group element of the secp256k1 curve, in jacobian coordinates. */ 24 | typedef struct { 25 | secp256k1_fe x; /* actual X: x/z^2 */ 26 | secp256k1_fe y; /* actual Y: y/z^3 */ 27 | secp256k1_fe z; 28 | int infinity; /* whether this represents the point at infinity */ 29 | } secp256k1_gej; 30 | 31 | #define SECP256K1_GEJ_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1), 0} 32 | #define SECP256K1_GEJ_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} 33 | 34 | typedef struct { 35 | secp256k1_fe_storage x; 36 | secp256k1_fe_storage y; 37 | } secp256k1_ge_storage; 38 | 39 | #define SECP256K1_GE_STORAGE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_STORAGE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_STORAGE_CONST((i),(j),(k),(l),(m),(n),(o),(p))} 40 | 41 | #define SECP256K1_GE_STORAGE_CONST_GET(t) SECP256K1_FE_STORAGE_CONST_GET(t.x), SECP256K1_FE_STORAGE_CONST_GET(t.y) 42 | 43 | /** Set a group element equal to the point with given X and Y coordinates */ 44 | static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y); 45 | 46 | /** Set a group element (affine) equal to the point with the given X coordinate 47 | * and a Y coordinate that is a quadratic residue modulo p. The return value 48 | * is true iff a coordinate with the given X coordinate exists. 49 | */ 50 | static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x); 51 | 52 | /** Set a group element (affine) equal to the point with the given X coordinate, and given oddness 53 | * for Y. Return value indicates whether the result is valid. */ 54 | static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd); 55 | 56 | /** Check whether a group element is the point at infinity. */ 57 | static int secp256k1_ge_is_infinity(const secp256k1_ge *a); 58 | 59 | /** Check whether a group element is valid (i.e., on the curve). */ 60 | static int secp256k1_ge_is_valid_var(const secp256k1_ge *a); 61 | 62 | static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a); 63 | 64 | /** Set a group element equal to another which is given in jacobian coordinates */ 65 | static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a); 66 | 67 | /** Set a batch of group elements equal to the inputs given in jacobian coordinates */ 68 | static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb); 69 | 70 | /** Set a batch of group elements equal to the inputs given in jacobian 71 | * coordinates (with known z-ratios). zr must contain the known z-ratios such 72 | * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. */ 73 | static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len); 74 | 75 | /** Bring a batch inputs given in jacobian coordinates (with known z-ratios) to 76 | * the same global z "denominator". zr must contain the known z-ratios such 77 | * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. The x and y 78 | * coordinates of the result are stored in r, the common z coordinate is 79 | * stored in globalz. */ 80 | static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp256k1_fe *globalz, const secp256k1_gej *a, const secp256k1_fe *zr); 81 | 82 | /** Set a group element (jacobian) equal to the point at infinity. */ 83 | static void secp256k1_gej_set_infinity(secp256k1_gej *r); 84 | 85 | /** Set a group element (jacobian) equal to another which is given in affine coordinates. */ 86 | static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a); 87 | 88 | /** Compare the X coordinate of a group element (jacobian). */ 89 | static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a); 90 | 91 | /** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ 92 | static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a); 93 | 94 | /** Check whether a group element is the point at infinity. */ 95 | static int secp256k1_gej_is_infinity(const secp256k1_gej *a); 96 | 97 | /** Check whether a group element's y coordinate is a quadratic residue. */ 98 | static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a); 99 | 100 | /** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). 101 | * a may not be zero. Constant time. */ 102 | static void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); 103 | 104 | /** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). */ 105 | static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); 106 | 107 | /** Set r equal to the sum of a and b. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */ 108 | static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr); 109 | 110 | /** Set r equal to the sum of a and b (with b given in affine coordinates, and not infinity). */ 111 | static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b); 112 | 113 | /** Set r equal to the sum of a and b (with b given in affine coordinates). This is more efficient 114 | than secp256k1_gej_add_var. It is identical to secp256k1_gej_add_ge but without constant-time 115 | guarantee, and b is allowed to be infinity. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */ 116 | static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr); 117 | 118 | /** Set r equal to the sum of a and b (with the inverse of b's Z coordinate passed as bzinv). */ 119 | static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv); 120 | 121 | #ifdef USE_ENDOMORPHISM 122 | /** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */ 123 | static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a); 124 | #endif 125 | 126 | /** Clear a secp256k1_gej to prevent leaking sensitive information. */ 127 | static void secp256k1_gej_clear(secp256k1_gej *r); 128 | 129 | /** Clear a secp256k1_ge to prevent leaking sensitive information. */ 130 | static void secp256k1_ge_clear(secp256k1_ge *r); 131 | 132 | /** Convert a group element to the storage type. */ 133 | static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a); 134 | 135 | /** Convert a group element back from the storage type. */ 136 | static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a); 137 | 138 | /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ 139 | static void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag); 140 | 141 | /** Rescale a jacobian point by b which must be non-zero. Constant-time. */ 142 | static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *b); 143 | 144 | #endif /* SECP256K1_GROUP_H */ 145 | -------------------------------------------------------------------------------- /src/secp256k1/src/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_t; 18 | 19 | static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash); 20 | static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t size); 21 | static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32); 22 | 23 | typedef struct { 24 | secp256k1_sha256_t inner, outer; 25 | } secp256k1_hmac_sha256_t; 26 | 27 | static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t size); 28 | static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size); 29 | static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *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_t; 36 | 37 | static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen); 38 | static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen); 39 | static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng); 40 | 41 | #endif /* SECP256K1_HASH_H */ 42 | -------------------------------------------------------------------------------- /src/secp256k1/src/hash_impl.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_IMPL_H 8 | #define SECP256K1_HASH_IMPL_H 9 | 10 | #include "hash.h" 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) 17 | #define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) 18 | #define Sigma0(x) (((x) >> 2 | (x) << 30) ^ ((x) >> 13 | (x) << 19) ^ ((x) >> 22 | (x) << 10)) 19 | #define Sigma1(x) (((x) >> 6 | (x) << 26) ^ ((x) >> 11 | (x) << 21) ^ ((x) >> 25 | (x) << 7)) 20 | #define sigma0(x) (((x) >> 7 | (x) << 25) ^ ((x) >> 18 | (x) << 14) ^ ((x) >> 3)) 21 | #define sigma1(x) (((x) >> 17 | (x) << 15) ^ ((x) >> 19 | (x) << 13) ^ ((x) >> 10)) 22 | 23 | #define Round(a,b,c,d,e,f,g,h,k,w) do { \ 24 | uint32_t t1 = (h) + Sigma1(e) + Ch((e), (f), (g)) + (k) + (w); \ 25 | uint32_t t2 = Sigma0(a) + Maj((a), (b), (c)); \ 26 | (d) += t1; \ 27 | (h) = t1 + t2; \ 28 | } while(0) 29 | 30 | #ifdef WORDS_BIGENDIAN 31 | #define BE32(x) (x) 32 | #else 33 | #define BE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24)) 34 | #endif 35 | 36 | static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash) { 37 | hash->s[0] = 0x6a09e667ul; 38 | hash->s[1] = 0xbb67ae85ul; 39 | hash->s[2] = 0x3c6ef372ul; 40 | hash->s[3] = 0xa54ff53aul; 41 | hash->s[4] = 0x510e527ful; 42 | hash->s[5] = 0x9b05688cul; 43 | hash->s[6] = 0x1f83d9abul; 44 | hash->s[7] = 0x5be0cd19ul; 45 | hash->bytes = 0; 46 | } 47 | 48 | /** Perform one SHA-256 transformation, processing 16 big endian 32-bit words. */ 49 | static void secp256k1_sha256_transform(uint32_t* s, const uint32_t* chunk) { 50 | uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; 51 | uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; 52 | 53 | Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = BE32(chunk[0])); 54 | Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = BE32(chunk[1])); 55 | Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = BE32(chunk[2])); 56 | Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = BE32(chunk[3])); 57 | Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = BE32(chunk[4])); 58 | Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = BE32(chunk[5])); 59 | Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = BE32(chunk[6])); 60 | Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = BE32(chunk[7])); 61 | Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = BE32(chunk[8])); 62 | Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = BE32(chunk[9])); 63 | Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = BE32(chunk[10])); 64 | Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = BE32(chunk[11])); 65 | Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = BE32(chunk[12])); 66 | Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = BE32(chunk[13])); 67 | Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = BE32(chunk[14])); 68 | Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = BE32(chunk[15])); 69 | 70 | Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1)); 71 | Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2)); 72 | Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3)); 73 | Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4)); 74 | Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5)); 75 | Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6)); 76 | Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7)); 77 | Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8)); 78 | Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9)); 79 | Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10)); 80 | Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11)); 81 | Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12)); 82 | Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13)); 83 | Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14)); 84 | Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15)); 85 | Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0)); 86 | 87 | Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1)); 88 | Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2)); 89 | Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3)); 90 | Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4)); 91 | Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5)); 92 | Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6)); 93 | Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7)); 94 | Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8)); 95 | Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9)); 96 | Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10)); 97 | Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11)); 98 | Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12)); 99 | Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13)); 100 | Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14)); 101 | Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15)); 102 | Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0)); 103 | 104 | Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1)); 105 | Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2)); 106 | Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3)); 107 | Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4)); 108 | Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5)); 109 | Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6)); 110 | Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7)); 111 | Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8)); 112 | Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9)); 113 | Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10)); 114 | Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11)); 115 | Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12)); 116 | Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13)); 117 | Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14)); 118 | Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15)); 119 | Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0)); 120 | 121 | s[0] += a; 122 | s[1] += b; 123 | s[2] += c; 124 | s[3] += d; 125 | s[4] += e; 126 | s[5] += f; 127 | s[6] += g; 128 | s[7] += h; 129 | } 130 | 131 | static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t len) { 132 | size_t bufsize = hash->bytes & 0x3F; 133 | hash->bytes += len; 134 | while (bufsize + len >= 64) { 135 | /* Fill the buffer, and process it. */ 136 | memcpy(((unsigned char*)hash->buf) + bufsize, data, 64 - bufsize); 137 | data += 64 - bufsize; 138 | len -= 64 - bufsize; 139 | secp256k1_sha256_transform(hash->s, hash->buf); 140 | bufsize = 0; 141 | } 142 | if (len) { 143 | /* Fill the buffer with what remains. */ 144 | memcpy(((unsigned char*)hash->buf) + bufsize, data, len); 145 | } 146 | } 147 | 148 | static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32) { 149 | static const unsigned char pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 150 | uint32_t sizedesc[2]; 151 | uint32_t out[8]; 152 | int i = 0; 153 | sizedesc[0] = BE32(hash->bytes >> 29); 154 | sizedesc[1] = BE32(hash->bytes << 3); 155 | secp256k1_sha256_write(hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64)); 156 | secp256k1_sha256_write(hash, (const unsigned char*)sizedesc, 8); 157 | for (i = 0; i < 8; i++) { 158 | out[i] = BE32(hash->s[i]); 159 | hash->s[i] = 0; 160 | } 161 | memcpy(out32, (const unsigned char*)out, 32); 162 | } 163 | 164 | static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t keylen) { 165 | int n; 166 | unsigned char rkey[64]; 167 | if (keylen <= 64) { 168 | memcpy(rkey, key, keylen); 169 | memset(rkey + keylen, 0, 64 - keylen); 170 | } else { 171 | secp256k1_sha256_t sha256; 172 | secp256k1_sha256_initialize(&sha256); 173 | secp256k1_sha256_write(&sha256, key, keylen); 174 | secp256k1_sha256_finalize(&sha256, rkey); 175 | memset(rkey + 32, 0, 32); 176 | } 177 | 178 | secp256k1_sha256_initialize(&hash->outer); 179 | for (n = 0; n < 64; n++) { 180 | rkey[n] ^= 0x5c; 181 | } 182 | secp256k1_sha256_write(&hash->outer, rkey, 64); 183 | 184 | secp256k1_sha256_initialize(&hash->inner); 185 | for (n = 0; n < 64; n++) { 186 | rkey[n] ^= 0x5c ^ 0x36; 187 | } 188 | secp256k1_sha256_write(&hash->inner, rkey, 64); 189 | memset(rkey, 0, 64); 190 | } 191 | 192 | static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size) { 193 | secp256k1_sha256_write(&hash->inner, data, size); 194 | } 195 | 196 | static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32) { 197 | unsigned char temp[32]; 198 | secp256k1_sha256_finalize(&hash->inner, temp); 199 | secp256k1_sha256_write(&hash->outer, temp, 32); 200 | memset(temp, 0, 32); 201 | secp256k1_sha256_finalize(&hash->outer, out32); 202 | } 203 | 204 | 205 | static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen) { 206 | secp256k1_hmac_sha256_t hmac; 207 | static const unsigned char zero[1] = {0x00}; 208 | static const unsigned char one[1] = {0x01}; 209 | 210 | memset(rng->v, 0x01, 32); /* RFC6979 3.2.b. */ 211 | memset(rng->k, 0x00, 32); /* RFC6979 3.2.c. */ 212 | 213 | /* RFC6979 3.2.d. */ 214 | secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); 215 | secp256k1_hmac_sha256_write(&hmac, rng->v, 32); 216 | secp256k1_hmac_sha256_write(&hmac, zero, 1); 217 | secp256k1_hmac_sha256_write(&hmac, key, keylen); 218 | secp256k1_hmac_sha256_finalize(&hmac, rng->k); 219 | secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); 220 | secp256k1_hmac_sha256_write(&hmac, rng->v, 32); 221 | secp256k1_hmac_sha256_finalize(&hmac, rng->v); 222 | 223 | /* RFC6979 3.2.f. */ 224 | secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); 225 | secp256k1_hmac_sha256_write(&hmac, rng->v, 32); 226 | secp256k1_hmac_sha256_write(&hmac, one, 1); 227 | secp256k1_hmac_sha256_write(&hmac, key, keylen); 228 | secp256k1_hmac_sha256_finalize(&hmac, rng->k); 229 | secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); 230 | secp256k1_hmac_sha256_write(&hmac, rng->v, 32); 231 | secp256k1_hmac_sha256_finalize(&hmac, rng->v); 232 | rng->retry = 0; 233 | } 234 | 235 | static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen) { 236 | /* RFC6979 3.2.h. */ 237 | static const unsigned char zero[1] = {0x00}; 238 | if (rng->retry) { 239 | secp256k1_hmac_sha256_t hmac; 240 | secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); 241 | secp256k1_hmac_sha256_write(&hmac, rng->v, 32); 242 | secp256k1_hmac_sha256_write(&hmac, zero, 1); 243 | secp256k1_hmac_sha256_finalize(&hmac, rng->k); 244 | secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); 245 | secp256k1_hmac_sha256_write(&hmac, rng->v, 32); 246 | secp256k1_hmac_sha256_finalize(&hmac, rng->v); 247 | } 248 | 249 | while (outlen > 0) { 250 | secp256k1_hmac_sha256_t hmac; 251 | int now = outlen; 252 | secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); 253 | secp256k1_hmac_sha256_write(&hmac, rng->v, 32); 254 | secp256k1_hmac_sha256_finalize(&hmac, rng->v); 255 | if (now > 32) { 256 | now = 32; 257 | } 258 | memcpy(out, rng->v, now); 259 | out += now; 260 | outlen -= now; 261 | } 262 | 263 | rng->retry = 1; 264 | } 265 | 266 | static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng) { 267 | memset(rng->k, 0, 32); 268 | memset(rng->v, 0, 32); 269 | rng->retry = 0; 270 | } 271 | 272 | #undef BE32 273 | #undef Round 274 | #undef sigma1 275 | #undef sigma0 276 | #undef Sigma1 277 | #undef Sigma0 278 | #undef Maj 279 | #undef Ch 280 | 281 | #endif /* SECP256K1_HASH_IMPL_H */ 282 | -------------------------------------------------------------------------------- /src/secp256k1/src/libsecp256k1-config.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Okada, Takahiro on 2018/02/25. 3 | // 4 | 5 | #ifndef ARDUINO_WEB3_LIBSECP256K1_CONFIG_H 6 | #define ARDUINO_WEB3_LIBSECP256K1_CONFIG_H 7 | 8 | #endif //ARDUINO_WEB3_LIBSECP256K1_CONFIG_H 9 | -------------------------------------------------------------------------------- /src/secp256k1/src/module/recovery/main_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013-2015 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_MODULE_RECOVERY_MAIN_H 8 | #define SECP256K1_MODULE_RECOVERY_MAIN_H 9 | 10 | #include "../../../include/secp256k1_recovery.h" 11 | 12 | static void secp256k1_ecdsa_recoverable_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const secp256k1_ecdsa_recoverable_signature* sig) { 13 | (void)ctx; 14 | if (sizeof(secp256k1_scalar) == 32) { 15 | /* When the secp256k1_scalar type is exactly 32 byte, use its 16 | * representation inside secp256k1_ecdsa_signature, as conversion is very fast. 17 | * Note that secp256k1_ecdsa_signature_save must use the same representation. */ 18 | memcpy(r, &sig->data[0], 32); 19 | memcpy(s, &sig->data[32], 32); 20 | } else { 21 | secp256k1_scalar_set_b32(r, &sig->data[0], NULL); 22 | secp256k1_scalar_set_b32(s, &sig->data[32], NULL); 23 | } 24 | *recid = sig->data[64]; 25 | } 26 | 27 | static void secp256k1_ecdsa_recoverable_signature_save(secp256k1_ecdsa_recoverable_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s, int recid) { 28 | if (sizeof(secp256k1_scalar) == 32) { 29 | memcpy(&sig->data[0], r, 32); 30 | memcpy(&sig->data[32], s, 32); 31 | } else { 32 | secp256k1_scalar_get_b32(&sig->data[0], r); 33 | secp256k1_scalar_get_b32(&sig->data[32], s); 34 | } 35 | sig->data[64] = recid; 36 | } 37 | 38 | int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature* sig, const unsigned char *input64, int recid) { 39 | secp256k1_scalar r, s; 40 | int ret = 1; 41 | int overflow = 0; 42 | 43 | (void)ctx; 44 | ARG_CHECK(sig != NULL); 45 | ARG_CHECK(input64 != NULL); 46 | ARG_CHECK(recid >= 0 && recid <= 3); 47 | 48 | secp256k1_scalar_set_b32(&r, &input64[0], &overflow); 49 | ret &= !overflow; 50 | secp256k1_scalar_set_b32(&s, &input64[32], &overflow); 51 | ret &= !overflow; 52 | if (ret) { 53 | secp256k1_ecdsa_recoverable_signature_save(sig, &r, &s, recid); 54 | } else { 55 | memset(sig, 0, sizeof(*sig)); 56 | } 57 | return ret; 58 | } 59 | 60 | int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature* sig) { 61 | secp256k1_scalar r, s; 62 | 63 | (void)ctx; 64 | ARG_CHECK(output64 != NULL); 65 | ARG_CHECK(sig != NULL); 66 | ARG_CHECK(recid != NULL); 67 | 68 | secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, recid, sig); 69 | secp256k1_scalar_get_b32(&output64[0], &r); 70 | secp256k1_scalar_get_b32(&output64[32], &s); 71 | return 1; 72 | } 73 | 74 | int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const secp256k1_ecdsa_recoverable_signature* sigin) { 75 | secp256k1_scalar r, s; 76 | int recid; 77 | 78 | (void)ctx; 79 | ARG_CHECK(sig != NULL); 80 | ARG_CHECK(sigin != NULL); 81 | 82 | secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, sigin); 83 | secp256k1_ecdsa_signature_save(sig, &r, &s); 84 | return 1; 85 | } 86 | 87 | static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar* sigs, secp256k1_ge *pubkey, const secp256k1_scalar *message, int recid) { 88 | unsigned char brx[32]; 89 | secp256k1_fe fx; 90 | secp256k1_ge x; 91 | secp256k1_gej xj; 92 | secp256k1_scalar rn, u1, u2; 93 | secp256k1_gej qj; 94 | int r; 95 | 96 | if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { 97 | return 0; 98 | } 99 | 100 | secp256k1_scalar_get_b32(brx, sigr); 101 | r = secp256k1_fe_set_b32(&fx, brx); 102 | (void)r; 103 | VERIFY_CHECK(r); /* brx comes from a scalar, so is less than the order; certainly less than p */ 104 | if (recid & 2) { 105 | if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) { 106 | return 0; 107 | } 108 | secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe); 109 | } 110 | if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) { 111 | return 0; 112 | } 113 | secp256k1_gej_set_ge(&xj, &x); 114 | secp256k1_scalar_inverse_var(&rn, sigr); 115 | secp256k1_scalar_mul(&u1, &rn, message); 116 | secp256k1_scalar_negate(&u1, &u1); 117 | secp256k1_scalar_mul(&u2, &rn, sigs); 118 | secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1); 119 | secp256k1_ge_set_gej_var(pubkey, &qj); 120 | return !secp256k1_gej_is_infinity(&qj); 121 | } 122 | 123 | int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { 124 | secp256k1_scalar r, s; 125 | secp256k1_scalar sec, non, msg; 126 | int recid; 127 | int ret = 0; 128 | int overflow = 0; 129 | VERIFY_CHECK(ctx != NULL); 130 | ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); 131 | ARG_CHECK(msg32 != NULL); 132 | ARG_CHECK(signature != NULL); 133 | ARG_CHECK(seckey != NULL); 134 | if (noncefp == NULL) { 135 | noncefp = secp256k1_nonce_function_default; 136 | } 137 | 138 | secp256k1_scalar_set_b32(&sec, seckey, &overflow); 139 | /* Fail if the secret key is invalid. */ 140 | if (!overflow && !secp256k1_scalar_is_zero(&sec)) { 141 | unsigned char nonce32[32]; 142 | unsigned int count = 0; 143 | secp256k1_scalar_set_b32(&msg, msg32, NULL); 144 | while (1) { 145 | ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); 146 | if (!ret) { 147 | break; 148 | } 149 | secp256k1_scalar_set_b32(&non, nonce32, &overflow); 150 | if (!secp256k1_scalar_is_zero(&non) && !overflow) { 151 | if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, &recid)) { 152 | break; 153 | } 154 | } 155 | count++; 156 | } 157 | memset(nonce32, 0, 32); 158 | secp256k1_scalar_clear(&msg); 159 | secp256k1_scalar_clear(&non); 160 | secp256k1_scalar_clear(&sec); 161 | } 162 | if (ret) { 163 | secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid); 164 | } else { 165 | memset(signature, 0, sizeof(*signature)); 166 | } 167 | return ret; 168 | } 169 | 170 | int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32) { 171 | secp256k1_ge q; 172 | secp256k1_scalar r, s; 173 | secp256k1_scalar m; 174 | int recid; 175 | VERIFY_CHECK(ctx != NULL); 176 | ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); 177 | ARG_CHECK(msg32 != NULL); 178 | ARG_CHECK(signature != NULL); 179 | ARG_CHECK(pubkey != NULL); 180 | 181 | secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature); 182 | VERIFY_CHECK(recid >= 0 && recid < 4); /* should have been caught in parse_compact */ 183 | secp256k1_scalar_set_b32(&m, msg32, NULL); 184 | if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &r, &s, &q, &m, recid)) { 185 | secp256k1_pubkey_save(pubkey, &q); 186 | return 1; 187 | } else { 188 | memset(pubkey, 0, sizeof(*pubkey)); 189 | return 0; 190 | } 191 | } 192 | 193 | #endif /* SECP256K1_MODULE_RECOVERY_MAIN_H */ 194 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | #define USE_NUM_NONE 11 | 12 | #ifndef USE_NUM_NONE 13 | 14 | #if defined HAVE_CONFIG_H 15 | #include "libsecp256k1-config.h" 16 | #endif 17 | 18 | #define USE_NUM_GMP 19 | #if defined(USE_NUM_GMP) 20 | #include "num_gmp.h" 21 | #else 22 | #error "Please select num implementation" 23 | #endif 24 | 25 | /** Copy a number. */ 26 | static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a); 27 | 28 | /** Convert a number's absolute value to a binary big-endian string. 29 | * There must be enough place. */ 30 | static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a); 31 | 32 | /** Set a number to the value of a binary big-endian string. */ 33 | static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen); 34 | 35 | /** Compute a modular inverse. The input must be less than the modulus. */ 36 | static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m); 37 | 38 | /** Compute the jacobi symbol (a|b). b must be positive and odd. */ 39 | static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b); 40 | 41 | /** Compare the absolute value of two numbers. */ 42 | static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b); 43 | 44 | /** Test whether two number are equal (including sign). */ 45 | static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b); 46 | 47 | /** Add two (signed) numbers. */ 48 | static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 49 | 50 | /** Subtract two (signed) numbers. */ 51 | static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 52 | 53 | /** Multiply two (signed) numbers. */ 54 | static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 55 | 56 | /** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1, 57 | even if r was negative. */ 58 | static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m); 59 | 60 | /** Right-shift the passed number by bits bits. */ 61 | static void secp256k1_num_shift(secp256k1_num *r, int bits); 62 | 63 | /** Check whether a number is zero. */ 64 | static int secp256k1_num_is_zero(const secp256k1_num *a); 65 | 66 | /** Check whether a number is one. */ 67 | static int secp256k1_num_is_one(const secp256k1_num *a); 68 | 69 | /** Check whether a number is strictly negative. */ 70 | static int secp256k1_num_is_neg(const secp256k1_num *a); 71 | 72 | /** Change a number's sign. */ 73 | static void secp256k1_num_negate(secp256k1_num *r); 74 | 75 | #endif 76 | 77 | #endif /* SECP256K1_NUM_H */ 78 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | -------------------------------------------------------------------------------- /src/secp256k1/src/num_gmp_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_REPR_IMPL_H 8 | #define SECP256K1_NUM_REPR_IMPL_H 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "util.h" 15 | #include "num.h" 16 | 17 | #ifdef VERIFY 18 | static void secp256k1_num_sanity(const secp256k1_num *a) { 19 | VERIFY_CHECK(a->limbs == 1 || (a->limbs > 1 && a->data[a->limbs-1] != 0)); 20 | } 21 | #else 22 | #define secp256k1_num_sanity(a) do { } while(0) 23 | #endif 24 | 25 | static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a) { 26 | *r = *a; 27 | } 28 | 29 | static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a) { 30 | unsigned char tmp[65]; 31 | int len = 0; 32 | int shift = 0; 33 | if (a->limbs>1 || a->data[0] != 0) { 34 | len = mpn_get_str(tmp, 256, (mp_limb_t*)a->data, a->limbs); 35 | } 36 | while (shift < len && tmp[shift] == 0) shift++; 37 | VERIFY_CHECK(len-shift <= (int)rlen); 38 | memset(r, 0, rlen - len + shift); 39 | if (len > shift) { 40 | memcpy(r + rlen - len + shift, tmp + shift, len - shift); 41 | } 42 | memset(tmp, 0, sizeof(tmp)); 43 | } 44 | 45 | static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen) { 46 | int len; 47 | VERIFY_CHECK(alen > 0); 48 | VERIFY_CHECK(alen <= 64); 49 | len = mpn_set_str(r->data, a, alen, 256); 50 | if (len == 0) { 51 | r->data[0] = 0; 52 | len = 1; 53 | } 54 | VERIFY_CHECK(len <= NUM_LIMBS*2); 55 | r->limbs = len; 56 | r->neg = 0; 57 | while (r->limbs > 1 && r->data[r->limbs-1]==0) { 58 | r->limbs--; 59 | } 60 | } 61 | 62 | static void secp256k1_num_add_abs(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { 63 | mp_limb_t c = mpn_add(r->data, a->data, a->limbs, b->data, b->limbs); 64 | r->limbs = a->limbs; 65 | if (c != 0) { 66 | VERIFY_CHECK(r->limbs < 2*NUM_LIMBS); 67 | r->data[r->limbs++] = c; 68 | } 69 | } 70 | 71 | static void secp256k1_num_sub_abs(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { 72 | mp_limb_t c = mpn_sub(r->data, a->data, a->limbs, b->data, b->limbs); 73 | (void)c; 74 | VERIFY_CHECK(c == 0); 75 | r->limbs = a->limbs; 76 | while (r->limbs > 1 && r->data[r->limbs-1]==0) { 77 | r->limbs--; 78 | } 79 | } 80 | 81 | static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m) { 82 | secp256k1_num_sanity(r); 83 | secp256k1_num_sanity(m); 84 | 85 | if (r->limbs >= m->limbs) { 86 | mp_limb_t t[2*NUM_LIMBS]; 87 | mpn_tdiv_qr(t, r->data, 0, r->data, r->limbs, m->data, m->limbs); 88 | memset(t, 0, sizeof(t)); 89 | r->limbs = m->limbs; 90 | while (r->limbs > 1 && r->data[r->limbs-1]==0) { 91 | r->limbs--; 92 | } 93 | } 94 | 95 | if (r->neg && (r->limbs > 1 || r->data[0] != 0)) { 96 | secp256k1_num_sub_abs(r, m, r); 97 | r->neg = 0; 98 | } 99 | } 100 | 101 | static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m) { 102 | int i; 103 | mp_limb_t g[NUM_LIMBS+1]; 104 | mp_limb_t u[NUM_LIMBS+1]; 105 | mp_limb_t v[NUM_LIMBS+1]; 106 | mp_size_t sn; 107 | mp_size_t gn; 108 | secp256k1_num_sanity(a); 109 | secp256k1_num_sanity(m); 110 | 111 | /** mpn_gcdext computes: (G,S) = gcdext(U,V), where 112 | * * G = gcd(U,V) 113 | * * G = U*S + V*T 114 | * * U has equal or more limbs than V, and V has no padding 115 | * If we set U to be (a padded version of) a, and V = m: 116 | * G = a*S + m*T 117 | * G = a*S mod m 118 | * Assuming G=1: 119 | * S = 1/a mod m 120 | */ 121 | VERIFY_CHECK(m->limbs <= NUM_LIMBS); 122 | VERIFY_CHECK(m->data[m->limbs-1] != 0); 123 | for (i = 0; i < m->limbs; i++) { 124 | u[i] = (i < a->limbs) ? a->data[i] : 0; 125 | v[i] = m->data[i]; 126 | } 127 | sn = NUM_LIMBS+1; 128 | gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs); 129 | (void)gn; 130 | VERIFY_CHECK(gn == 1); 131 | VERIFY_CHECK(g[0] == 1); 132 | r->neg = a->neg ^ m->neg; 133 | if (sn < 0) { 134 | mpn_sub(r->data, m->data, m->limbs, r->data, -sn); 135 | r->limbs = m->limbs; 136 | while (r->limbs > 1 && r->data[r->limbs-1]==0) { 137 | r->limbs--; 138 | } 139 | } else { 140 | r->limbs = sn; 141 | } 142 | memset(g, 0, sizeof(g)); 143 | memset(u, 0, sizeof(u)); 144 | memset(v, 0, sizeof(v)); 145 | } 146 | 147 | static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b) { 148 | int ret; 149 | mpz_t ga, gb; 150 | secp256k1_num_sanity(a); 151 | secp256k1_num_sanity(b); 152 | VERIFY_CHECK(!b->neg && (b->limbs > 0) && (b->data[0] & 1)); 153 | 154 | mpz_inits(ga, gb, NULL); 155 | 156 | mpz_import(gb, b->limbs, -1, sizeof(mp_limb_t), 0, 0, b->data); 157 | mpz_import(ga, a->limbs, -1, sizeof(mp_limb_t), 0, 0, a->data); 158 | if (a->neg) { 159 | mpz_neg(ga, ga); 160 | } 161 | 162 | ret = mpz_jacobi(ga, gb); 163 | 164 | mpz_clears(ga, gb, NULL); 165 | 166 | return ret; 167 | } 168 | 169 | static int secp256k1_num_is_one(const secp256k1_num *a) { 170 | return (a->limbs == 1 && a->data[0] == 1); 171 | } 172 | 173 | static int secp256k1_num_is_zero(const secp256k1_num *a) { 174 | return (a->limbs == 1 && a->data[0] == 0); 175 | } 176 | 177 | static int secp256k1_num_is_neg(const secp256k1_num *a) { 178 | return (a->limbs > 1 || a->data[0] != 0) && a->neg; 179 | } 180 | 181 | static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b) { 182 | if (a->limbs > b->limbs) { 183 | return 1; 184 | } 185 | if (a->limbs < b->limbs) { 186 | return -1; 187 | } 188 | return mpn_cmp(a->data, b->data, a->limbs); 189 | } 190 | 191 | static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b) { 192 | if (a->limbs > b->limbs) { 193 | return 0; 194 | } 195 | if (a->limbs < b->limbs) { 196 | return 0; 197 | } 198 | if ((a->neg && !secp256k1_num_is_zero(a)) != (b->neg && !secp256k1_num_is_zero(b))) { 199 | return 0; 200 | } 201 | return mpn_cmp(a->data, b->data, a->limbs) == 0; 202 | } 203 | 204 | static void secp256k1_num_subadd(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b, int bneg) { 205 | if (!(b->neg ^ bneg ^ a->neg)) { /* a and b have the same sign */ 206 | r->neg = a->neg; 207 | if (a->limbs >= b->limbs) { 208 | secp256k1_num_add_abs(r, a, b); 209 | } else { 210 | secp256k1_num_add_abs(r, b, a); 211 | } 212 | } else { 213 | if (secp256k1_num_cmp(a, b) > 0) { 214 | r->neg = a->neg; 215 | secp256k1_num_sub_abs(r, a, b); 216 | } else { 217 | r->neg = b->neg ^ bneg; 218 | secp256k1_num_sub_abs(r, b, a); 219 | } 220 | } 221 | } 222 | 223 | static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { 224 | secp256k1_num_sanity(a); 225 | secp256k1_num_sanity(b); 226 | secp256k1_num_subadd(r, a, b, 0); 227 | } 228 | 229 | static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { 230 | secp256k1_num_sanity(a); 231 | secp256k1_num_sanity(b); 232 | secp256k1_num_subadd(r, a, b, 1); 233 | } 234 | 235 | static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { 236 | mp_limb_t tmp[2*NUM_LIMBS+1]; 237 | secp256k1_num_sanity(a); 238 | secp256k1_num_sanity(b); 239 | 240 | VERIFY_CHECK(a->limbs + b->limbs <= 2*NUM_LIMBS+1); 241 | if ((a->limbs==1 && a->data[0]==0) || (b->limbs==1 && b->data[0]==0)) { 242 | r->limbs = 1; 243 | r->neg = 0; 244 | r->data[0] = 0; 245 | return; 246 | } 247 | if (a->limbs >= b->limbs) { 248 | mpn_mul(tmp, a->data, a->limbs, b->data, b->limbs); 249 | } else { 250 | mpn_mul(tmp, b->data, b->limbs, a->data, a->limbs); 251 | } 252 | r->limbs = a->limbs + b->limbs; 253 | if (r->limbs > 1 && tmp[r->limbs - 1]==0) { 254 | r->limbs--; 255 | } 256 | VERIFY_CHECK(r->limbs <= 2*NUM_LIMBS); 257 | mpn_copyi(r->data, tmp, r->limbs); 258 | r->neg = a->neg ^ b->neg; 259 | memset(tmp, 0, sizeof(tmp)); 260 | } 261 | 262 | static void secp256k1_num_shift(secp256k1_num *r, int bits) { 263 | if (bits % GMP_NUMB_BITS) { 264 | /* Shift within limbs. */ 265 | mpn_rshift(r->data, r->data, r->limbs, bits % GMP_NUMB_BITS); 266 | } 267 | if (bits >= GMP_NUMB_BITS) { 268 | int i; 269 | /* Shift full limbs. */ 270 | for (i = 0; i < r->limbs; i++) { 271 | int index = i + (bits / GMP_NUMB_BITS); 272 | if (index < r->limbs && index < 2*NUM_LIMBS) { 273 | r->data[i] = r->data[index]; 274 | } else { 275 | r->data[i] = 0; 276 | } 277 | } 278 | } 279 | while (r->limbs>1 && r->data[r->limbs-1]==0) { 280 | r->limbs--; 281 | } 282 | } 283 | 284 | static void secp256k1_num_negate(secp256k1_num *r) { 285 | r->neg ^= 1; 286 | } 287 | 288 | #endif /* SECP256K1_NUM_REPR_IMPL_H */ 289 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | #if defined HAVE_CONFIG_H 11 | #include "libsecp256k1-config.h" 12 | #endif 13 | 14 | #include "num.h" 15 | 16 | #if defined(USE_NUM_GMP) 17 | #include "num_gmp_impl.h" 18 | #elif defined(USE_NUM_NONE) 19 | /* Nothing. */ 20 | #else 21 | #error "Please select num implementation" 22 | #endif 23 | 24 | #endif /* SECP256K1_NUM_IMPL_H */ 25 | -------------------------------------------------------------------------------- /src/secp256k1/src/scalar.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_H 8 | #define SECP256K1_SCALAR_H 9 | 10 | #include "num.h" 11 | 12 | #if defined HAVE_CONFIG_H 13 | #include "libsecp256k1-config.h" 14 | #endif 15 | 16 | #define USE_SCALAR_8X32 17 | #if defined(EXHAUSTIVE_TEST_ORDER) 18 | #include "scalar_low.h" 19 | #elif defined(USE_SCALAR_4X64) 20 | #include "scalar_4x64.h" 21 | #elif defined(USE_SCALAR_8X32) 22 | #include "scalar_8x32.h" 23 | #else 24 | #error "Please select scalar implementation" 25 | #endif 26 | 27 | /** Clear a scalar to prevent the leak of sensitive data. */ 28 | static void secp256k1_scalar_clear(secp256k1_scalar *r); 29 | 30 | /** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */ 31 | static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count); 32 | 33 | /** Access bits from a scalar. Not constant time. */ 34 | static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count); 35 | 36 | /** Set a scalar from a big endian byte array. */ 37 | static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow); 38 | 39 | /** Set a scalar to an unsigned integer. */ 40 | static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v); 41 | 42 | /** Convert a scalar to a byte array. */ 43 | static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a); 44 | 45 | /** Add two scalars together (modulo the group order). Returns whether it overflowed. */ 46 | static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); 47 | 48 | /** Conditionally add a power of two to a scalar. The result is not allowed to overflow. */ 49 | static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag); 50 | 51 | /** Multiply two scalars (modulo the group order). */ 52 | static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); 53 | 54 | /** Shift a scalar right by some amount strictly between 0 and 16, returning 55 | * the low bits that were shifted off */ 56 | static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n); 57 | 58 | /** Compute the square of a scalar (modulo the group order). */ 59 | static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a); 60 | 61 | /** Compute the inverse of a scalar (modulo the group order). */ 62 | static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *a); 63 | 64 | /** Compute the inverse of a scalar (modulo the group order), without constant-time guarantee. */ 65 | static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *a); 66 | 67 | /** Compute the complement of a scalar (modulo the group order). */ 68 | static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a); 69 | 70 | /** Check whether a scalar equals zero. */ 71 | static int secp256k1_scalar_is_zero(const secp256k1_scalar *a); 72 | 73 | /** Check whether a scalar equals one. */ 74 | static int secp256k1_scalar_is_one(const secp256k1_scalar *a); 75 | 76 | /** Check whether a scalar, considered as an nonnegative integer, is even. */ 77 | static int secp256k1_scalar_is_even(const secp256k1_scalar *a); 78 | 79 | /** Check whether a scalar is higher than the group order divided by 2. */ 80 | static int secp256k1_scalar_is_high(const secp256k1_scalar *a); 81 | 82 | /** Conditionally negate a number, in constant time. 83 | * Returns -1 if the number was negated, 1 otherwise */ 84 | static int secp256k1_scalar_cond_negate(secp256k1_scalar *a, int flag); 85 | 86 | #ifndef USE_NUM_NONE 87 | /** Convert a scalar to a number. */ 88 | static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a); 89 | 90 | /** Get the order of the group as a number. */ 91 | static void secp256k1_scalar_order_get_num(secp256k1_num *r); 92 | #endif 93 | 94 | /** Compare two scalars. */ 95 | static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b); 96 | 97 | #ifdef USE_ENDOMORPHISM 98 | /** Find r1 and r2 such that r1+r2*2^128 = a. */ 99 | static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); 100 | /** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (see secp256k1_gej_mul_lambda). */ 101 | static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); 102 | #endif 103 | 104 | /** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */ 105 | static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift); 106 | 107 | #endif /* SECP256K1_SCALAR_H */ 108 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | -------------------------------------------------------------------------------- /src/secp256k1/src/scalar_impl.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_IMPL_H 8 | #define SECP256K1_SCALAR_IMPL_H 9 | 10 | #include "group.h" 11 | #include "scalar.h" 12 | 13 | #if defined HAVE_CONFIG_H 14 | #include "libsecp256k1-config.h" 15 | #endif 16 | 17 | #if defined(EXHAUSTIVE_TEST_ORDER) 18 | #include "scalar_low_impl.h" 19 | #elif defined(USE_SCALAR_4X64) 20 | #include "scalar_4x64_impl.h" 21 | #elif defined(USE_SCALAR_8X32) 22 | #include "scalar_8x32_impl.h" 23 | #else 24 | #error "Please select scalar implementation" 25 | #endif 26 | 27 | #ifndef USE_NUM_NONE 28 | static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a) { 29 | unsigned char c[32]; 30 | secp256k1_scalar_get_b32(c, a); 31 | secp256k1_num_set_bin(r, c, 32); 32 | } 33 | 34 | /** secp256k1 curve order, see secp256k1_ecdsa_const_order_as_fe in ecdsa_impl.h */ 35 | static void secp256k1_scalar_order_get_num(secp256k1_num *r) { 36 | #if defined(EXHAUSTIVE_TEST_ORDER) 37 | static const unsigned char order[32] = { 38 | 0,0,0,0,0,0,0,0, 39 | 0,0,0,0,0,0,0,0, 40 | 0,0,0,0,0,0,0,0, 41 | 0,0,0,0,0,0,0,EXHAUSTIVE_TEST_ORDER 42 | }; 43 | #else 44 | static const unsigned char order[32] = { 45 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 46 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, 47 | 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, 48 | 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 49 | }; 50 | #endif 51 | secp256k1_num_set_bin(r, order, 32); 52 | } 53 | #endif 54 | 55 | static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { 56 | #if defined(EXHAUSTIVE_TEST_ORDER) 57 | int i; 58 | *r = 0; 59 | for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) 60 | if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1) 61 | *r = i; 62 | /* If this VERIFY_CHECK triggers we were given a noninvertible scalar (and thus 63 | * have a composite group order; fix it in exhaustive_tests.c). */ 64 | VERIFY_CHECK(*r != 0); 65 | } 66 | #else 67 | secp256k1_scalar *t; 68 | int i; 69 | /* First compute xN as x ^ (2^N - 1) for some values of N, 70 | * and uM as x ^ M for some values of M. */ 71 | secp256k1_scalar x2, x3, x6, x8, x14, x28, x56, x112, x126; 72 | secp256k1_scalar u2, u5, u9, u11, u13; 73 | 74 | secp256k1_scalar_sqr(&u2, x); 75 | secp256k1_scalar_mul(&x2, &u2, x); 76 | secp256k1_scalar_mul(&u5, &u2, &x2); 77 | secp256k1_scalar_mul(&x3, &u5, &u2); 78 | secp256k1_scalar_mul(&u9, &x3, &u2); 79 | secp256k1_scalar_mul(&u11, &u9, &u2); 80 | secp256k1_scalar_mul(&u13, &u11, &u2); 81 | 82 | secp256k1_scalar_sqr(&x6, &u13); 83 | secp256k1_scalar_sqr(&x6, &x6); 84 | secp256k1_scalar_mul(&x6, &x6, &u11); 85 | 86 | secp256k1_scalar_sqr(&x8, &x6); 87 | secp256k1_scalar_sqr(&x8, &x8); 88 | secp256k1_scalar_mul(&x8, &x8, &x2); 89 | 90 | secp256k1_scalar_sqr(&x14, &x8); 91 | for (i = 0; i < 5; i++) { 92 | secp256k1_scalar_sqr(&x14, &x14); 93 | } 94 | secp256k1_scalar_mul(&x14, &x14, &x6); 95 | 96 | secp256k1_scalar_sqr(&x28, &x14); 97 | for (i = 0; i < 13; i++) { 98 | secp256k1_scalar_sqr(&x28, &x28); 99 | } 100 | secp256k1_scalar_mul(&x28, &x28, &x14); 101 | 102 | secp256k1_scalar_sqr(&x56, &x28); 103 | for (i = 0; i < 27; i++) { 104 | secp256k1_scalar_sqr(&x56, &x56); 105 | } 106 | secp256k1_scalar_mul(&x56, &x56, &x28); 107 | 108 | secp256k1_scalar_sqr(&x112, &x56); 109 | for (i = 0; i < 55; i++) { 110 | secp256k1_scalar_sqr(&x112, &x112); 111 | } 112 | secp256k1_scalar_mul(&x112, &x112, &x56); 113 | 114 | secp256k1_scalar_sqr(&x126, &x112); 115 | for (i = 0; i < 13; i++) { 116 | secp256k1_scalar_sqr(&x126, &x126); 117 | } 118 | secp256k1_scalar_mul(&x126, &x126, &x14); 119 | 120 | /* Then accumulate the final result (t starts at x126). */ 121 | t = &x126; 122 | for (i = 0; i < 3; i++) { 123 | secp256k1_scalar_sqr(t, t); 124 | } 125 | secp256k1_scalar_mul(t, t, &u5); /* 101 */ 126 | for (i = 0; i < 4; i++) { /* 0 */ 127 | secp256k1_scalar_sqr(t, t); 128 | } 129 | secp256k1_scalar_mul(t, t, &x3); /* 111 */ 130 | for (i = 0; i < 4; i++) { /* 0 */ 131 | secp256k1_scalar_sqr(t, t); 132 | } 133 | secp256k1_scalar_mul(t, t, &u5); /* 101 */ 134 | for (i = 0; i < 5; i++) { /* 0 */ 135 | secp256k1_scalar_sqr(t, t); 136 | } 137 | secp256k1_scalar_mul(t, t, &u11); /* 1011 */ 138 | for (i = 0; i < 4; i++) { 139 | secp256k1_scalar_sqr(t, t); 140 | } 141 | secp256k1_scalar_mul(t, t, &u11); /* 1011 */ 142 | for (i = 0; i < 4; i++) { /* 0 */ 143 | secp256k1_scalar_sqr(t, t); 144 | } 145 | secp256k1_scalar_mul(t, t, &x3); /* 111 */ 146 | for (i = 0; i < 5; i++) { /* 00 */ 147 | secp256k1_scalar_sqr(t, t); 148 | } 149 | secp256k1_scalar_mul(t, t, &x3); /* 111 */ 150 | for (i = 0; i < 6; i++) { /* 00 */ 151 | secp256k1_scalar_sqr(t, t); 152 | } 153 | secp256k1_scalar_mul(t, t, &u13); /* 1101 */ 154 | for (i = 0; i < 4; i++) { /* 0 */ 155 | secp256k1_scalar_sqr(t, t); 156 | } 157 | secp256k1_scalar_mul(t, t, &u5); /* 101 */ 158 | for (i = 0; i < 3; i++) { 159 | secp256k1_scalar_sqr(t, t); 160 | } 161 | secp256k1_scalar_mul(t, t, &x3); /* 111 */ 162 | for (i = 0; i < 5; i++) { /* 0 */ 163 | secp256k1_scalar_sqr(t, t); 164 | } 165 | secp256k1_scalar_mul(t, t, &u9); /* 1001 */ 166 | for (i = 0; i < 6; i++) { /* 000 */ 167 | secp256k1_scalar_sqr(t, t); 168 | } 169 | secp256k1_scalar_mul(t, t, &u5); /* 101 */ 170 | for (i = 0; i < 10; i++) { /* 0000000 */ 171 | secp256k1_scalar_sqr(t, t); 172 | } 173 | secp256k1_scalar_mul(t, t, &x3); /* 111 */ 174 | for (i = 0; i < 4; i++) { /* 0 */ 175 | secp256k1_scalar_sqr(t, t); 176 | } 177 | secp256k1_scalar_mul(t, t, &x3); /* 111 */ 178 | for (i = 0; i < 9; i++) { /* 0 */ 179 | secp256k1_scalar_sqr(t, t); 180 | } 181 | secp256k1_scalar_mul(t, t, &x8); /* 11111111 */ 182 | for (i = 0; i < 5; i++) { /* 0 */ 183 | secp256k1_scalar_sqr(t, t); 184 | } 185 | secp256k1_scalar_mul(t, t, &u9); /* 1001 */ 186 | for (i = 0; i < 6; i++) { /* 00 */ 187 | secp256k1_scalar_sqr(t, t); 188 | } 189 | secp256k1_scalar_mul(t, t, &u11); /* 1011 */ 190 | for (i = 0; i < 4; i++) { 191 | secp256k1_scalar_sqr(t, t); 192 | } 193 | secp256k1_scalar_mul(t, t, &u13); /* 1101 */ 194 | for (i = 0; i < 5; i++) { 195 | secp256k1_scalar_sqr(t, t); 196 | } 197 | secp256k1_scalar_mul(t, t, &x2); /* 11 */ 198 | for (i = 0; i < 6; i++) { /* 00 */ 199 | secp256k1_scalar_sqr(t, t); 200 | } 201 | secp256k1_scalar_mul(t, t, &u13); /* 1101 */ 202 | for (i = 0; i < 10; i++) { /* 000000 */ 203 | secp256k1_scalar_sqr(t, t); 204 | } 205 | secp256k1_scalar_mul(t, t, &u13); /* 1101 */ 206 | for (i = 0; i < 4; i++) { 207 | secp256k1_scalar_sqr(t, t); 208 | } 209 | secp256k1_scalar_mul(t, t, &u9); /* 1001 */ 210 | for (i = 0; i < 6; i++) { /* 00000 */ 211 | secp256k1_scalar_sqr(t, t); 212 | } 213 | secp256k1_scalar_mul(t, t, x); /* 1 */ 214 | for (i = 0; i < 8; i++) { /* 00 */ 215 | secp256k1_scalar_sqr(t, t); 216 | } 217 | secp256k1_scalar_mul(r, t, &x6); /* 111111 */ 218 | } 219 | 220 | SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { 221 | return !(a->d[0] & 1); 222 | } 223 | #endif 224 | 225 | static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { 226 | #define USE_SCALAR_INV_BUILTIN 227 | #if defined(USE_SCALAR_INV_BUILTIN) 228 | secp256k1_scalar_inverse(r, x); 229 | #elif defined(USE_SCALAR_INV_NUM) 230 | unsigned char b[32]; 231 | secp256k1_num n, m; 232 | secp256k1_scalar t = *x; 233 | secp256k1_scalar_get_b32(b, &t); 234 | secp256k1_num_set_bin(&n, b, 32); 235 | secp256k1_scalar_order_get_num(&m); 236 | secp256k1_num_mod_inverse(&n, &n, &m); 237 | secp256k1_num_get_bin(b, 32, &n); 238 | secp256k1_scalar_set_b32(r, b, NULL); 239 | /* Verify that the inverse was computed correctly, without GMP code. */ 240 | secp256k1_scalar_mul(&t, &t, r); 241 | CHECK(secp256k1_scalar_is_one(&t)); 242 | #else 243 | #error "Please select scalar inverse implementation" 244 | #endif 245 | } 246 | 247 | #ifdef USE_ENDOMORPHISM 248 | #if defined(EXHAUSTIVE_TEST_ORDER) 249 | /** 250 | * Find k1 and k2 given k, such that k1 + k2 * lambda == k mod n; unlike in the 251 | * full case we don't bother making k1 and k2 be small, we just want them to be 252 | * nontrivial to get full test coverage for the exhaustive tests. We therefore 253 | * (arbitrarily) set k2 = k + 5 and k1 = k - k2 * lambda. 254 | */ 255 | static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { 256 | *r2 = (*a + 5) % EXHAUSTIVE_TEST_ORDER; 257 | *r1 = (*a + (EXHAUSTIVE_TEST_ORDER - *r2) * EXHAUSTIVE_TEST_LAMBDA) % EXHAUSTIVE_TEST_ORDER; 258 | } 259 | #else 260 | /** 261 | * The Secp256k1 curve has an endomorphism, where lambda * (x, y) = (beta * x, y), where 262 | * lambda is {0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a, 263 | * 0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78,0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72} 264 | * 265 | * "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm 266 | * (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1 267 | * and k2 have a small size. 268 | * It relies on constants a1, b1, a2, b2. These constants for the value of lambda above are: 269 | * 270 | * - a1 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} 271 | * - b1 = -{0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3} 272 | * - a2 = {0x01,0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8} 273 | * - b2 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} 274 | * 275 | * The algorithm then computes c1 = round(b1 * k / n) and c2 = round(b2 * k / n), and gives 276 | * k1 = k - (c1*a1 + c2*a2) and k2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and 277 | * compute k1 as k - k2 * lambda, avoiding the need for constants a1 and a2. 278 | * 279 | * g1, g2 are precomputed constants used to replace division with a rounded multiplication 280 | * when decomposing the scalar for an endomorphism-based point multiplication. 281 | * 282 | * The possibility of using precomputed estimates is mentioned in "Guide to Elliptic Curve 283 | * Cryptography" (Hankerson, Menezes, Vanstone) in section 3.5. 284 | * 285 | * The derivation is described in the paper "Efficient Software Implementation of Public-Key 286 | * Cryptography on Sensor Networks Using the MSP430X Microcontroller" (Gouvea, Oliveira, Lopez), 287 | * Section 4.3 (here we use a somewhat higher-precision estimate): 288 | * d = a1*b2 - b1*a2 289 | * g1 = round((2^272)*b2/d) 290 | * g2 = round((2^272)*b1/d) 291 | * 292 | * (Note that 'd' is also equal to the curve order here because [a1,b1] and [a2,b2] are found 293 | * as outputs of the Extended Euclidean Algorithm on inputs 'order' and 'lambda'). 294 | * 295 | * The function below splits a in r1 and r2, such that r1 + lambda * r2 == a (mod order). 296 | */ 297 | 298 | static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { 299 | secp256k1_scalar c1, c2; 300 | static const secp256k1_scalar minus_lambda = SECP256K1_SCALAR_CONST( 301 | 0xAC9C52B3UL, 0x3FA3CF1FUL, 0x5AD9E3FDUL, 0x77ED9BA4UL, 302 | 0xA880B9FCUL, 0x8EC739C2UL, 0xE0CFC810UL, 0xB51283CFUL 303 | ); 304 | static const secp256k1_scalar minus_b1 = SECP256K1_SCALAR_CONST( 305 | 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 306 | 0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C3UL 307 | ); 308 | static const secp256k1_scalar minus_b2 = SECP256K1_SCALAR_CONST( 309 | 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 310 | 0x8A280AC5UL, 0x0774346DUL, 0xD765CDA8UL, 0x3DB1562CUL 311 | ); 312 | static const secp256k1_scalar g1 = SECP256K1_SCALAR_CONST( 313 | 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00003086UL, 314 | 0xD221A7D4UL, 0x6BCDE86CUL, 0x90E49284UL, 0xEB153DABUL 315 | ); 316 | static const secp256k1_scalar g2 = SECP256K1_SCALAR_CONST( 317 | 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x0000E443UL, 318 | 0x7ED6010EUL, 0x88286F54UL, 0x7FA90ABFUL, 0xE4C42212UL 319 | ); 320 | VERIFY_CHECK(r1 != a); 321 | VERIFY_CHECK(r2 != a); 322 | /* these _var calls are constant time since the shift amount is constant */ 323 | secp256k1_scalar_mul_shift_var(&c1, a, &g1, 272); 324 | secp256k1_scalar_mul_shift_var(&c2, a, &g2, 272); 325 | secp256k1_scalar_mul(&c1, &c1, &minus_b1); 326 | secp256k1_scalar_mul(&c2, &c2, &minus_b2); 327 | secp256k1_scalar_add(r2, &c1, &c2); 328 | secp256k1_scalar_mul(r1, r2, &minus_lambda); 329 | secp256k1_scalar_add(r1, r1, a); 330 | } 331 | #endif 332 | #endif 333 | 334 | #endif /* SECP256K1_SCALAR_IMPL_H */ 335 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | -------------------------------------------------------------------------------- /src/secp256k1/src/scalar_low_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_SCALAR_REPR_IMPL_H 8 | #define SECP256K1_SCALAR_REPR_IMPL_H 9 | 10 | #include "../../../../../../Downloads/bitcoin-master/src/secp256k1/src/scalar.h" 11 | 12 | #include 13 | 14 | SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { 15 | return !(*a & 1); 16 | } 17 | 18 | SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { *r = 0; } 19 | SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { *r = v; } 20 | 21 | SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { 22 | if (offset < 32) 23 | return ((*a >> offset) & ((((uint32_t)1) << count) - 1)); 24 | else 25 | return 0; 26 | } 27 | 28 | SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { 29 | return secp256k1_scalar_get_bits(a, offset, count); 30 | } 31 | 32 | SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; } 33 | 34 | static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { 35 | *r = (*a + *b) % EXHAUSTIVE_TEST_ORDER; 36 | return *r < *b; 37 | } 38 | 39 | static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { 40 | if (flag && bit < 32) 41 | *r += (1 << bit); 42 | #ifdef VERIFY 43 | VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); 44 | #endif 45 | } 46 | 47 | static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { 48 | const int base = 0x100 % EXHAUSTIVE_TEST_ORDER; 49 | int i; 50 | *r = 0; 51 | for (i = 0; i < 32; i++) { 52 | *r = ((*r * base) + b32[i]) % EXHAUSTIVE_TEST_ORDER; 53 | } 54 | /* just deny overflow, it basically always happens */ 55 | if (overflow) *overflow = 0; 56 | } 57 | 58 | static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { 59 | memset(bin, 0, 32); 60 | bin[28] = *a >> 24; bin[29] = *a >> 16; bin[30] = *a >> 8; bin[31] = *a; 61 | } 62 | 63 | SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { 64 | return *a == 0; 65 | } 66 | 67 | static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { 68 | if (*a == 0) { 69 | *r = 0; 70 | } else { 71 | *r = EXHAUSTIVE_TEST_ORDER - *a; 72 | } 73 | } 74 | 75 | SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { 76 | return *a == 1; 77 | } 78 | 79 | static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { 80 | return *a > EXHAUSTIVE_TEST_ORDER / 2; 81 | } 82 | 83 | static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { 84 | if (flag) secp256k1_scalar_negate(r, r); 85 | return flag ? -1 : 1; 86 | } 87 | 88 | static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { 89 | *r = (*a * *b) % EXHAUSTIVE_TEST_ORDER; 90 | } 91 | 92 | static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { 93 | int ret; 94 | VERIFY_CHECK(n > 0); 95 | VERIFY_CHECK(n < 16); 96 | ret = *r & ((1 << n) - 1); 97 | *r >>= n; 98 | return ret; 99 | } 100 | 101 | static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { 102 | *r = (*a * *a) % EXHAUSTIVE_TEST_ORDER; 103 | } 104 | 105 | static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { 106 | *r1 = *a; 107 | *r2 = 0; 108 | } 109 | 110 | SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { 111 | return *a == *b; 112 | } 113 | 114 | #endif /* SECP256K1_SCALAR_REPR_IMPL_H */ 115 | -------------------------------------------------------------------------------- /src/secp256k1/src/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 | #if defined HAVE_CONFIG_H 11 | #include "libsecp256k1-config.h" 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | typedef struct { 19 | void (*fn)(const char *text, void* data); 20 | const void* data; 21 | } secp256k1_callback; 22 | 23 | static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * const cb, const char * const text) { 24 | cb->fn(text, (void*)cb->data); 25 | } 26 | 27 | #ifdef DETERMINISTIC 28 | #define TEST_FAILURE(msg) do { \ 29 | fprintf(stderr, "%s\n", msg); \ 30 | abort(); \ 31 | } while(0); 32 | #else 33 | #define TEST_FAILURE(msg) do { \ 34 | fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \ 35 | abort(); \ 36 | } while(0) 37 | #endif 38 | 39 | #ifdef HAVE_BUILTIN_EXPECT 40 | #define EXPECT(x,c) __builtin_expect((x),(c)) 41 | #else 42 | #define EXPECT(x,c) (x) 43 | #endif 44 | 45 | #ifdef DETERMINISTIC 46 | #define CHECK(cond) do { \ 47 | if (EXPECT(!(cond), 0)) { \ 48 | TEST_FAILURE("test condition failed"); \ 49 | } \ 50 | } while(0) 51 | #else 52 | #define CHECK(cond) do { \ 53 | if (EXPECT(!(cond), 0)) { \ 54 | TEST_FAILURE("test condition failed: " #cond); \ 55 | } \ 56 | } while(0) 57 | #endif 58 | 59 | /* Like assert(), but when VERIFY is defined, and side-effect safe. */ 60 | #if defined(COVERAGE) 61 | #define VERIFY_CHECK(check) 62 | #define VERIFY_SETUP(stmt) 63 | #elif defined(VERIFY) 64 | #define VERIFY_CHECK CHECK 65 | #define VERIFY_SETUP(stmt) do { stmt; } while(0) 66 | #else 67 | #define VERIFY_CHECK(cond) do { (void)(cond); } while(0) 68 | #define VERIFY_SETUP(stmt) 69 | #endif 70 | 71 | static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_t size) { 72 | void *ret = malloc(size); 73 | if (ret == NULL) { 74 | secp256k1_callback_call(cb, "Out of memory"); 75 | } 76 | return ret; 77 | } 78 | 79 | /* Macro for restrict, when available and not in a VERIFY build. */ 80 | #if defined(SECP256K1_BUILD) && defined(VERIFY) 81 | # define SECP256K1_RESTRICT 82 | #else 83 | # if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) 84 | # if SECP256K1_GNUC_PREREQ(3,0) 85 | # define SECP256K1_RESTRICT __restrict__ 86 | # elif (defined(_MSC_VER) && _MSC_VER >= 1400) 87 | # define SECP256K1_RESTRICT __restrict 88 | # else 89 | # define SECP256K1_RESTRICT 90 | # endif 91 | # else 92 | # define SECP256K1_RESTRICT restrict 93 | # endif 94 | #endif 95 | 96 | #if defined(_WIN32) 97 | # define I64FORMAT "I64d" 98 | # define I64uFORMAT "I64u" 99 | #else 100 | # define I64FORMAT "lld" 101 | # define I64uFORMAT "llu" 102 | #endif 103 | 104 | #if defined(HAVE___INT128) 105 | # if defined(__GNUC__) 106 | # define SECP256K1_GNUC_EXT __extension__ 107 | # else 108 | # define SECP256K1_GNUC_EXT 109 | # endif 110 | SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; 111 | #endif 112 | 113 | #endif /* SECP256K1_UTIL_H */ 114 | --------------------------------------------------------------------------------