├── .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 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
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 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
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 | 
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 |
--------------------------------------------------------------------------------