├── .gitignore ├── CMakeLists.txt ├── README.md ├── bitcoin_test.cpp ├── bitcoin_test.hpp ├── license.txt ├── main.cpp ├── makefile ├── secp256k1 ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── COPYING ├── Makefile.am ├── README.md ├── TODO ├── autogen.sh ├── build-aux │ └── m4 │ │ ├── ax_jni_include_dir.m4 │ │ ├── ax_prog_cc_for_build.m4 │ │ └── bitcoin_secp.m4 ├── configure.ac ├── contrib │ ├── lax_der_parsing.c │ ├── lax_der_parsing.h │ ├── lax_der_privatekey_parsing.c │ └── lax_der_privatekey_parsing.h ├── include │ ├── secp256k1.h │ ├── secp256k1_ecdh.h │ ├── secp256k1_multiset.h │ └── secp256k1_recovery.h ├── libsecp256k1.pc.in ├── obj │ └── .gitignore ├── sage │ ├── group_prover.sage │ ├── secp256k1.sage │ └── weierstrass_prover.sage └── src │ ├── asm │ └── field_10x26_arm.s │ ├── basic-config.h │ ├── bench.h │ ├── bench_ecdh.c │ ├── bench_internal.c │ ├── bench_multiset.c │ ├── bench_recover.c │ ├── bench_sign.c │ ├── bench_verify.c │ ├── ecdsa.h │ ├── ecdsa_impl.h │ ├── eckey.h │ ├── eckey_impl.h │ ├── ecmult.h │ ├── ecmult_const.h │ ├── ecmult_const_impl.h │ ├── ecmult_gen.h │ ├── ecmult_gen_impl.h │ ├── ecmult_impl.h │ ├── field.h │ ├── field_10x26.h │ ├── field_10x26_impl.h │ ├── field_5x52.h │ ├── field_5x52_asm_impl.h │ ├── field_5x52_impl.h │ ├── field_5x52_int128_impl.h │ ├── field_impl.h │ ├── gen_context.c │ ├── group.h │ ├── group_impl.h │ ├── hash.h │ ├── hash_impl.h │ ├── java │ ├── org_bitcoin_NativeSecp256k1.c │ ├── org_bitcoin_NativeSecp256k1.h │ ├── org_bitcoin_Secp256k1Context.c │ └── org_bitcoin_Secp256k1Context.h │ ├── libsecp256k1-config.h.cmake.in │ ├── modules │ ├── ecdh │ │ ├── Makefile.am.include │ │ ├── main_impl.h │ │ └── tests_impl.h │ ├── multiset │ │ ├── Makefile.am.include │ │ ├── README.md │ │ ├── main_impl.h │ │ └── tests_impl.h │ └── recovery │ │ ├── Makefile.am.include │ │ ├── main_impl.h │ │ └── tests_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 │ ├── testrand.h │ ├── testrand_impl.h │ ├── tests.c │ ├── tests_exhaustive.c │ └── util.h ├── src ├── addresses.cpp ├── addresses.hpp ├── base.cpp ├── base.hpp ├── block.cpp ├── block.hpp ├── bloom_filter.cpp ├── bloom_filter.hpp ├── bloom_lookup.cpp ├── bloom_lookup.hpp ├── chain.cpp ├── chain.hpp ├── daemon.cpp ├── daemon.hpp ├── forks.cpp ├── forks.hpp ├── header.cpp ├── header.hpp ├── info.cpp ├── info.hpp ├── interpreter.cpp ├── interpreter.hpp ├── key.cpp ├── key.hpp ├── mem_pool.cpp ├── mem_pool.hpp ├── message.cpp ├── message.hpp ├── mnemonics.hpp ├── monitor.cpp ├── monitor.hpp ├── node.cpp ├── node.hpp ├── output.cpp ├── output.hpp ├── outputs.cpp ├── outputs.hpp ├── peer.cpp ├── peer.hpp ├── profiler_setup.hpp ├── requests.cpp ├── requests.hpp ├── seeds.hpp ├── transaction.cpp └── transaction.hpp └── tests └── 06128e87be8b1b4dea47a7247d5528d2702c96826c7a648497e773b800000000.pending_block /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .objects 3 | .include 4 | test 5 | test.debug 6 | bitcoin 7 | bitcoin.debug 8 | build_secp256k1 9 | .gdb* 10 | chain_test 11 | test_outputs 12 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # NextCash Bitcoin Cash 2 | 3 | cmake_minimum_required(VERSION 3.4.1) 4 | 5 | # Setup SECP256K1 library 6 | set( secp256k1_lib_src_dir secp256k1 ) 7 | set( secp256k1_lib_build_dir secp256k1/build ) 8 | 9 | add_subdirectory( ${secp256k1_lib_src_dir} 10 | ${secp256k1_lib_build_dir} ) 11 | 12 | 13 | include_directories( ../nextcash/src/base 14 | ../nextcash/src/io 15 | ../nextcash/src/crypto 16 | ../nextcash/src/dev 17 | secp256k1/include 18 | src 19 | . ) 20 | 21 | add_library( bitcoin STATIC SHARED 22 | src/base.cpp 23 | src/block.cpp 24 | src/bloom_filter.cpp 25 | src/bloom_lookup.cpp 26 | src/chain.cpp 27 | src/daemon.cpp 28 | src/forks.cpp 29 | src/header.cpp 30 | src/info.cpp 31 | src/interpreter.cpp 32 | src/key.cpp 33 | src/mem_pool.cpp 34 | src/message.cpp 35 | src/monitor.cpp 36 | src/node.cpp 37 | src/output.cpp 38 | src/outputs.cpp 39 | src/peer.cpp 40 | src/requests.cpp 41 | src/transaction.cpp 42 | bitcoin_test.cpp ) 43 | 44 | # Link NextCash and SECP256K1 libraries 45 | target_link_libraries( bitcoin nextcash secp256k1 ) 46 | 47 | set_property( TARGET bitcoin PROPERTY CXX_STANDARD 11 ) 48 | set_property( TARGET bitcoin PROPERTY CXX_STANDARD_REQUIRED ON ) 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bitcoin 2 | Fresh Bitcoin Cash/SV Implementation 3 | 4 | This is a new Bitcoin Cash/SV implementation built almost completely from the ground up. 5 | It currently uses Pieter Wuille's secp256k1 implementation. Copyright (c) 2013 Pieter Wuille. 6 | 7 | Support for selecting the Bitcoin SV chain has recently been added. 8 | 9 | It is currently fully functional. There is an SPV mode on which an Android wallet is being built. 10 | 11 | With it I hope to try performance improvements and to also add security to Bitcoin through more diverse implementations. 12 | 13 | Keep in mind it is still in early development and still needs complete consensus rules verification, performance improvements, code cleanup, and many tests. 14 | 15 | Current notable features 16 | * Multi-threaded design from the ground up 17 | * Multi-threaded block validation 18 | * Multi-threaded mempool acceptance 19 | * Multi-threaded UTXO set saving 20 | * UTXO set design in which 10 million transactions can be indexed in memory using around 1 GB. 21 | * Initial block download with pre-approved block hash below which blocks will not be validated, and just used to update the UTXO set 22 | * Custom requests interface for quering block chain data through TCP/IP. 23 | 24 | Future features 25 | * Graphene 26 | 27 | Please feel free to send comments. 28 | 29 | Build/install instructions are in the wiki of this repo. 30 | https://github.com/nextcashtech/bitcoin/wiki/Compiler-Setup 31 | -------------------------------------------------------------------------------- /bitcoin_test.hpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2017-2018 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | 9 | namespace BitCoin 10 | { 11 | bool test(); 12 | } 13 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2017-2018 NextCash, LLC 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, 6 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 7 | furnished to do so, subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or 10 | substantial portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 13 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 16 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | -------------------------------------------------------------------------------- /secp256k1/.gitignore: -------------------------------------------------------------------------------- 1 | bench_inv 2 | bench_ecdh 3 | bench_ecmult 4 | bench_multiset 5 | bench_sign 6 | bench_verify 7 | bench_schnorr_verify 8 | bench_recover 9 | bench_internal 10 | tests 11 | exhaustive_tests 12 | gen_context 13 | *.exe 14 | *.so 15 | *.a 16 | !.gitignore 17 | 18 | Makefile 19 | configure 20 | .libs/ 21 | Makefile.in 22 | aclocal.m4 23 | autom4te.cache/ 24 | config.log 25 | config.status 26 | *.tar.gz 27 | *.la 28 | libtool 29 | .deps/ 30 | .dirstamp 31 | *.lo 32 | *.o 33 | *~ 34 | src/libsecp256k1-config.h 35 | src/libsecp256k1-config.h.in 36 | src/ecmult_static_context.h 37 | build-aux/config.guess 38 | build-aux/config.sub 39 | build-aux/depcomp 40 | build-aux/install-sh 41 | build-aux/ltmain.sh 42 | build-aux/m4/libtool.m4 43 | build-aux/m4/lt~obsolete.m4 44 | build-aux/m4/ltoptions.m4 45 | build-aux/m4/ltsugar.m4 46 | build-aux/m4/ltversion.m4 47 | build-aux/missing 48 | build-aux/compile 49 | build-aux/test-driver 50 | src/stamp-h1 51 | libsecp256k1.pc 52 | -------------------------------------------------------------------------------- /secp256k1/.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | sudo: false 3 | addons: 4 | apt: 5 | packages: libgmp-dev 6 | compiler: 7 | - clang 8 | - gcc 9 | cache: 10 | directories: 11 | - src/java/guava/ 12 | env: 13 | global: 14 | - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no RECOVERY=no EXPERIMENTAL=no JNI=no 15 | - GUAVA_URL=https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar GUAVA_JAR=src/java/guava/guava-18.0.jar 16 | matrix: 17 | - SCALAR=32bit RECOVERY=yes 18 | - SCALAR=32bit FIELD=32bit ECDH=yes EXPERIMENTAL=yes 19 | - SCALAR=64bit 20 | - FIELD=64bit RECOVERY=yes 21 | - FIELD=64bit ENDOMORPHISM=yes 22 | - FIELD=64bit ENDOMORPHISM=yes ECDH=yes EXPERIMENTAL=yes 23 | - FIELD=64bit ASM=x86_64 24 | - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64 25 | - FIELD=32bit ENDOMORPHISM=yes 26 | - BIGNUM=no 27 | - BIGNUM=no ENDOMORPHISM=yes RECOVERY=yes EXPERIMENTAL=yes 28 | - BIGNUM=no STATICPRECOMPUTATION=no 29 | - BUILD=distcheck 30 | - EXTRAFLAGS=CPPFLAGS=-DDETERMINISTIC 31 | - EXTRAFLAGS=CFLAGS=-O0 32 | - BUILD=check-java JNI=yes ECDH=yes EXPERIMENTAL=yes 33 | matrix: 34 | fast_finish: true 35 | include: 36 | - compiler: clang 37 | env: HOST=i686-linux-gnu ENDOMORPHISM=yes 38 | addons: 39 | apt: 40 | packages: 41 | - gcc-multilib 42 | - libgmp-dev:i386 43 | - compiler: clang 44 | env: HOST=i686-linux-gnu 45 | addons: 46 | apt: 47 | packages: 48 | - gcc-multilib 49 | - compiler: gcc 50 | env: HOST=i686-linux-gnu ENDOMORPHISM=yes 51 | addons: 52 | apt: 53 | packages: 54 | - gcc-multilib 55 | - compiler: gcc 56 | env: HOST=i686-linux-gnu 57 | addons: 58 | apt: 59 | packages: 60 | - gcc-multilib 61 | - libgmp-dev:i386 62 | before_install: mkdir -p `dirname $GUAVA_JAR` 63 | install: if [ ! -f $GUAVA_JAR ]; then wget $GUAVA_URL -O $GUAVA_JAR; fi 64 | before_script: ./autogen.sh 65 | script: 66 | - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi 67 | - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi 68 | - ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-recovery=$RECOVERY --enable-jni=$JNI $EXTRAFLAGS $USE_HOST && make -j2 $BUILD 69 | os: linux 70 | -------------------------------------------------------------------------------- /secp256k1/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SECP256K1 Implementation 2 | 3 | cmake_minimum_required(VERSION 3.4.1) 4 | 5 | 6 | # Use Basic Configuration 7 | add_definitions( -DUSE_NUM_NONE ) 8 | add_definitions( -DUSE_FIELD_INV_BUILTIN ) 9 | add_definitions( -DUSE_SCALAR_INV_BUILTIN ) 10 | add_definitions( -DUSE_FIELD_10X26 ) 11 | add_definitions( -DUSE_SCALAR_8X32 ) 12 | 13 | include_directories( ./ include ) 14 | 15 | add_library( secp256k1 STATIC SHARED 16 | src/secp256k1.c ) 17 | -------------------------------------------------------------------------------- /secp256k1/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Pieter Wuille 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /secp256k1/Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I build-aux/m4 2 | 3 | lib_LTLIBRARIES = libsecp256k1.la 4 | if USE_JNI 5 | JNI_LIB = libsecp256k1_jni.la 6 | noinst_LTLIBRARIES = $(JNI_LIB) 7 | else 8 | JNI_LIB = 9 | endif 10 | include_HEADERS = include/secp256k1.h 11 | noinst_HEADERS = 12 | noinst_HEADERS += src/scalar.h 13 | noinst_HEADERS += src/scalar_4x64.h 14 | noinst_HEADERS += src/scalar_8x32.h 15 | noinst_HEADERS += src/scalar_low.h 16 | noinst_HEADERS += src/scalar_impl.h 17 | noinst_HEADERS += src/scalar_4x64_impl.h 18 | noinst_HEADERS += src/scalar_8x32_impl.h 19 | noinst_HEADERS += src/scalar_low_impl.h 20 | noinst_HEADERS += src/group.h 21 | noinst_HEADERS += src/group_impl.h 22 | noinst_HEADERS += src/num_gmp.h 23 | noinst_HEADERS += src/num_gmp_impl.h 24 | noinst_HEADERS += src/ecdsa.h 25 | noinst_HEADERS += src/ecdsa_impl.h 26 | noinst_HEADERS += src/eckey.h 27 | noinst_HEADERS += src/eckey_impl.h 28 | noinst_HEADERS += src/ecmult.h 29 | noinst_HEADERS += src/ecmult_impl.h 30 | noinst_HEADERS += src/ecmult_const.h 31 | noinst_HEADERS += src/ecmult_const_impl.h 32 | noinst_HEADERS += src/ecmult_gen.h 33 | noinst_HEADERS += src/ecmult_gen_impl.h 34 | noinst_HEADERS += src/num.h 35 | noinst_HEADERS += src/num_impl.h 36 | noinst_HEADERS += src/field_10x26.h 37 | noinst_HEADERS += src/field_10x26_impl.h 38 | noinst_HEADERS += src/field_5x52.h 39 | noinst_HEADERS += src/field_5x52_impl.h 40 | noinst_HEADERS += src/field_5x52_int128_impl.h 41 | noinst_HEADERS += src/field_5x52_asm_impl.h 42 | noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h 43 | noinst_HEADERS += src/java/org_bitcoin_Secp256k1Context.h 44 | noinst_HEADERS += src/util.h 45 | noinst_HEADERS += src/testrand.h 46 | noinst_HEADERS += src/testrand_impl.h 47 | noinst_HEADERS += src/hash.h 48 | noinst_HEADERS += src/hash_impl.h 49 | noinst_HEADERS += src/field.h 50 | noinst_HEADERS += src/field_impl.h 51 | noinst_HEADERS += src/bench.h 52 | noinst_HEADERS += contrib/lax_der_parsing.h 53 | noinst_HEADERS += contrib/lax_der_parsing.c 54 | noinst_HEADERS += contrib/lax_der_privatekey_parsing.h 55 | noinst_HEADERS += contrib/lax_der_privatekey_parsing.c 56 | 57 | if USE_EXTERNAL_ASM 58 | COMMON_LIB = libsecp256k1_common.la 59 | noinst_LTLIBRARIES = $(COMMON_LIB) 60 | else 61 | COMMON_LIB = 62 | endif 63 | 64 | pkgconfigdir = $(libdir)/pkgconfig 65 | pkgconfig_DATA = libsecp256k1.pc 66 | 67 | if USE_EXTERNAL_ASM 68 | if USE_ASM_ARM 69 | libsecp256k1_common_la_SOURCES = src/asm/field_10x26_arm.s 70 | endif 71 | endif 72 | 73 | libsecp256k1_la_SOURCES = src/secp256k1.c 74 | libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) 75 | libsecp256k1_la_LIBADD = $(JNI_LIB) $(SECP_LIBS) $(COMMON_LIB) 76 | 77 | libsecp256k1_jni_la_SOURCES = src/java/org_bitcoin_NativeSecp256k1.c src/java/org_bitcoin_Secp256k1Context.c 78 | libsecp256k1_jni_la_CPPFLAGS = -DSECP256K1_BUILD $(JNI_INCLUDES) 79 | 80 | noinst_PROGRAMS = 81 | if USE_BENCHMARK 82 | noinst_PROGRAMS += bench_verify bench_sign bench_internal 83 | bench_verify_SOURCES = src/bench_verify.c 84 | bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) 85 | bench_sign_SOURCES = src/bench_sign.c 86 | bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) 87 | bench_internal_SOURCES = src/bench_internal.c 88 | bench_internal_LDADD = $(SECP_LIBS) $(COMMON_LIB) 89 | bench_internal_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src $(SECP_INCLUDES) 90 | endif 91 | 92 | TESTS = 93 | if USE_TESTS 94 | noinst_PROGRAMS += tests 95 | tests_SOURCES = src/tests.c 96 | tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) 97 | if !ENABLE_COVERAGE 98 | tests_CPPFLAGS += -DVERIFY 99 | endif 100 | tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) 101 | tests_LDFLAGS = -static 102 | TESTS += tests 103 | endif 104 | 105 | if USE_EXHAUSTIVE_TESTS 106 | noinst_PROGRAMS += exhaustive_tests 107 | exhaustive_tests_SOURCES = src/tests_exhaustive.c 108 | exhaustive_tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src $(SECP_INCLUDES) 109 | if !ENABLE_COVERAGE 110 | exhaustive_tests_CPPFLAGS += -DVERIFY 111 | endif 112 | exhaustive_tests_LDADD = $(SECP_LIBS) 113 | exhaustive_tests_LDFLAGS = -static 114 | TESTS += exhaustive_tests 115 | endif 116 | 117 | JAVAROOT=src/java 118 | JAVAORG=org/bitcoin 119 | JAVA_GUAVA=$(srcdir)/$(JAVAROOT)/guava/guava-18.0.jar 120 | CLASSPATH_ENV=CLASSPATH=$(JAVA_GUAVA) 121 | JAVA_FILES= \ 122 | $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1.java \ 123 | $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Test.java \ 124 | $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Util.java \ 125 | $(JAVAROOT)/$(JAVAORG)/Secp256k1Context.java 126 | 127 | if USE_JNI 128 | 129 | $(JAVA_GUAVA): 130 | @echo Guava is missing. Fetch it via: \ 131 | wget https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar -O $(@) 132 | @false 133 | 134 | .stamp-java: $(JAVA_FILES) 135 | @echo Compiling $^ 136 | $(AM_V_at)$(CLASSPATH_ENV) javac $^ 137 | @touch $@ 138 | 139 | if USE_TESTS 140 | 141 | check-java: libsecp256k1.la $(JAVA_GUAVA) .stamp-java 142 | $(AM_V_at)java -Djava.library.path="./:./src:./src/.libs:.libs/" -cp "$(JAVA_GUAVA):$(JAVAROOT)" $(JAVAORG)/NativeSecp256k1Test 143 | 144 | endif 145 | endif 146 | 147 | if USE_ECMULT_STATIC_PRECOMPUTATION 148 | CPPFLAGS_FOR_BUILD +=-I$(top_srcdir) 149 | CFLAGS_FOR_BUILD += -Wall -Wextra -Wno-unused-function 150 | 151 | gen_context_OBJECTS = gen_context.o 152 | gen_context_BIN = gen_context$(BUILD_EXEEXT) 153 | gen_%.o: src/gen_%.c 154 | $(CC_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@ 155 | 156 | $(gen_context_BIN): $(gen_context_OBJECTS) 157 | $(CC_FOR_BUILD) $^ -o $@ 158 | 159 | $(libsecp256k1_la_OBJECTS): src/ecmult_static_context.h 160 | $(tests_OBJECTS): src/ecmult_static_context.h 161 | $(bench_internal_OBJECTS): src/ecmult_static_context.h 162 | 163 | src/ecmult_static_context.h: $(gen_context_BIN) 164 | ./$(gen_context_BIN) 165 | 166 | CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h $(JAVAROOT)/$(JAVAORG)/*.class .stamp-java 167 | endif 168 | 169 | EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h $(JAVA_FILES) 170 | 171 | if ENABLE_MODULE_ECDH 172 | include src/modules/ecdh/Makefile.am.include 173 | endif 174 | 175 | if ENABLE_MODULE_MULTISET 176 | include src/modules/multiset/Makefile.am.include 177 | endif 178 | 179 | if ENABLE_MODULE_RECOVERY 180 | include src/modules/recovery/Makefile.am.include 181 | endif 182 | -------------------------------------------------------------------------------- /secp256k1/README.md: -------------------------------------------------------------------------------- 1 | libsecp256k1 2 | ============ 3 | 4 | [![Build Status](https://travis-ci.org/bitcoin-core/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin-core/secp256k1) 5 | 6 | Optimized C library for EC operations on curve secp256k1. 7 | 8 | This library is a work in progress and is being used to research best practices. Use at your own risk. 9 | 10 | Features: 11 | * secp256k1 ECDSA signing/verification and key generation. 12 | * Adding/multiplying private/public keys. 13 | * Serialization/parsing of private keys, public keys, signatures. 14 | * Constant time, constant memory access signing and pubkey generation. 15 | * Derandomized DSA (via RFC6979 or with a caller provided function.) 16 | * Very efficient implementation. 17 | 18 | Implementation details 19 | ---------------------- 20 | 21 | * General 22 | * No runtime heap allocation. 23 | * Extensive testing infrastructure. 24 | * Structured to facilitate review and analysis. 25 | * Intended to be portable to any system with a C89 compiler and uint64_t support. 26 | * Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.") 27 | * Field operations 28 | * Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1). 29 | * Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys). 30 | * Using 10 26-bit limbs. 31 | * Field inverses and square roots using a sliding window over blocks of 1s (by Peter Dettman). 32 | * Scalar operations 33 | * Optimized implementation without data-dependent branches of arithmetic modulo the curve's order. 34 | * Using 4 64-bit limbs (relying on __int128 support in the compiler). 35 | * Using 8 32-bit limbs. 36 | * Group operations 37 | * Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7). 38 | * Use addition between points in Jacobian and affine coordinates where possible. 39 | * Use a unified addition/doubling formula where necessary to avoid data-dependent branches. 40 | * Point/x comparison without a field inversion by comparison in the Jacobian coordinate space. 41 | * Point multiplication for verification (a*P + b*G). 42 | * Use wNAF notation for point multiplicands. 43 | * Use a much larger window for multiples of G, using precomputed multiples. 44 | * Use Shamir's trick to do the multiplication with the public key and the generator simultaneously. 45 | * Optionally (off by default) use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones. 46 | * Point multiplication for signing 47 | * Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions. 48 | * Access the table with branch-free conditional moves so memory access is uniform. 49 | * No data-dependent branches 50 | * The precomputed tables add and eventually subtract points for which no known scalar (private key) is known, preventing even an attacker with control over the private key used to control the data internally. 51 | 52 | Build steps 53 | ----------- 54 | 55 | libsecp256k1 is built using autotools: 56 | 57 | $ ./autogen.sh 58 | $ ./configure 59 | $ make 60 | $ ./tests 61 | $ sudo make install # optional 62 | -------------------------------------------------------------------------------- /secp256k1/TODO: -------------------------------------------------------------------------------- 1 | * Unit tests for fieldelem/groupelem, including ones intended to 2 | trigger fieldelem's boundary cases. 3 | * Complete constant-time operations for signing/keygen 4 | -------------------------------------------------------------------------------- /secp256k1/autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | autoreconf -if --warnings=all 4 | -------------------------------------------------------------------------------- /secp256k1/build-aux/m4/ax_jni_include_dir.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_jni_include_dir.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_JNI_INCLUDE_DIR 8 | # 9 | # DESCRIPTION 10 | # 11 | # AX_JNI_INCLUDE_DIR finds include directories needed for compiling 12 | # programs using the JNI interface. 13 | # 14 | # JNI include directories are usually in the Java distribution. This is 15 | # deduced from the value of $JAVA_HOME, $JAVAC, or the path to "javac", in 16 | # that order. When this macro completes, a list of directories is left in 17 | # the variable JNI_INCLUDE_DIRS. 18 | # 19 | # Example usage follows: 20 | # 21 | # AX_JNI_INCLUDE_DIR 22 | # 23 | # for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS 24 | # do 25 | # CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" 26 | # done 27 | # 28 | # If you want to force a specific compiler: 29 | # 30 | # - at the configure.in level, set JAVAC=yourcompiler before calling 31 | # AX_JNI_INCLUDE_DIR 32 | # 33 | # - at the configure level, setenv JAVAC 34 | # 35 | # Note: This macro can work with the autoconf M4 macros for Java programs. 36 | # This particular macro is not part of the original set of macros. 37 | # 38 | # LICENSE 39 | # 40 | # Copyright (c) 2008 Don Anderson 41 | # 42 | # Copying and distribution of this file, with or without modification, are 43 | # permitted in any medium without royalty provided the copyright notice 44 | # and this notice are preserved. This file is offered as-is, without any 45 | # warranty. 46 | 47 | #serial 14 48 | 49 | AU_ALIAS([AC_JNI_INCLUDE_DIR], [AX_JNI_INCLUDE_DIR]) 50 | AC_DEFUN([AX_JNI_INCLUDE_DIR],[ 51 | 52 | JNI_INCLUDE_DIRS="" 53 | 54 | if test "x$JAVA_HOME" != x; then 55 | _JTOPDIR="$JAVA_HOME" 56 | else 57 | if test "x$JAVAC" = x; then 58 | JAVAC=javac 59 | fi 60 | AC_PATH_PROG([_ACJNI_JAVAC], [$JAVAC], [no]) 61 | if test "x$_ACJNI_JAVAC" = xno; then 62 | AC_MSG_WARN([cannot find JDK; try setting \$JAVAC or \$JAVA_HOME]) 63 | fi 64 | _ACJNI_FOLLOW_SYMLINKS("$_ACJNI_JAVAC") 65 | _JTOPDIR=`echo "$_ACJNI_FOLLOWED" | sed -e 's://*:/:g' -e 's:/[[^/]]*$::'` 66 | fi 67 | 68 | case "$host_os" in 69 | darwin*) # Apple Java headers are inside the Xcode bundle. 70 | macos_version=$(sw_vers -productVersion | sed -n -e 's/^@<:@0-9@:>@*.\(@<:@0-9@:>@*\).@<:@0-9@:>@*/\1/p') 71 | if @<:@ "$macos_version" -gt "7" @:>@; then 72 | _JTOPDIR="$(xcrun --show-sdk-path)/System/Library/Frameworks/JavaVM.framework" 73 | _JINC="$_JTOPDIR/Headers" 74 | else 75 | _JTOPDIR="/System/Library/Frameworks/JavaVM.framework" 76 | _JINC="$_JTOPDIR/Headers" 77 | fi 78 | ;; 79 | *) _JINC="$_JTOPDIR/include";; 80 | esac 81 | _AS_ECHO_LOG([_JTOPDIR=$_JTOPDIR]) 82 | _AS_ECHO_LOG([_JINC=$_JINC]) 83 | 84 | # On Mac OS X 10.6.4, jni.h is a symlink: 85 | # /System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/jni.h 86 | # -> ../../CurrentJDK/Headers/jni.h. 87 | AC_CACHE_CHECK(jni headers, ac_cv_jni_header_path, 88 | [ 89 | if test -f "$_JINC/jni.h"; then 90 | ac_cv_jni_header_path="$_JINC" 91 | JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path" 92 | else 93 | _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` 94 | if test -f "$_JTOPDIR/include/jni.h"; then 95 | ac_cv_jni_header_path="$_JTOPDIR/include" 96 | JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path" 97 | else 98 | ac_cv_jni_header_path=none 99 | fi 100 | fi 101 | ]) 102 | 103 | # get the likely subdirectories for system specific java includes 104 | case "$host_os" in 105 | bsdi*) _JNI_INC_SUBDIRS="bsdos";; 106 | freebsd*) _JNI_INC_SUBDIRS="freebsd";; 107 | darwin*) _JNI_INC_SUBDIRS="darwin";; 108 | linux*) _JNI_INC_SUBDIRS="linux genunix";; 109 | osf*) _JNI_INC_SUBDIRS="alpha";; 110 | solaris*) _JNI_INC_SUBDIRS="solaris";; 111 | mingw*) _JNI_INC_SUBDIRS="win32";; 112 | cygwin*) _JNI_INC_SUBDIRS="win32";; 113 | *) _JNI_INC_SUBDIRS="genunix";; 114 | esac 115 | 116 | if test "x$ac_cv_jni_header_path" != "xnone"; then 117 | # add any subdirectories that are present 118 | for JINCSUBDIR in $_JNI_INC_SUBDIRS 119 | do 120 | if test -d "$_JTOPDIR/include/$JINCSUBDIR"; then 121 | JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include/$JINCSUBDIR" 122 | fi 123 | done 124 | fi 125 | ]) 126 | 127 | # _ACJNI_FOLLOW_SYMLINKS 128 | # Follows symbolic links on , 129 | # finally setting variable _ACJNI_FOLLOWED 130 | # ---------------------------------------- 131 | AC_DEFUN([_ACJNI_FOLLOW_SYMLINKS],[ 132 | # find the include directory relative to the javac executable 133 | _cur="$1" 134 | while ls -ld "$_cur" 2>/dev/null | grep " -> " >/dev/null; do 135 | AC_MSG_CHECKING([symlink for $_cur]) 136 | _slink=`ls -ld "$_cur" | sed 's/.* -> //'` 137 | case "$_slink" in 138 | /*) _cur="$_slink";; 139 | # 'X' avoids triggering unwanted echo options. 140 | *) _cur=`echo "X$_cur" | sed -e 's/^X//' -e 's:[[^/]]*$::'`"$_slink";; 141 | esac 142 | AC_MSG_RESULT([$_cur]) 143 | done 144 | _ACJNI_FOLLOWED="$_cur" 145 | ])# _ACJNI 146 | -------------------------------------------------------------------------------- /secp256k1/build-aux/m4/ax_prog_cc_for_build.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_PROG_CC_FOR_BUILD 8 | # 9 | # DESCRIPTION 10 | # 11 | # This macro searches for a C compiler that generates native executables, 12 | # that is a C compiler that surely is not a cross-compiler. This can be 13 | # useful if you have to generate source code at compile-time like for 14 | # example GCC does. 15 | # 16 | # The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything 17 | # needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD). 18 | # The value of these variables can be overridden by the user by specifying 19 | # a compiler with an environment variable (like you do for standard CC). 20 | # 21 | # It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object 22 | # file extensions for the build platform, and GCC_FOR_BUILD to `yes' if 23 | # the compiler we found is GCC. All these variables but GCC_FOR_BUILD are 24 | # substituted in the Makefile. 25 | # 26 | # LICENSE 27 | # 28 | # Copyright (c) 2008 Paolo Bonzini 29 | # 30 | # Copying and distribution of this file, with or without modification, are 31 | # permitted in any medium without royalty provided the copyright notice 32 | # and this notice are preserved. This file is offered as-is, without any 33 | # warranty. 34 | 35 | #serial 8 36 | 37 | AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD]) 38 | AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl 39 | AC_REQUIRE([AC_PROG_CC])dnl 40 | AC_REQUIRE([AC_PROG_CPP])dnl 41 | AC_REQUIRE([AC_EXEEXT])dnl 42 | AC_REQUIRE([AC_CANONICAL_HOST])dnl 43 | 44 | dnl Use the standard macros, but make them use other variable names 45 | dnl 46 | pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl 47 | pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl 48 | pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl 49 | pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl 50 | pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl 51 | pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl 52 | pushdef([ac_cv_objext], ac_cv_build_objext)dnl 53 | pushdef([ac_exeext], ac_build_exeext)dnl 54 | pushdef([ac_objext], ac_build_objext)dnl 55 | pushdef([CC], CC_FOR_BUILD)dnl 56 | pushdef([CPP], CPP_FOR_BUILD)dnl 57 | pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl 58 | pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl 59 | pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl 60 | pushdef([host], build)dnl 61 | pushdef([host_alias], build_alias)dnl 62 | pushdef([host_cpu], build_cpu)dnl 63 | pushdef([host_vendor], build_vendor)dnl 64 | pushdef([host_os], build_os)dnl 65 | pushdef([ac_cv_host], ac_cv_build)dnl 66 | pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl 67 | pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl 68 | pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl 69 | pushdef([ac_cv_host_os], ac_cv_build_os)dnl 70 | pushdef([ac_cpp], ac_build_cpp)dnl 71 | pushdef([ac_compile], ac_build_compile)dnl 72 | pushdef([ac_link], ac_build_link)dnl 73 | 74 | save_cross_compiling=$cross_compiling 75 | save_ac_tool_prefix=$ac_tool_prefix 76 | cross_compiling=no 77 | ac_tool_prefix= 78 | 79 | AC_PROG_CC 80 | AC_PROG_CPP 81 | AC_EXEEXT 82 | 83 | ac_tool_prefix=$save_ac_tool_prefix 84 | cross_compiling=$save_cross_compiling 85 | 86 | dnl Restore the old definitions 87 | dnl 88 | popdef([ac_link])dnl 89 | popdef([ac_compile])dnl 90 | popdef([ac_cpp])dnl 91 | popdef([ac_cv_host_os])dnl 92 | popdef([ac_cv_host_vendor])dnl 93 | popdef([ac_cv_host_cpu])dnl 94 | popdef([ac_cv_host_alias])dnl 95 | popdef([ac_cv_host])dnl 96 | popdef([host_os])dnl 97 | popdef([host_vendor])dnl 98 | popdef([host_cpu])dnl 99 | popdef([host_alias])dnl 100 | popdef([host])dnl 101 | popdef([LDFLAGS])dnl 102 | popdef([CPPFLAGS])dnl 103 | popdef([CFLAGS])dnl 104 | popdef([CPP])dnl 105 | popdef([CC])dnl 106 | popdef([ac_objext])dnl 107 | popdef([ac_exeext])dnl 108 | popdef([ac_cv_objext])dnl 109 | popdef([ac_cv_exeext])dnl 110 | popdef([ac_cv_prog_cc_g])dnl 111 | popdef([ac_cv_prog_cc_cross])dnl 112 | popdef([ac_cv_prog_cc_works])dnl 113 | popdef([ac_cv_prog_gcc])dnl 114 | popdef([ac_cv_prog_CPP])dnl 115 | 116 | dnl Finally, set Makefile variables 117 | dnl 118 | BUILD_EXEEXT=$ac_build_exeext 119 | BUILD_OBJEXT=$ac_build_objext 120 | AC_SUBST(BUILD_EXEEXT)dnl 121 | AC_SUBST(BUILD_OBJEXT)dnl 122 | AC_SUBST([CFLAGS_FOR_BUILD])dnl 123 | AC_SUBST([CPPFLAGS_FOR_BUILD])dnl 124 | AC_SUBST([LDFLAGS_FOR_BUILD])dnl 125 | ]) 126 | -------------------------------------------------------------------------------- /secp256k1/build-aux/m4/bitcoin_secp.m4: -------------------------------------------------------------------------------- 1 | dnl libsecp25k1 helper checks 2 | AC_DEFUN([SECP_INT128_CHECK],[ 3 | has_int128=$ac_cv_type___int128 4 | ]) 5 | 6 | dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell. 7 | AC_DEFUN([SECP_64BIT_ASM_CHECK],[ 8 | AC_MSG_CHECKING(for x86_64 assembly availability) 9 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 10 | #include ]],[[ 11 | uint64_t a = 11, tmp; 12 | __asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); 13 | ]])],[has_64bit_asm=yes],[has_64bit_asm=no]) 14 | AC_MSG_RESULT([$has_64bit_asm]) 15 | ]) 16 | 17 | dnl 18 | AC_DEFUN([SECP_OPENSSL_CHECK],[ 19 | has_libcrypto=no 20 | m4_ifdef([PKG_CHECK_MODULES],[ 21 | PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes],[has_libcrypto=no]) 22 | if test x"$has_libcrypto" = x"yes"; then 23 | TEMP_LIBS="$LIBS" 24 | LIBS="$LIBS $CRYPTO_LIBS" 25 | AC_CHECK_LIB(crypto, main,[AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])],[has_libcrypto=no]) 26 | LIBS="$TEMP_LIBS" 27 | fi 28 | ]) 29 | if test x$has_libcrypto = xno; then 30 | AC_CHECK_HEADER(openssl/crypto.h,[ 31 | AC_CHECK_LIB(crypto, main,[ 32 | has_libcrypto=yes 33 | CRYPTO_LIBS=-lcrypto 34 | AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed]) 35 | ]) 36 | ]) 37 | LIBS= 38 | fi 39 | if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then 40 | AC_MSG_CHECKING(for EC functions in libcrypto) 41 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 42 | #include 43 | #include 44 | #include ]],[[ 45 | EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_secp256k1); 46 | ECDSA_sign(0, NULL, 0, NULL, NULL, eckey); 47 | ECDSA_verify(0, NULL, 0, NULL, 0, eckey); 48 | EC_KEY_free(eckey); 49 | ECDSA_SIG *sig_openssl; 50 | sig_openssl = ECDSA_SIG_new(); 51 | ECDSA_SIG_free(sig_openssl); 52 | ]])],[has_openssl_ec=yes],[has_openssl_ec=no]) 53 | AC_MSG_RESULT([$has_openssl_ec]) 54 | fi 55 | ]) 56 | 57 | dnl 58 | AC_DEFUN([SECP_GMP_CHECK],[ 59 | if test x"$has_gmp" != x"yes"; then 60 | CPPFLAGS_TEMP="$CPPFLAGS" 61 | CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS" 62 | LIBS_TEMP="$LIBS" 63 | LIBS="$GMP_LIBS $LIBS" 64 | AC_CHECK_HEADER(gmp.h,[AC_CHECK_LIB(gmp, __gmpz_init,[has_gmp=yes; GMP_LIBS="$GMP_LIBS -lgmp"; AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])])]) 65 | CPPFLAGS="$CPPFLAGS_TEMP" 66 | LIBS="$LIBS_TEMP" 67 | fi 68 | ]) 69 | -------------------------------------------------------------------------------- /secp256k1/contrib/lax_der_parsing.c: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 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 | #include 8 | #include 9 | 10 | #include "lax_der_parsing.h" 11 | 12 | int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { 13 | size_t rpos, rlen, spos, slen; 14 | size_t pos = 0; 15 | size_t lenbyte; 16 | unsigned char tmpsig[64] = {0}; 17 | int overflow = 0; 18 | 19 | /* Hack to initialize sig with a correctly-parsed but invalid signature. */ 20 | secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 21 | 22 | /* Sequence tag byte */ 23 | if (pos == inputlen || input[pos] != 0x30) { 24 | return 0; 25 | } 26 | pos++; 27 | 28 | /* Sequence length bytes */ 29 | if (pos == inputlen) { 30 | return 0; 31 | } 32 | lenbyte = input[pos++]; 33 | if (lenbyte & 0x80) { 34 | lenbyte -= 0x80; 35 | if (pos + lenbyte > inputlen) { 36 | return 0; 37 | } 38 | pos += lenbyte; 39 | } 40 | 41 | /* Integer tag byte for R */ 42 | if (pos == inputlen || input[pos] != 0x02) { 43 | return 0; 44 | } 45 | pos++; 46 | 47 | /* Integer length for R */ 48 | if (pos == inputlen) { 49 | return 0; 50 | } 51 | lenbyte = input[pos++]; 52 | if (lenbyte & 0x80) { 53 | lenbyte -= 0x80; 54 | if (pos + lenbyte > inputlen) { 55 | return 0; 56 | } 57 | while (lenbyte > 0 && input[pos] == 0) { 58 | pos++; 59 | lenbyte--; 60 | } 61 | if (lenbyte >= sizeof(size_t)) { 62 | return 0; 63 | } 64 | rlen = 0; 65 | while (lenbyte > 0) { 66 | rlen = (rlen << 8) + input[pos]; 67 | pos++; 68 | lenbyte--; 69 | } 70 | } else { 71 | rlen = lenbyte; 72 | } 73 | if (rlen > inputlen - pos) { 74 | return 0; 75 | } 76 | rpos = pos; 77 | pos += rlen; 78 | 79 | /* Integer tag byte for S */ 80 | if (pos == inputlen || input[pos] != 0x02) { 81 | return 0; 82 | } 83 | pos++; 84 | 85 | /* Integer length for S */ 86 | if (pos == inputlen) { 87 | return 0; 88 | } 89 | lenbyte = input[pos++]; 90 | if (lenbyte & 0x80) { 91 | lenbyte -= 0x80; 92 | if (pos + lenbyte > inputlen) { 93 | return 0; 94 | } 95 | while (lenbyte > 0 && input[pos] == 0) { 96 | pos++; 97 | lenbyte--; 98 | } 99 | if (lenbyte >= sizeof(size_t)) { 100 | return 0; 101 | } 102 | slen = 0; 103 | while (lenbyte > 0) { 104 | slen = (slen << 8) + input[pos]; 105 | pos++; 106 | lenbyte--; 107 | } 108 | } else { 109 | slen = lenbyte; 110 | } 111 | if (slen > inputlen - pos) { 112 | return 0; 113 | } 114 | spos = pos; 115 | pos += slen; 116 | 117 | /* Ignore leading zeroes in R */ 118 | while (rlen > 0 && input[rpos] == 0) { 119 | rlen--; 120 | rpos++; 121 | } 122 | /* Copy R value */ 123 | if (rlen > 32) { 124 | overflow = 1; 125 | } else { 126 | memcpy(tmpsig + 32 - rlen, input + rpos, rlen); 127 | } 128 | 129 | /* Ignore leading zeroes in S */ 130 | while (slen > 0 && input[spos] == 0) { 131 | slen--; 132 | spos++; 133 | } 134 | /* Copy S value */ 135 | if (slen > 32) { 136 | overflow = 1; 137 | } else { 138 | memcpy(tmpsig + 64 - slen, input + spos, slen); 139 | } 140 | 141 | if (!overflow) { 142 | overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 143 | } 144 | if (overflow) { 145 | memset(tmpsig, 0, 64); 146 | secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 147 | } 148 | return 1; 149 | } 150 | 151 | -------------------------------------------------------------------------------- /secp256k1/contrib/lax_der_parsing.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 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 | * Please do not link this file directly. It is not part of the libsecp256k1 9 | * project and does not promise any stability in its API, functionality or 10 | * presence. Projects which use this code should instead copy this header 11 | * and its accompanying .c file directly into their codebase. 12 | ****/ 13 | 14 | /* This file defines a function that parses DER with various errors and 15 | * violations. This is not a part of the library itself, because the allowed 16 | * violations are chosen arbitrarily and do not follow or establish any 17 | * standard. 18 | * 19 | * In many places it matters that different implementations do not only accept 20 | * the same set of valid signatures, but also reject the same set of signatures. 21 | * The only means to accomplish that is by strictly obeying a standard, and not 22 | * accepting anything else. 23 | * 24 | * Nonetheless, sometimes there is a need for compatibility with systems that 25 | * use signatures which do not strictly obey DER. The snippet below shows how 26 | * certain violations are easily supported. You may need to adapt it. 27 | * 28 | * Do not use this for new systems. Use well-defined DER or compact signatures 29 | * instead if you have the choice (see secp256k1_ecdsa_signature_parse_der and 30 | * secp256k1_ecdsa_signature_parse_compact). 31 | * 32 | * The supported violations are: 33 | * - All numbers are parsed as nonnegative integers, even though X.609-0207 34 | * section 8.3.3 specifies that integers are always encoded as two's 35 | * complement. 36 | * - Integers can have length 0, even though section 8.3.1 says they can't. 37 | * - Integers with overly long padding are accepted, violation section 38 | * 8.3.2. 39 | * - 127-byte long length descriptors are accepted, even though section 40 | * 8.1.3.5.c says that they are not. 41 | * - Trailing garbage data inside or after the signature is ignored. 42 | * - The length descriptor of the sequence is ignored. 43 | * 44 | * Compared to for example OpenSSL, many violations are NOT supported: 45 | * - Using overly long tag descriptors for the sequence or integers inside, 46 | * violating section 8.1.2.2. 47 | * - Encoding primitive integers as constructed values, violating section 48 | * 8.3.1. 49 | */ 50 | 51 | #ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H 52 | #define SECP256K1_CONTRIB_LAX_DER_PARSING_H 53 | 54 | #include 55 | 56 | #ifdef __cplusplus 57 | extern "C" { 58 | #endif 59 | 60 | /** Parse a signature in "lax DER" format 61 | * 62 | * Returns: 1 when the signature could be parsed, 0 otherwise. 63 | * Args: ctx: a secp256k1 context object 64 | * Out: sig: a pointer to a signature object 65 | * In: input: a pointer to the signature to be parsed 66 | * inputlen: the length of the array pointed to be input 67 | * 68 | * This function will accept any valid DER encoded signature, even if the 69 | * encoded numbers are out of range. In addition, it will accept signatures 70 | * which violate the DER spec in various ways. Its purpose is to allow 71 | * validation of the Bitcoin blockchain, which includes non-DER signatures 72 | * from before the network rules were updated to enforce DER. Note that 73 | * the set of supported violations is a strict subset of what OpenSSL will 74 | * accept. 75 | * 76 | * After the call, sig will always be initialized. If parsing failed or the 77 | * encoded numbers are out of range, signature validation with it is 78 | * guaranteed to fail for every message and public key. 79 | */ 80 | int ecdsa_signature_parse_der_lax( 81 | const secp256k1_context* ctx, 82 | secp256k1_ecdsa_signature* sig, 83 | const unsigned char *input, 84 | size_t inputlen 85 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | 91 | #endif /* SECP256K1_CONTRIB_LAX_DER_PARSING_H */ 92 | -------------------------------------------------------------------------------- /secp256k1/contrib/lax_der_privatekey_parsing.c: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014, 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 | #include 8 | #include 9 | 10 | #include "lax_der_privatekey_parsing.h" 11 | 12 | int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *privkey, size_t privkeylen) { 13 | const unsigned char *end = privkey + privkeylen; 14 | int lenb = 0; 15 | int len = 0; 16 | memset(out32, 0, 32); 17 | /* sequence header */ 18 | if (end < privkey+1 || *privkey != 0x30) { 19 | return 0; 20 | } 21 | privkey++; 22 | /* sequence length constructor */ 23 | if (end < privkey+1 || !(*privkey & 0x80)) { 24 | return 0; 25 | } 26 | lenb = *privkey & ~0x80; privkey++; 27 | if (lenb < 1 || lenb > 2) { 28 | return 0; 29 | } 30 | if (end < privkey+lenb) { 31 | return 0; 32 | } 33 | /* sequence length */ 34 | len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0); 35 | privkey += lenb; 36 | if (end < privkey+len) { 37 | return 0; 38 | } 39 | /* sequence element 0: version number (=1) */ 40 | if (end < privkey+3 || privkey[0] != 0x02 || privkey[1] != 0x01 || privkey[2] != 0x01) { 41 | return 0; 42 | } 43 | privkey += 3; 44 | /* sequence element 1: octet string, up to 32 bytes */ 45 | if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) { 46 | return 0; 47 | } 48 | memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]); 49 | if (!secp256k1_ec_seckey_verify(ctx, out32)) { 50 | memset(out32, 0, 32); 51 | return 0; 52 | } 53 | return 1; 54 | } 55 | 56 | int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) { 57 | secp256k1_pubkey pubkey; 58 | size_t pubkeylen = 0; 59 | if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) { 60 | *privkeylen = 0; 61 | return 0; 62 | } 63 | if (compressed) { 64 | static const unsigned char begin[] = { 65 | 0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20 66 | }; 67 | static const unsigned char middle[] = { 68 | 0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, 69 | 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 70 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 71 | 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, 72 | 0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, 73 | 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, 74 | 0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 75 | 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, 76 | 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00 77 | }; 78 | unsigned char *ptr = privkey; 79 | memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); 80 | memcpy(ptr, key32, 32); ptr += 32; 81 | memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); 82 | pubkeylen = 33; 83 | secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED); 84 | ptr += pubkeylen; 85 | *privkeylen = ptr - privkey; 86 | } else { 87 | static const unsigned char begin[] = { 88 | 0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20 89 | }; 90 | static const unsigned char middle[] = { 91 | 0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, 92 | 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 93 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 94 | 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, 95 | 0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, 96 | 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, 97 | 0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11, 98 | 0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10, 99 | 0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 100 | 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, 101 | 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00 102 | }; 103 | unsigned char *ptr = privkey; 104 | memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); 105 | memcpy(ptr, key32, 32); ptr += 32; 106 | memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); 107 | pubkeylen = 65; 108 | secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED); 109 | ptr += pubkeylen; 110 | *privkeylen = ptr - privkey; 111 | } 112 | return 1; 113 | } 114 | -------------------------------------------------------------------------------- /secp256k1/contrib/lax_der_privatekey_parsing.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014, 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 | * Please do not link this file directly. It is not part of the libsecp256k1 9 | * project and does not promise any stability in its API, functionality or 10 | * presence. Projects which use this code should instead copy this header 11 | * and its accompanying .c file directly into their codebase. 12 | ****/ 13 | 14 | /* This file contains code snippets that parse DER private keys with 15 | * various errors and violations. This is not a part of the library 16 | * itself, because the allowed violations are chosen arbitrarily and 17 | * do not follow or establish any standard. 18 | * 19 | * It also contains code to serialize private keys in a compatible 20 | * manner. 21 | * 22 | * These functions are meant for compatibility with applications 23 | * that require BER encoded keys. When working with secp256k1-specific 24 | * code, the simple 32-byte private keys normally used by the 25 | * library are sufficient. 26 | */ 27 | 28 | #ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H 29 | #define SECP256K1_CONTRIB_BER_PRIVATEKEY_H 30 | 31 | #include 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /** Export a private key in DER format. 38 | * 39 | * Returns: 1 if the private key was valid. 40 | * Args: ctx: pointer to a context object, initialized for signing (cannot 41 | * be NULL) 42 | * Out: privkey: pointer to an array for storing the private key in BER. 43 | * Should have space for 279 bytes, and cannot be NULL. 44 | * privkeylen: Pointer to an int where the length of the private key in 45 | * privkey will be stored. 46 | * In: seckey: pointer to a 32-byte secret key to export. 47 | * compressed: 1 if the key should be exported in 48 | * compressed format, 0 otherwise 49 | * 50 | * This function is purely meant for compatibility with applications that 51 | * require BER encoded keys. When working with secp256k1-specific code, the 52 | * simple 32-byte private keys are sufficient. 53 | * 54 | * Note that this function does not guarantee correct DER output. It is 55 | * guaranteed to be parsable by secp256k1_ec_privkey_import_der 56 | */ 57 | SECP256K1_WARN_UNUSED_RESULT int ec_privkey_export_der( 58 | const secp256k1_context* ctx, 59 | unsigned char *privkey, 60 | size_t *privkeylen, 61 | const unsigned char *seckey, 62 | int compressed 63 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 64 | 65 | /** Import a private key in DER format. 66 | * Returns: 1 if a private key was extracted. 67 | * Args: ctx: pointer to a context object (cannot be NULL). 68 | * Out: seckey: pointer to a 32-byte array for storing the private key. 69 | * (cannot be NULL). 70 | * In: privkey: pointer to a private key in DER format (cannot be NULL). 71 | * privkeylen: length of the DER private key pointed to be privkey. 72 | * 73 | * This function will accept more than just strict DER, and even allow some BER 74 | * violations. The public key stored inside the DER-encoded private key is not 75 | * verified for correctness, nor are the curve parameters. Use this function 76 | * only if you know in advance it is supposed to contain a secp256k1 private 77 | * key. 78 | */ 79 | SECP256K1_WARN_UNUSED_RESULT int ec_privkey_import_der( 80 | const secp256k1_context* ctx, 81 | unsigned char *seckey, 82 | const unsigned char *privkey, 83 | size_t privkeylen 84 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /* SECP256K1_CONTRIB_BER_PRIVATEKEY_H */ 91 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /secp256k1/include/secp256k1_multiset.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2017 Tomas van der Wansem * 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_MULTISET__ 9 | # define _SECP256K1_MULTISET__ 10 | 11 | # include "secp256k1.h" 12 | 13 | 14 | # ifdef __cplusplus 15 | extern "C" { 16 | # endif 17 | 18 | 19 | /** Opaque multiset; this is actually a group element **/ 20 | typedef struct { 21 | unsigned char d[96]; 22 | } secp256k1_multiset; 23 | 24 | 25 | 26 | /** Initialize a multiset 27 | * The resulting multiset the multiset for no data elements 28 | * 29 | * Returns: 1: success 30 | * 0: invalid parameter 31 | * Args: ctx: pointer to a context object (cannot be NULL) 32 | * Out: multiset: the resulting multiset 33 | */ 34 | SECP256K1_API int secp256k1_multiset_init( 35 | const secp256k1_context* ctx, 36 | secp256k1_multiset *multiset 37 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); 38 | 39 | 40 | /** Adds an element to a multiset from single data element 41 | * 42 | * Returns: 1: success 43 | * 0: invalid parameter 44 | * Args: ctx: pointer to a context object (cannot be NULL) 45 | * Out: multiset: the multiset to update 46 | * In: input: the data to add 47 | * inputLen: the size of the data to add 48 | */ 49 | SECP256K1_API int secp256k1_multiset_add( 50 | const secp256k1_context* ctx, 51 | secp256k1_multiset *multiset, 52 | const unsigned char *input, 53 | size_t inputLen 54 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 55 | 56 | /** Removes an element from a multiset 57 | * 58 | * Returns: 1: success 59 | * 0: invalid parameter 60 | * Args: ctx: pointer to a context object (cannot be NULL) 61 | * Out: multiset: the multiset to update 62 | * In: input: the data to remove 63 | * inputLen: the size of the data to remove 64 | */ 65 | SECP256K1_API int secp256k1_multiset_remove( 66 | const secp256k1_context* ctx, 67 | secp256k1_multiset *multiset, 68 | const unsigned char *input, 69 | size_t inputLen 70 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 71 | 72 | 73 | 74 | /** Combines two multisets 75 | * 76 | * Returns: 1: success 77 | * 0: invalid parameter 78 | * Args: ctx: pointer to a context object (cannot be NULL) 79 | * In/Out: multiset: the multiset to which the input must be added 80 | * In: input: the multiset to add 81 | */ 82 | SECP256K1_API int secp256k1_multiset_combine( 83 | const secp256k1_context* ctx, 84 | secp256k1_multiset *multiset, 85 | const secp256k1_multiset *input 86 | 87 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 88 | 89 | 90 | /** Converts a multiset to a hash 91 | * 92 | * Returns: 1: success 93 | * 0: invalid parameter 94 | * Args: ctx: pointer to a context object (cannot be NULL) 95 | * Out: hash: the resulting 32-byte hash 96 | * In: multiset: the multiset to hash 97 | */ 98 | SECP256K1_API int secp256k1_multiset_finalize( 99 | const secp256k1_context* ctx, 100 | unsigned char *resultHash, 101 | const secp256k1_multiset *multiset 102 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 103 | 104 | 105 | 106 | # ifdef __cplusplus 107 | } 108 | # endif 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /secp256k1/libsecp256k1.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libsecp256k1 7 | Description: Optimized C library for EC operations on curve secp256k1 8 | URL: https://github.com/bitcoin-core/secp256k1 9 | Version: @PACKAGE_VERSION@ 10 | Cflags: -I${includedir} 11 | Libs.private: @SECP_LIBS@ 12 | Libs: -L${libdir} -lsecp256k1 13 | 14 | -------------------------------------------------------------------------------- /secp256k1/obj/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcashtech/bitcoin/15f62465e909ef676d1cd41515776d0db2eeefc1/secp256k1/obj/.gitignore -------------------------------------------------------------------------------- /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 | #ifdef USE_BASIC_CONFIG 11 | 12 | #undef USE_ASM_X86_64 13 | #undef USE_ENDOMORPHISM 14 | #undef USE_FIELD_10X26 15 | #undef USE_FIELD_5X52 16 | #undef USE_FIELD_INV_BUILTIN 17 | #undef USE_FIELD_INV_NUM 18 | #undef USE_NUM_GMP 19 | #undef USE_NUM_NONE 20 | #undef USE_SCALAR_4X64 21 | #undef USE_SCALAR_8X32 22 | #undef USE_SCALAR_INV_BUILTIN 23 | #undef USE_SCALAR_INV_NUM 24 | 25 | #define USE_NUM_NONE 1 26 | #define USE_FIELD_INV_BUILTIN 1 27 | #define USE_SCALAR_INV_BUILTIN 1 28 | #define USE_FIELD_10X26 1 29 | #define USE_SCALAR_8X32 1 30 | 31 | #endif /* USE_BASIC_CONFIG */ 32 | 33 | #endif /* SECP256K1_BASIC_CONFIG_H */ 34 | -------------------------------------------------------------------------------- /secp256k1/src/bench.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_BENCH_H 8 | #define SECP256K1_BENCH_H 9 | 10 | #include 11 | #include 12 | #include "sys/time.h" 13 | 14 | static double gettimedouble(void) { 15 | struct timeval tv; 16 | gettimeofday(&tv, NULL); 17 | return tv.tv_usec * 0.000001 + tv.tv_sec; 18 | } 19 | 20 | void print_number(double x) { 21 | double y = x; 22 | int c = 0; 23 | if (y < 0.0) { 24 | y = -y; 25 | } 26 | while (y > 0 && y < 100.0) { 27 | y *= 10.0; 28 | c++; 29 | } 30 | printf("%.*f", c, x); 31 | } 32 | 33 | void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) { 34 | int i; 35 | double min = HUGE_VAL; 36 | double sum = 0.0; 37 | double max = 0.0; 38 | for (i = 0; i < count; i++) { 39 | double begin, total; 40 | if (setup != NULL) { 41 | setup(data); 42 | } 43 | begin = gettimedouble(); 44 | benchmark(data); 45 | total = gettimedouble() - begin; 46 | if (teardown != NULL) { 47 | teardown(data); 48 | } 49 | if (total < min) { 50 | min = total; 51 | } 52 | if (total > max) { 53 | max = total; 54 | } 55 | sum += total; 56 | } 57 | printf("%s: min ", name); 58 | print_number(min * 1000000.0 / iter); 59 | printf("us / avg "); 60 | print_number((sum / count) * 1000000.0 / iter); 61 | printf("us / max "); 62 | print_number(max * 1000000.0 / iter); 63 | printf("us\n"); 64 | } 65 | 66 | #endif /* SECP256K1_BENCH_H */ 67 | -------------------------------------------------------------------------------- /secp256k1/src/bench_ecdh.c: -------------------------------------------------------------------------------- 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 | #include 8 | 9 | #include "include/secp256k1.h" 10 | #include "include/secp256k1_ecdh.h" 11 | #include "util.h" 12 | #include "bench.h" 13 | 14 | typedef struct { 15 | secp256k1_context *ctx; 16 | secp256k1_pubkey point; 17 | unsigned char scalar[32]; 18 | } bench_ecdh_data; 19 | 20 | static void bench_ecdh_setup(void* arg) { 21 | int i; 22 | bench_ecdh_data *data = (bench_ecdh_data*)arg; 23 | const unsigned char point[] = { 24 | 0x03, 25 | 0x54, 0x94, 0xc1, 0x5d, 0x32, 0x09, 0x97, 0x06, 26 | 0xc2, 0x39, 0x5f, 0x94, 0x34, 0x87, 0x45, 0xfd, 27 | 0x75, 0x7c, 0xe3, 0x0e, 0x4e, 0x8c, 0x90, 0xfb, 28 | 0xa2, 0xba, 0xd1, 0x84, 0xf8, 0x83, 0xc6, 0x9f 29 | }; 30 | 31 | /* create a context with no capabilities */ 32 | data->ctx = secp256k1_context_create(SECP256K1_FLAGS_TYPE_CONTEXT); 33 | for (i = 0; i < 32; i++) { 34 | data->scalar[i] = i + 1; 35 | } 36 | CHECK(secp256k1_ec_pubkey_parse(data->ctx, &data->point, point, sizeof(point)) == 1); 37 | } 38 | 39 | static void bench_ecdh(void* arg) { 40 | int i; 41 | unsigned char res[32]; 42 | bench_ecdh_data *data = (bench_ecdh_data*)arg; 43 | 44 | for (i = 0; i < 20000; i++) { 45 | CHECK(secp256k1_ecdh(data->ctx, res, &data->point, data->scalar) == 1); 46 | } 47 | } 48 | 49 | int main(void) { 50 | bench_ecdh_data data; 51 | 52 | run_benchmark("ecdh", bench_ecdh, bench_ecdh_setup, NULL, &data, 10, 20000); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /secp256k1/src/bench_multiset.c: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2017 Tomas van der Wansem * 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 | #include "include/secp256k1.h" 8 | #include "include/secp256k1_multiset.h" 9 | #include "util.h" 10 | #include "bench.h" 11 | 12 | secp256k1_context *ctx; 13 | 14 | #define UNUSED(x) (void)(x) 15 | 16 | void bench_multiset(void* arg) { 17 | int it=0; 18 | unsigned n,m; 19 | unsigned char result[32]; 20 | secp256k1_multiset multiset; 21 | 22 | UNUSED(arg); 23 | secp256k1_multiset_init(ctx, &multiset); 24 | 25 | for (m=0; m < 300000; m++) 26 | { 27 | unsigned char buf[32*3]; 28 | secp256k1_multiset x; 29 | 30 | for(n = 0; n < sizeof(buf); n++) 31 | { 32 | buf[n] = it++; 33 | } 34 | 35 | secp256k1_multiset_add(ctx, &x, buf, sizeof(buf)); 36 | } 37 | 38 | secp256k1_multiset_finalize(ctx, result, &multiset); 39 | } 40 | 41 | void bench_multiset_setup(void* arg) { 42 | UNUSED(arg); 43 | } 44 | 45 | int main(void) { 46 | 47 | ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); 48 | 49 | run_benchmark("multiset", bench_multiset, bench_multiset_setup, NULL, NULL, 5, 1); 50 | 51 | secp256k1_context_destroy(ctx); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /secp256k1/src/bench_recover.c: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014-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 | #include "include/secp256k1.h" 8 | #include "include/secp256k1_recovery.h" 9 | #include "util.h" 10 | #include "bench.h" 11 | 12 | typedef struct { 13 | secp256k1_context *ctx; 14 | unsigned char msg[32]; 15 | unsigned char sig[64]; 16 | } bench_recover_data; 17 | 18 | void bench_recover(void* arg) { 19 | int i; 20 | bench_recover_data *data = (bench_recover_data*)arg; 21 | secp256k1_pubkey pubkey; 22 | unsigned char pubkeyc[33]; 23 | 24 | for (i = 0; i < 20000; i++) { 25 | int j; 26 | size_t pubkeylen = 33; 27 | secp256k1_ecdsa_recoverable_signature sig; 28 | CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(data->ctx, &sig, data->sig, i % 2)); 29 | CHECK(secp256k1_ecdsa_recover(data->ctx, &pubkey, &sig, data->msg)); 30 | CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED)); 31 | for (j = 0; j < 32; j++) { 32 | data->sig[j + 32] = data->msg[j]; /* Move former message to S. */ 33 | data->msg[j] = data->sig[j]; /* Move former R to message. */ 34 | data->sig[j] = pubkeyc[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */ 35 | } 36 | } 37 | } 38 | 39 | void bench_recover_setup(void* arg) { 40 | int i; 41 | bench_recover_data *data = (bench_recover_data*)arg; 42 | 43 | for (i = 0; i < 32; i++) { 44 | data->msg[i] = 1 + i; 45 | } 46 | for (i = 0; i < 64; i++) { 47 | data->sig[i] = 65 + i; 48 | } 49 | } 50 | 51 | int main(void) { 52 | bench_recover_data data; 53 | 54 | data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); 55 | 56 | run_benchmark("ecdsa_recover", bench_recover, bench_recover_setup, NULL, &data, 10, 20000); 57 | 58 | secp256k1_context_destroy(data.ctx); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /secp256k1/src/bench_sign.c: -------------------------------------------------------------------------------- 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 | #include "include/secp256k1.h" 8 | #include "util.h" 9 | #include "bench.h" 10 | 11 | typedef struct { 12 | secp256k1_context* ctx; 13 | unsigned char msg[32]; 14 | unsigned char key[32]; 15 | } bench_sign; 16 | 17 | static void bench_sign_setup(void* arg) { 18 | int i; 19 | bench_sign *data = (bench_sign*)arg; 20 | 21 | for (i = 0; i < 32; i++) { 22 | data->msg[i] = i + 1; 23 | } 24 | for (i = 0; i < 32; i++) { 25 | data->key[i] = i + 65; 26 | } 27 | } 28 | 29 | static void bench_sign_run(void* arg) { 30 | int i; 31 | bench_sign *data = (bench_sign*)arg; 32 | 33 | unsigned char sig[74]; 34 | for (i = 0; i < 20000; i++) { 35 | size_t siglen = 74; 36 | int j; 37 | secp256k1_ecdsa_signature signature; 38 | CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL)); 39 | CHECK(secp256k1_ecdsa_signature_serialize_der(data->ctx, sig, &siglen, &signature)); 40 | for (j = 0; j < 32; j++) { 41 | data->msg[j] = sig[j]; 42 | data->key[j] = sig[j + 32]; 43 | } 44 | } 45 | } 46 | 47 | int main(void) { 48 | bench_sign data; 49 | 50 | data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); 51 | 52 | run_benchmark("ecdsa_sign", bench_sign_run, bench_sign_setup, NULL, &data, 10, 20000); 53 | 54 | secp256k1_context_destroy(data.ctx); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /secp256k1/src/bench_verify.c: -------------------------------------------------------------------------------- 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 | #include 8 | #include 9 | 10 | #include "include/secp256k1.h" 11 | #include "util.h" 12 | #include "bench.h" 13 | 14 | #ifdef ENABLE_OPENSSL_TESTS 15 | #include 16 | #include 17 | #include 18 | #endif 19 | 20 | typedef struct { 21 | secp256k1_context *ctx; 22 | unsigned char msg[32]; 23 | unsigned char key[32]; 24 | unsigned char sig[72]; 25 | size_t siglen; 26 | unsigned char pubkey[33]; 27 | size_t pubkeylen; 28 | #ifdef ENABLE_OPENSSL_TESTS 29 | EC_GROUP* ec_group; 30 | #endif 31 | } benchmark_verify_t; 32 | 33 | static void benchmark_verify(void* arg) { 34 | int i; 35 | benchmark_verify_t* data = (benchmark_verify_t*)arg; 36 | 37 | for (i = 0; i < 20000; i++) { 38 | secp256k1_pubkey pubkey; 39 | secp256k1_ecdsa_signature sig; 40 | data->sig[data->siglen - 1] ^= (i & 0xFF); 41 | data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); 42 | data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); 43 | CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1); 44 | CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1); 45 | CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (i == 0)); 46 | data->sig[data->siglen - 1] ^= (i & 0xFF); 47 | data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); 48 | data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); 49 | } 50 | } 51 | 52 | #ifdef ENABLE_OPENSSL_TESTS 53 | static void benchmark_verify_openssl(void* arg) { 54 | int i; 55 | benchmark_verify_t* data = (benchmark_verify_t*)arg; 56 | 57 | for (i = 0; i < 20000; i++) { 58 | data->sig[data->siglen - 1] ^= (i & 0xFF); 59 | data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); 60 | data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); 61 | { 62 | EC_KEY *pkey = EC_KEY_new(); 63 | const unsigned char *pubkey = &data->pubkey[0]; 64 | int result; 65 | 66 | CHECK(pkey != NULL); 67 | result = EC_KEY_set_group(pkey, data->ec_group); 68 | CHECK(result); 69 | result = (o2i_ECPublicKey(&pkey, &pubkey, data->pubkeylen)) != NULL; 70 | CHECK(result); 71 | result = ECDSA_verify(0, &data->msg[0], sizeof(data->msg), &data->sig[0], data->siglen, pkey) == (i == 0); 72 | CHECK(result); 73 | EC_KEY_free(pkey); 74 | } 75 | data->sig[data->siglen - 1] ^= (i & 0xFF); 76 | data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); 77 | data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); 78 | } 79 | } 80 | #endif 81 | 82 | int main(void) { 83 | int i; 84 | secp256k1_pubkey pubkey; 85 | secp256k1_ecdsa_signature sig; 86 | benchmark_verify_t data; 87 | 88 | data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); 89 | 90 | for (i = 0; i < 32; i++) { 91 | data.msg[i] = 1 + i; 92 | } 93 | for (i = 0; i < 32; i++) { 94 | data.key[i] = 33 + i; 95 | } 96 | data.siglen = 72; 97 | CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL)); 98 | CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig)); 99 | CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key)); 100 | data.pubkeylen = 33; 101 | CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1); 102 | 103 | run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000); 104 | #ifdef ENABLE_OPENSSL_TESTS 105 | data.ec_group = EC_GROUP_new_by_curve_name(NID_secp256k1); 106 | run_benchmark("ecdsa_verify_openssl", benchmark_verify_openssl, NULL, NULL, &data, 10, 20000); 107 | EC_GROUP_free(data.ec_group); 108 | #endif 109 | 110 | secp256k1_context_destroy(data.ctx); 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /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 | 16 | static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size); 17 | static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s); 18 | static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message); 19 | static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid); 20 | 21 | #endif /* SECP256K1_ECDSA_H */ 22 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | #if defined(USE_FIELD_10X26) 26 | #include "field_10x26.h" 27 | #elif defined(USE_FIELD_5X52) 28 | #include "field_5x52.h" 29 | #else 30 | #error "Please select field implementation" 31 | #endif 32 | 33 | #include "util.h" 34 | 35 | /** Normalize a field element. */ 36 | static void secp256k1_fe_normalize(secp256k1_fe *r); 37 | 38 | /** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */ 39 | static void secp256k1_fe_normalize_weak(secp256k1_fe *r); 40 | 41 | /** Normalize a field element, without constant-time guarantee. */ 42 | static void secp256k1_fe_normalize_var(secp256k1_fe *r); 43 | 44 | /** Verify whether a field element represents zero i.e. would normalize to a zero value. The field 45 | * implementation may optionally normalize the input, but this should not be relied upon. */ 46 | static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r); 47 | 48 | /** Verify whether a field element represents zero i.e. would normalize to a zero value. The field 49 | * implementation may optionally normalize the input, but this should not be relied upon. */ 50 | static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r); 51 | 52 | /** Set a field element equal to a small integer. Resulting field element is normalized. */ 53 | static void secp256k1_fe_set_int(secp256k1_fe *r, int a); 54 | 55 | /** Sets a field element equal to zero, initializing all fields. */ 56 | static void secp256k1_fe_clear(secp256k1_fe *a); 57 | 58 | /** Verify whether a field element is zero. Requires the input to be normalized. */ 59 | static int secp256k1_fe_is_zero(const secp256k1_fe *a); 60 | 61 | /** Check the "oddness" of a field element. Requires the input to be normalized. */ 62 | static int secp256k1_fe_is_odd(const secp256k1_fe *a); 63 | 64 | /** Compare two field elements. Requires magnitude-1 inputs. */ 65 | static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b); 66 | 67 | /** Same as secp256k1_fe_equal, but may be variable time. */ 68 | static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b); 69 | 70 | /** Compare two field elements. Requires both inputs to be normalized */ 71 | static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b); 72 | 73 | /** Set a field element equal to 32-byte big endian value. If successful, the resulting field element is normalized. */ 74 | static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a); 75 | 76 | /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ 77 | static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a); 78 | 79 | /** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input 80 | * as an argument. The magnitude of the output is one higher. */ 81 | static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m); 82 | 83 | /** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that 84 | * small integer. */ 85 | static void secp256k1_fe_mul_int(secp256k1_fe *r, int a); 86 | 87 | /** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */ 88 | static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a); 89 | 90 | /** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8. 91 | * The output magnitude is 1 (but not guaranteed to be normalized). */ 92 | static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b); 93 | 94 | /** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8. 95 | * The output magnitude is 1 (but not guaranteed to be normalized). */ 96 | static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a); 97 | 98 | /** If a has a square root, it is computed in r and 1 is returned. If a does not 99 | * have a square root, the root of its negation is computed and 0 is returned. 100 | * The input's magnitude can be at most 8. The output magnitude is 1 (but not 101 | * guaranteed to be normalized). The result in r will always be a square 102 | * itself. */ 103 | static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a); 104 | 105 | /** Checks whether a field element is a quadratic residue. */ 106 | static int secp256k1_fe_is_quad_var(const secp256k1_fe *a); 107 | 108 | /** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be 109 | * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ 110 | static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a); 111 | 112 | /** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */ 113 | static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a); 114 | 115 | /** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be 116 | * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and 117 | * outputs must not overlap in memory. */ 118 | static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len); 119 | 120 | /** Convert a field element to the storage type. */ 121 | static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a); 122 | 123 | /** Convert a field element back from the storage type. */ 124 | static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a); 125 | 126 | /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ 127 | static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag); 128 | 129 | /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ 130 | static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); 131 | 132 | #endif /* SECP256K1_FIELD_H */ 133 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /secp256k1/src/gen_context.c: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014, 2015 Thomas Daede, Cory Fields * 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 | #define USE_BASIC_CONFIG 1 8 | 9 | #include "basic-config.h" 10 | #include "include/secp256k1.h" 11 | #include "field_impl.h" 12 | #include "scalar_impl.h" 13 | #include "group_impl.h" 14 | #include "ecmult_gen_impl.h" 15 | 16 | static void default_error_callback_fn(const char* str, void* data) { 17 | (void)data; 18 | fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); 19 | abort(); 20 | } 21 | 22 | static const secp256k1_callback default_error_callback = { 23 | default_error_callback_fn, 24 | NULL 25 | }; 26 | 27 | int main(int argc, char **argv) { 28 | secp256k1_ecmult_gen_context ctx; 29 | int inner; 30 | int outer; 31 | FILE* fp; 32 | 33 | (void)argc; 34 | (void)argv; 35 | 36 | fp = fopen("src/ecmult_static_context.h","w"); 37 | if (fp == NULL) { 38 | fprintf(stderr, "Could not open src/ecmult_static_context.h for writing!\n"); 39 | return -1; 40 | } 41 | 42 | fprintf(fp, "#ifndef _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); 43 | fprintf(fp, "#define _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); 44 | fprintf(fp, "#include \"src/group.h\"\n"); 45 | fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n"); 46 | fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_static_context[64][16] = {\n"); 47 | 48 | secp256k1_ecmult_gen_context_init(&ctx); 49 | secp256k1_ecmult_gen_context_build(&ctx, &default_error_callback); 50 | for(outer = 0; outer != 64; outer++) { 51 | fprintf(fp,"{\n"); 52 | for(inner = 0; inner != 16; inner++) { 53 | fprintf(fp," SC(%uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu)", SECP256K1_GE_STORAGE_CONST_GET((*ctx.prec)[outer][inner])); 54 | if (inner != 15) { 55 | fprintf(fp,",\n"); 56 | } else { 57 | fprintf(fp,"\n"); 58 | } 59 | } 60 | if (outer != 63) { 61 | fprintf(fp,"},\n"); 62 | } else { 63 | fprintf(fp,"}\n"); 64 | } 65 | } 66 | fprintf(fp,"};\n"); 67 | secp256k1_ecmult_gen_context_clear(&ctx); 68 | 69 | fprintf(fp, "#undef SC\n"); 70 | fprintf(fp, "#endif\n"); 71 | fclose(fp); 72 | 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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; 18 | 19 | static void secp256k1_sha256_initialize(secp256k1_sha256 *hash); 20 | static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size); 21 | static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32); 22 | 23 | typedef struct { 24 | secp256k1_sha256 inner, outer; 25 | } secp256k1_hmac_sha256; 26 | 27 | static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size); 28 | static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size); 29 | static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32); 30 | 31 | typedef struct { 32 | unsigned char v[32]; 33 | unsigned char k[32]; 34 | int retry; 35 | } secp256k1_rfc6979_hmac_sha256; 36 | 37 | static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); 38 | static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); 39 | static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng); 40 | 41 | #endif /* SECP256K1_HASH_H */ 42 | -------------------------------------------------------------------------------- /secp256k1/src/java/org_bitcoin_NativeSecp256k1.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | #include "include/secp256k1.h" 4 | /* Header for class org_bitcoin_NativeSecp256k1 */ 5 | 6 | #ifndef _Included_org_bitcoin_NativeSecp256k1 7 | #define _Included_org_bitcoin_NativeSecp256k1 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | /* 12 | * Class: org_bitcoin_NativeSecp256k1 13 | * Method: secp256k1_ctx_clone 14 | * Signature: (J)J 15 | */ 16 | SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ctx_1clone 17 | (JNIEnv *, jclass, jlong); 18 | 19 | /* 20 | * Class: org_bitcoin_NativeSecp256k1 21 | * Method: secp256k1_context_randomize 22 | * Signature: (Ljava/nio/ByteBuffer;J)I 23 | */ 24 | SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1context_1randomize 25 | (JNIEnv *, jclass, jobject, jlong); 26 | 27 | /* 28 | * Class: org_bitcoin_NativeSecp256k1 29 | * Method: secp256k1_privkey_tweak_add 30 | * Signature: (Ljava/nio/ByteBuffer;J)[[B 31 | */ 32 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1add 33 | (JNIEnv *, jclass, jobject, jlong); 34 | 35 | /* 36 | * Class: org_bitcoin_NativeSecp256k1 37 | * Method: secp256k1_privkey_tweak_mul 38 | * Signature: (Ljava/nio/ByteBuffer;J)[[B 39 | */ 40 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1mul 41 | (JNIEnv *, jclass, jobject, jlong); 42 | 43 | /* 44 | * Class: org_bitcoin_NativeSecp256k1 45 | * Method: secp256k1_pubkey_tweak_add 46 | * Signature: (Ljava/nio/ByteBuffer;JI)[[B 47 | */ 48 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1add 49 | (JNIEnv *, jclass, jobject, jlong, jint); 50 | 51 | /* 52 | * Class: org_bitcoin_NativeSecp256k1 53 | * Method: secp256k1_pubkey_tweak_mul 54 | * Signature: (Ljava/nio/ByteBuffer;JI)[[B 55 | */ 56 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1mul 57 | (JNIEnv *, jclass, jobject, jlong, jint); 58 | 59 | /* 60 | * Class: org_bitcoin_NativeSecp256k1 61 | * Method: secp256k1_destroy_context 62 | * Signature: (J)V 63 | */ 64 | SECP256K1_API void JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1destroy_1context 65 | (JNIEnv *, jclass, jlong); 66 | 67 | /* 68 | * Class: org_bitcoin_NativeSecp256k1 69 | * Method: secp256k1_ecdsa_verify 70 | * Signature: (Ljava/nio/ByteBuffer;JII)I 71 | */ 72 | SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify 73 | (JNIEnv *, jclass, jobject, jlong, jint, jint); 74 | 75 | /* 76 | * Class: org_bitcoin_NativeSecp256k1 77 | * Method: secp256k1_ecdsa_sign 78 | * Signature: (Ljava/nio/ByteBuffer;J)[[B 79 | */ 80 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1sign 81 | (JNIEnv *, jclass, jobject, jlong); 82 | 83 | /* 84 | * Class: org_bitcoin_NativeSecp256k1 85 | * Method: secp256k1_ec_seckey_verify 86 | * Signature: (Ljava/nio/ByteBuffer;J)I 87 | */ 88 | SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1seckey_1verify 89 | (JNIEnv *, jclass, jobject, jlong); 90 | 91 | /* 92 | * Class: org_bitcoin_NativeSecp256k1 93 | * Method: secp256k1_ec_pubkey_create 94 | * Signature: (Ljava/nio/ByteBuffer;J)[[B 95 | */ 96 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1create 97 | (JNIEnv *, jclass, jobject, jlong); 98 | 99 | /* 100 | * Class: org_bitcoin_NativeSecp256k1 101 | * Method: secp256k1_ec_pubkey_parse 102 | * Signature: (Ljava/nio/ByteBuffer;JI)[[B 103 | */ 104 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1parse 105 | (JNIEnv *, jclass, jobject, jlong, jint); 106 | 107 | /* 108 | * Class: org_bitcoin_NativeSecp256k1 109 | * Method: secp256k1_ecdh 110 | * Signature: (Ljava/nio/ByteBuffer;JI)[[B 111 | */ 112 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdh 113 | (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen); 114 | 115 | 116 | #ifdef __cplusplus 117 | } 118 | #endif 119 | #endif 120 | -------------------------------------------------------------------------------- /secp256k1/src/java/org_bitcoin_Secp256k1Context.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "org_bitcoin_Secp256k1Context.h" 4 | #include "include/secp256k1.h" 5 | 6 | SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context 7 | (JNIEnv* env, jclass classObject) 8 | { 9 | secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); 10 | 11 | (void)classObject;(void)env; 12 | 13 | return (uintptr_t)ctx; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /secp256k1/src/java/org_bitcoin_Secp256k1Context.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | #include "include/secp256k1.h" 4 | /* Header for class org_bitcoin_Secp256k1Context */ 5 | 6 | #ifndef _Included_org_bitcoin_Secp256k1Context 7 | #define _Included_org_bitcoin_Secp256k1Context 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | /* 12 | * Class: org_bitcoin_Secp256k1Context 13 | * Method: secp256k1_init_context 14 | * Signature: ()J 15 | */ 16 | SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context 17 | (JNIEnv *, jclass); 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | #endif 23 | -------------------------------------------------------------------------------- /secp256k1/src/libsecp256k1-config.h.cmake.in: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017 The Bitcoin developers */ 2 | 3 | #ifndef LIBSECP256K1_CONFIG_H 4 | #define LIBSECP256K1_CONFIG_H 5 | 6 | #cmakedefine HAVE___INT128 7 | 8 | #cmakedefine USE_NUM_GMP 9 | #cmakedefine USE_FIELD_INV_NUM 10 | #cmakedefine USE_SCALAR_INV_NUM 11 | 12 | #cmakedefine USE_NUM_NONE 13 | #cmakedefine USE_FIELD_INV_BUILTIN 14 | #cmakedefine USE_SCALAR_INV_BUILTIN 15 | 16 | #cmakedefine USE_SCALAR_4X64 17 | #cmakedefine USE_FIELD_5X52 18 | 19 | #cmakedefine USE_SCALAR_8X32 20 | #cmakedefine USE_FIELD_10X26 21 | 22 | #cmakedefine USE_ASM_X86_64 23 | 24 | #cmakedefine USE_ECMULT_STATIC_PRECOMPUTATION 25 | 26 | #cmakedefine ENABLE_MODULE_RECOVERY 27 | #cmakedefine ENABLE_MODULE_ECDH 28 | #cmakedefine ENABLE_MODULE_MULTISET 29 | 30 | #endif /* LIBSECP256K1_CONFIG_H */ 31 | -------------------------------------------------------------------------------- /secp256k1/src/modules/ecdh/Makefile.am.include: -------------------------------------------------------------------------------- 1 | include_HEADERS += include/secp256k1_ecdh.h 2 | noinst_HEADERS += src/modules/ecdh/main_impl.h 3 | noinst_HEADERS += src/modules/ecdh/tests_impl.h 4 | if USE_BENCHMARK 5 | noinst_PROGRAMS += bench_ecdh 6 | bench_ecdh_SOURCES = src/bench_ecdh.c 7 | bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) 8 | endif 9 | -------------------------------------------------------------------------------- /secp256k1/src/modules/ecdh/main_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_MODULE_ECDH_MAIN_H 8 | #define SECP256K1_MODULE_ECDH_MAIN_H 9 | 10 | #include "include/secp256k1_ecdh.h" 11 | #include "ecmult_const_impl.h" 12 | 13 | int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *result, const secp256k1_pubkey *point, const unsigned char *scalar) { 14 | int ret = 0; 15 | int overflow = 0; 16 | secp256k1_gej res; 17 | secp256k1_ge pt; 18 | secp256k1_scalar s; 19 | VERIFY_CHECK(ctx != NULL); 20 | ARG_CHECK(result != NULL); 21 | ARG_CHECK(point != NULL); 22 | ARG_CHECK(scalar != NULL); 23 | 24 | secp256k1_pubkey_load(ctx, &pt, point); 25 | secp256k1_scalar_set_b32(&s, scalar, &overflow); 26 | if (overflow || secp256k1_scalar_is_zero(&s)) { 27 | ret = 0; 28 | } else { 29 | unsigned char x[32]; 30 | unsigned char y[1]; 31 | secp256k1_sha256 sha; 32 | 33 | secp256k1_ecmult_const(&res, &pt, &s); 34 | secp256k1_ge_set_gej(&pt, &res); 35 | /* Compute a hash of the point in compressed form 36 | * Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not 37 | * expect its output to be secret and has a timing sidechannel. */ 38 | secp256k1_fe_normalize(&pt.x); 39 | secp256k1_fe_normalize(&pt.y); 40 | secp256k1_fe_get_b32(x, &pt.x); 41 | y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y); 42 | 43 | secp256k1_sha256_initialize(&sha); 44 | secp256k1_sha256_write(&sha, y, sizeof(y)); 45 | secp256k1_sha256_write(&sha, x, sizeof(x)); 46 | secp256k1_sha256_finalize(&sha, result); 47 | ret = 1; 48 | } 49 | 50 | secp256k1_scalar_clear(&s); 51 | return ret; 52 | } 53 | 54 | #endif /* SECP256K1_MODULE_ECDH_MAIN_H */ 55 | -------------------------------------------------------------------------------- /secp256k1/src/modules/ecdh/tests_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_MODULE_ECDH_TESTS_H 8 | #define SECP256K1_MODULE_ECDH_TESTS_H 9 | 10 | void test_ecdh_api(void) { 11 | /* Setup context that just counts errors */ 12 | secp256k1_context *tctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); 13 | secp256k1_pubkey point; 14 | unsigned char res[32]; 15 | unsigned char s_one[32] = { 0 }; 16 | int32_t ecount = 0; 17 | s_one[31] = 1; 18 | 19 | secp256k1_context_set_error_callback(tctx, counting_illegal_callback_fn, &ecount); 20 | secp256k1_context_set_illegal_callback(tctx, counting_illegal_callback_fn, &ecount); 21 | CHECK(secp256k1_ec_pubkey_create(tctx, &point, s_one) == 1); 22 | 23 | /* Check all NULLs are detected */ 24 | CHECK(secp256k1_ecdh(tctx, res, &point, s_one) == 1); 25 | CHECK(ecount == 0); 26 | CHECK(secp256k1_ecdh(tctx, NULL, &point, s_one) == 0); 27 | CHECK(ecount == 1); 28 | CHECK(secp256k1_ecdh(tctx, res, NULL, s_one) == 0); 29 | CHECK(ecount == 2); 30 | CHECK(secp256k1_ecdh(tctx, res, &point, NULL) == 0); 31 | CHECK(ecount == 3); 32 | CHECK(secp256k1_ecdh(tctx, res, &point, s_one) == 1); 33 | CHECK(ecount == 3); 34 | 35 | /* Cleanup */ 36 | secp256k1_context_destroy(tctx); 37 | } 38 | 39 | void test_ecdh_generator_basepoint(void) { 40 | unsigned char s_one[32] = { 0 }; 41 | secp256k1_pubkey point[2]; 42 | int i; 43 | 44 | s_one[31] = 1; 45 | /* Check against pubkey creation when the basepoint is the generator */ 46 | for (i = 0; i < 100; ++i) { 47 | secp256k1_sha256 sha; 48 | unsigned char s_b32[32]; 49 | unsigned char output_ecdh[32]; 50 | unsigned char output_ser[32]; 51 | unsigned char point_ser[33]; 52 | size_t point_ser_len = sizeof(point_ser); 53 | secp256k1_scalar s; 54 | 55 | random_scalar_order(&s); 56 | secp256k1_scalar_get_b32(s_b32, &s); 57 | 58 | /* compute using ECDH function */ 59 | CHECK(secp256k1_ec_pubkey_create(ctx, &point[0], s_one) == 1); 60 | CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32) == 1); 61 | /* compute "explicitly" */ 62 | CHECK(secp256k1_ec_pubkey_create(ctx, &point[1], s_b32) == 1); 63 | CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1); 64 | CHECK(point_ser_len == sizeof(point_ser)); 65 | secp256k1_sha256_initialize(&sha); 66 | secp256k1_sha256_write(&sha, point_ser, point_ser_len); 67 | secp256k1_sha256_finalize(&sha, output_ser); 68 | /* compare */ 69 | CHECK(memcmp(output_ecdh, output_ser, sizeof(output_ser)) == 0); 70 | } 71 | } 72 | 73 | void test_bad_scalar(void) { 74 | unsigned char s_zero[32] = { 0 }; 75 | unsigned char s_overflow[32] = { 76 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 77 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 78 | 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 79 | 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41 80 | }; 81 | unsigned char s_rand[32] = { 0 }; 82 | unsigned char output[32]; 83 | secp256k1_scalar rand; 84 | secp256k1_pubkey point; 85 | 86 | /* Create random point */ 87 | random_scalar_order(&rand); 88 | secp256k1_scalar_get_b32(s_rand, &rand); 89 | CHECK(secp256k1_ec_pubkey_create(ctx, &point, s_rand) == 1); 90 | 91 | /* Try to multiply it by bad values */ 92 | CHECK(secp256k1_ecdh(ctx, output, &point, s_zero) == 0); 93 | CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 0); 94 | /* ...and a good one */ 95 | s_overflow[31] -= 1; 96 | CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 1); 97 | } 98 | 99 | void run_ecdh_tests(void) { 100 | test_ecdh_api(); 101 | test_ecdh_generator_basepoint(); 102 | test_bad_scalar(); 103 | } 104 | 105 | #endif /* SECP256K1_MODULE_ECDH_TESTS_H */ 106 | -------------------------------------------------------------------------------- /secp256k1/src/modules/multiset/Makefile.am.include: -------------------------------------------------------------------------------- 1 | include_HEADERS += include/secp256k1_multiset.h 2 | noinst_HEADERS += src/modules/multiset/main_impl.h 3 | noinst_HEADERS += src/modules/multiset/tests_impl.h 4 | if USE_BENCHMARK 5 | noinst_PROGRAMS += bench_multiset 6 | bench_multiset_SOURCES = src/bench_multiset.c 7 | bench_multiset_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) 8 | endif 9 | -------------------------------------------------------------------------------- /secp256k1/src/modules/multiset/README.md: -------------------------------------------------------------------------------- 1 | Secp256k1 multiset module 2 | ========================= 3 | 4 | Abstract 5 | -------- 6 | 7 | This module allows calculating a cryptographically secure hash for a 8 | set with the properties: 9 | 10 | * The order of the elements of the set does not effect the hash 11 | * Elements can be added to the set without recalculating the entire set 12 | 13 | Or mathematically, it is: 14 | 15 | * Commutative: H(a,b) = H(b,a) 16 | * Associative: H(H(a,b),c) = H(a,H(b,c)) 17 | 18 | Hence it behaves similar to XORing the hashes of the individual elements, 19 | but without the cryptographic weakness of XOR. 20 | 21 | Motivation 22 | ---------- 23 | 24 | The multiset can be used by cryptocurrencies to cheaply create and 25 | maintain a commitment to the full UTXO set as proposed by Pieter Wiulle [1] 26 | 27 | It can also be used with a bucketed approach to enable cheap UTXO-proofs as 28 | proposed by Tomas van der Wansem [2] 29 | 30 | Usage 31 | ----- 32 | 33 | // Construct a multiset of (data1,data3) 34 | 35 | unsigned char data1[100],data2[150],data3[175]; 36 | ... 37 | secp256k1_multiset x,y; 38 | secp256k1_multiset_init (context, &x); 39 | 40 | // add all 3 data elements 41 | secp256k1_multiset_add(context, &y, data1, sizeof(data1)); 42 | secp256k1_multiset_add(context, &y, data2, sizeof(data2)); 43 | secp256k1_multiset_add(context, &y, data3, sizeof(data3)); 44 | 45 | // remove data2 46 | secp256k1_multiset_remove(context, &y, data2, sizeof(data2)); 47 | 48 | // convert to hash 49 | secp256k1_multiset_finalize(context, hashBuffer, &x); 50 | 51 | Algorithm 52 | --------- 53 | 54 | Using Elliptic Curves as multisets is described in [3]. 55 | 56 | This implementation uses trial-and-hash [4] to convert the hash into 57 | point on the secp256k1 curve which serves as multiset. The curve's 58 | group operations are then used to add and remove multisets. 59 | Associativity and Commutativity then follow. 60 | 61 | Security 62 | -------- 63 | The hash is secure against collision attacks. 64 | 65 | The algorithm used is susceptible to timing attacks. Therefore it does 66 | not securely conceal the underlying data being hashed. 67 | 68 | For the purpose of UTXO commitments this is not relevant. 69 | 70 | Faster and constant time algorithms exists [3] but only for char-2 curves. 71 | 72 | References 73 | ---------- 74 | 75 | [1] https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-May/014337.html 76 | 77 | [2] https://lists.linuxfoundation.org/pipermail/bitcoin-ml/2017-September/000240.html 78 | 79 | [3] https://arxiv.org/pdf/1601.06502.pdf 80 | 81 | [4] https://eprint.iacr.org/2009/226.pdf 82 | 83 | -------------------------------------------------------------------------------- /secp256k1/src/modules/multiset/main_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2017 Tomas van der Wansem * 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_MULTISET_MAIN_ 8 | #define _SECP256K1_MODULE_MULTISET_MAIN_ 9 | 10 | 11 | #include "include/secp256k1_multiset.h" 12 | 13 | #include "hash.h" 14 | #include "field.h" 15 | #include "group.h" 16 | 17 | /** Converts a group element (Jacobian) to a multiset. 18 | * Requires the field elements to be normalized 19 | * Infinite uses special value, z = 0 20 | */ 21 | static void multiset_from_gej_var(secp256k1_multiset *target, const secp256k1_gej *input) { 22 | if (input->infinity) { 23 | memset(&target->d, 0, sizeof(target->d)); 24 | } else { 25 | secp256k1_fe_get_b32(target->d, &input->x); 26 | secp256k1_fe_get_b32(target->d+32, &input->y); 27 | secp256k1_fe_get_b32(target->d+64, &input->z); 28 | } 29 | } 30 | 31 | /** Converts a multiset to group element (Jacobian) 32 | * Infinite uses special value, z = 0 33 | */ 34 | static void gej_from_multiset_var(secp256k1_gej *target, const secp256k1_multiset *input) { 35 | secp256k1_fe_set_b32(&target->x, input->d); 36 | secp256k1_fe_set_b32(&target->y, input->d+32); 37 | secp256k1_fe_set_b32(&target->z, input->d+64); 38 | 39 | target->infinity = secp256k1_fe_is_zero(&target->z) ? 1 : 0; 40 | } 41 | 42 | /** Converts a data element to a group element (affine) 43 | * 44 | * We use trial-and-rehash which is fast but non-constant time. 45 | * Though constant time algo's exist we are not concerned with timing attacks 46 | * as we make no attempt to hide the underlying data 47 | * 48 | * Pass inverse=0 to generate the group element, or inverse=1 to generate its inverse 49 | */ 50 | static void ge_from_data_var(secp256k1_ge *target, const unsigned char *input, size_t inputLen, int inverse) { 51 | secp256k1_sha256 hasher; 52 | unsigned char buffer[8+32]; 53 | unsigned char trial[32]; 54 | uint64_t prefix; 55 | 56 | /* Hash to buffer, leaving space for 8-byte prefix */ 57 | secp256k1_sha256_initialize(&hasher); 58 | secp256k1_sha256_write(&hasher, input, inputLen); 59 | secp256k1_sha256_finalize(&hasher, buffer+8); 60 | 61 | /* Loop through trials, with 50% success per loop 62 | * We can assume it ends within 2^64. */ 63 | for(prefix=0; 1; prefix++) 64 | { 65 | secp256k1_fe x; 66 | 67 | /* Set prefix in little-endian */ 68 | buffer[0] = prefix & 0xFF; 69 | buffer[1] = (prefix>>8) & 0xFF; 70 | buffer[2] = (prefix>>16) & 0xFF; 71 | buffer[3] = (prefix>>24) & 0xFF; 72 | buffer[4] = (prefix>>32) & 0xFF; 73 | buffer[5] = (prefix>>40) & 0xFF; 74 | buffer[6] = (prefix>>48) & 0xFF; 75 | buffer[7] = (prefix>>56) & 0xFF; 76 | 77 | /* Hash to trial */ 78 | secp256k1_sha256_initialize(&hasher); 79 | secp256k1_sha256_write(&hasher, buffer, sizeof(buffer)); 80 | secp256k1_sha256_finalize(&hasher, trial); 81 | 82 | if (!secp256k1_fe_set_b32(&x, trial)) { 83 | continue; 84 | } 85 | 86 | /* We let y is even be the element and odd be its inverse */ 87 | if (!secp256k1_ge_set_xo_var(target, &x, inverse)) { 88 | continue; 89 | } 90 | 91 | VERIFY_CHECK(secp256k1_ge_is_valid_var(target)); 92 | VERIFY_CHECK(!secp256k1_ge_is_infinity(target)); 93 | break; 94 | } 95 | } 96 | 97 | /** Adds or removes a data element */ 98 | static int multiset_add_remove(const secp256k1_context* ctx, secp256k1_multiset *multiset, const unsigned char *input, size_t inputLen, int remove) { 99 | secp256k1_ge newelm; 100 | secp256k1_gej source, target; 101 | 102 | VERIFY_CHECK(ctx != NULL); 103 | ARG_CHECK(multiset != NULL); 104 | ARG_CHECK(input != NULL); 105 | 106 | gej_from_multiset_var(&source, multiset); 107 | ge_from_data_var(&newelm, input, inputLen, remove); 108 | 109 | secp256k1_gej_add_ge_var(&target, &source, &newelm, NULL); 110 | 111 | secp256k1_fe_normalize(&target.x); 112 | secp256k1_fe_normalize(&target.y); 113 | secp256k1_fe_normalize(&target.z); 114 | multiset_from_gej_var(multiset, &target); 115 | 116 | return 1; 117 | } 118 | 119 | /** Adds a data element to the multiset */ 120 | int secp256k1_multiset_add(const secp256k1_context* ctx, secp256k1_multiset *multiset, const unsigned char *input, size_t inputLen) { 121 | return multiset_add_remove(ctx, multiset, input, inputLen, 0); 122 | } 123 | 124 | /** Removes a data element from the multiset */ 125 | int secp256k1_multiset_remove(const secp256k1_context* ctx, secp256k1_multiset *multiset, const unsigned char *input, size_t inputLen) { 126 | return multiset_add_remove(ctx, multiset, input, inputLen, 1); 127 | } 128 | 129 | /** Adds input multiset to multiset */ 130 | int secp256k1_multiset_combine(const secp256k1_context* ctx, secp256k1_multiset *multiset, const secp256k1_multiset *input) { 131 | secp256k1_gej gej_multiset, gej_input, gej_result; 132 | 133 | VERIFY_CHECK(ctx != NULL); 134 | ARG_CHECK(multiset != NULL); 135 | ARG_CHECK(input != NULL); 136 | 137 | gej_from_multiset_var(&gej_multiset, multiset); 138 | gej_from_multiset_var(&gej_input, input); 139 | 140 | secp256k1_gej_add_var(&gej_result, &gej_multiset, &gej_input, NULL); 141 | 142 | secp256k1_fe_normalize(&gej_result.x); 143 | secp256k1_fe_normalize(&gej_result.y); 144 | secp256k1_fe_normalize(&gej_result.z); 145 | multiset_from_gej_var(multiset, &gej_result); 146 | 147 | return 1; 148 | } 149 | 150 | /** Hash the multiset into resultHash */ 151 | int secp256k1_multiset_finalize(const secp256k1_context* ctx, unsigned char *resultHash, const secp256k1_multiset *multiset) { 152 | secp256k1_sha256 hasher; 153 | unsigned char buffer[64]; 154 | secp256k1_gej gej; 155 | secp256k1_ge ge; 156 | 157 | VERIFY_CHECK(ctx != NULL); 158 | ARG_CHECK(resultHash != NULL); 159 | ARG_CHECK(multiset != NULL); 160 | 161 | gej_from_multiset_var(&gej, multiset); 162 | 163 | if (gej.infinity) { 164 | /* empty set is encoded as zeros */ 165 | memset(resultHash, 0x00, 32); 166 | return 1; 167 | } 168 | 169 | /* we must normalize to affine first */ 170 | secp256k1_ge_set_gej(&ge, &gej); 171 | secp256k1_fe_normalize(&ge.x); 172 | secp256k1_fe_normalize(&ge.y); 173 | secp256k1_fe_get_b32(buffer, &ge.x); 174 | secp256k1_fe_get_b32(buffer+32, &ge.y); 175 | 176 | secp256k1_sha256_initialize(&hasher); 177 | secp256k1_sha256_write(&hasher, buffer, sizeof(buffer)); 178 | secp256k1_sha256_finalize(&hasher, resultHash); 179 | 180 | return 1; 181 | } 182 | 183 | /** Inits the multiset with the constant for empty data, 184 | * represented by the Jacobian GE infinite 185 | */ 186 | int secp256k1_multiset_init(const secp256k1_context* ctx, secp256k1_multiset *multiset) { 187 | const secp256k1_gej inf = SECP256K1_GEJ_CONST_INFINITY; 188 | 189 | VERIFY_CHECK(ctx != NULL); 190 | 191 | multiset_from_gej_var(multiset, &inf); 192 | 193 | return 1; 194 | } 195 | 196 | #endif /* _SECP256K1_MODULE_MULTISET_MAIN_ */ 197 | -------------------------------------------------------------------------------- /secp256k1/src/modules/recovery/Makefile.am.include: -------------------------------------------------------------------------------- 1 | include_HEADERS += include/secp256k1_recovery.h 2 | noinst_HEADERS += src/modules/recovery/main_impl.h 3 | noinst_HEADERS += src/modules/recovery/tests_impl.h 4 | if USE_BENCHMARK 5 | noinst_PROGRAMS += bench_recover 6 | bench_recover_SOURCES = src/bench_recover.c 7 | bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) 8 | endif 9 | -------------------------------------------------------------------------------- /secp256k1/src/modules/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 | -------------------------------------------------------------------------------- /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 | #ifndef USE_NUM_NONE 11 | 12 | #if defined HAVE_CONFIG_H 13 | #include "libsecp256k1-config.h" 14 | #endif 15 | 16 | #if defined(USE_NUM_GMP) 17 | #include "num_gmp.h" 18 | #else 19 | #error "Please select num implementation" 20 | #endif 21 | 22 | /** Copy a number. */ 23 | static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a); 24 | 25 | /** Convert a number's absolute value to a binary big-endian string. 26 | * There must be enough place. */ 27 | static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a); 28 | 29 | /** Set a number to the value of a binary big-endian string. */ 30 | static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen); 31 | 32 | /** Compute a modular inverse. The input must be less than the modulus. */ 33 | static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m); 34 | 35 | /** Compute the jacobi symbol (a|b). b must be positive and odd. */ 36 | static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b); 37 | 38 | /** Compare the absolute value of two numbers. */ 39 | static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b); 40 | 41 | /** Test whether two number are equal (including sign). */ 42 | static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b); 43 | 44 | /** Add two (signed) numbers. */ 45 | static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 46 | 47 | /** Subtract two (signed) numbers. */ 48 | static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 49 | 50 | /** Multiply two (signed) numbers. */ 51 | static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 52 | 53 | /** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1, 54 | even if r was negative. */ 55 | static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m); 56 | 57 | /** Right-shift the passed number by bits bits. */ 58 | static void secp256k1_num_shift(secp256k1_num *r, int bits); 59 | 60 | /** Check whether a number is zero. */ 61 | static int secp256k1_num_is_zero(const secp256k1_num *a); 62 | 63 | /** Check whether a number is one. */ 64 | static int secp256k1_num_is_one(const secp256k1_num *a); 65 | 66 | /** Check whether a number is strictly negative. */ 67 | static int secp256k1_num_is_neg(const secp256k1_num *a); 68 | 69 | /** Change a number's sign. */ 70 | static void secp256k1_num_negate(secp256k1_num *r); 71 | 72 | #endif 73 | 74 | #endif /* SECP256K1_NUM_H */ 75 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | #if defined(EXHAUSTIVE_TEST_ORDER) 17 | #include "scalar_low.h" 18 | #elif defined(USE_SCALAR_4X64) 19 | #include "scalar_4x64.h" 20 | #elif defined(USE_SCALAR_8X32) 21 | #include "scalar_8x32.h" 22 | #else 23 | #error "Please select scalar implementation" 24 | #endif 25 | 26 | /** Clear a scalar to prevent the leak of sensitive data. */ 27 | static void secp256k1_scalar_clear(secp256k1_scalar *r); 28 | 29 | /** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */ 30 | static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count); 31 | 32 | /** Access bits from a scalar. Not constant time. */ 33 | static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count); 34 | 35 | /** Set a scalar from a big endian byte array. */ 36 | static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow); 37 | 38 | /** Set a scalar to an unsigned integer. */ 39 | static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v); 40 | 41 | /** Convert a scalar to a byte array. */ 42 | static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a); 43 | 44 | /** Add two scalars together (modulo the group order). Returns whether it overflowed. */ 45 | static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); 46 | 47 | /** Conditionally add a power of two to a scalar. The result is not allowed to overflow. */ 48 | static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag); 49 | 50 | /** Multiply two scalars (modulo the group order). */ 51 | static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); 52 | 53 | /** Shift a scalar right by some amount strictly between 0 and 16, returning 54 | * the low bits that were shifted off */ 55 | static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n); 56 | 57 | /** Compute the square of a scalar (modulo the group order). */ 58 | static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a); 59 | 60 | /** Compute the inverse of a scalar (modulo the group order). */ 61 | static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *a); 62 | 63 | /** Compute the inverse of a scalar (modulo the group order), without constant-time guarantee. */ 64 | static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *a); 65 | 66 | /** Compute the complement of a scalar (modulo the group order). */ 67 | static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a); 68 | 69 | /** Check whether a scalar equals zero. */ 70 | static int secp256k1_scalar_is_zero(const secp256k1_scalar *a); 71 | 72 | /** Check whether a scalar equals one. */ 73 | static int secp256k1_scalar_is_one(const secp256k1_scalar *a); 74 | 75 | /** Check whether a scalar, considered as an nonnegative integer, is even. */ 76 | static int secp256k1_scalar_is_even(const secp256k1_scalar *a); 77 | 78 | /** Check whether a scalar is higher than the group order divided by 2. */ 79 | static int secp256k1_scalar_is_high(const secp256k1_scalar *a); 80 | 81 | /** Conditionally negate a number, in constant time. 82 | * Returns -1 if the number was negated, 1 otherwise */ 83 | static int secp256k1_scalar_cond_negate(secp256k1_scalar *a, int flag); 84 | 85 | #ifndef USE_NUM_NONE 86 | /** Convert a scalar to a number. */ 87 | static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a); 88 | 89 | /** Get the order of the group as a number. */ 90 | static void secp256k1_scalar_order_get_num(secp256k1_num *r); 91 | #endif 92 | 93 | /** Compare two scalars. */ 94 | static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b); 95 | 96 | #ifdef USE_ENDOMORPHISM 97 | /** Find r1 and r2 such that r1+r2*2^128 = a. */ 98 | static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); 99 | /** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (see secp256k1_gej_mul_lambda). */ 100 | static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); 101 | #endif 102 | 103 | /** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */ 104 | static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift); 105 | 106 | #endif /* SECP256K1_SCALAR_H */ 107 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 "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 | -------------------------------------------------------------------------------- /secp256k1/src/testrand.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_TESTRAND_H 8 | #define SECP256K1_TESTRAND_H 9 | 10 | #if defined HAVE_CONFIG_H 11 | #include "libsecp256k1-config.h" 12 | #endif 13 | 14 | /* A non-cryptographic RNG used only for test infrastructure. */ 15 | 16 | /** Seed the pseudorandom number generator for testing. */ 17 | SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16); 18 | 19 | /** Generate a pseudorandom number in the range [0..2**32-1]. */ 20 | static uint32_t secp256k1_rand32(void); 21 | 22 | /** Generate a pseudorandom number in the range [0..2**bits-1]. Bits must be 1 or 23 | * more. */ 24 | static uint32_t secp256k1_rand_bits(int bits); 25 | 26 | /** Generate a pseudorandom number in the range [0..range-1]. */ 27 | static uint32_t secp256k1_rand_int(uint32_t range); 28 | 29 | /** Generate a pseudorandom 32-byte array. */ 30 | static void secp256k1_rand256(unsigned char *b32); 31 | 32 | /** Generate a pseudorandom 32-byte array with long sequences of zero and one bits. */ 33 | static void secp256k1_rand256_test(unsigned char *b32); 34 | 35 | /** Generate pseudorandom bytes with long sequences of zero and one bits. */ 36 | static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len); 37 | 38 | #endif /* SECP256K1_TESTRAND_H */ 39 | -------------------------------------------------------------------------------- /secp256k1/src/testrand_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_TESTRAND_IMPL_H 8 | #define SECP256K1_TESTRAND_IMPL_H 9 | 10 | #include 11 | #include 12 | 13 | #include "testrand.h" 14 | #include "hash.h" 15 | 16 | static secp256k1_rfc6979_hmac_sha256 secp256k1_test_rng; 17 | static uint32_t secp256k1_test_rng_precomputed[8]; 18 | static int secp256k1_test_rng_precomputed_used = 8; 19 | static uint64_t secp256k1_test_rng_integer; 20 | static int secp256k1_test_rng_integer_bits_left = 0; 21 | 22 | SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16) { 23 | secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, seed16, 16); 24 | } 25 | 26 | SECP256K1_INLINE static uint32_t secp256k1_rand32(void) { 27 | if (secp256k1_test_rng_precomputed_used == 8) { 28 | secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, (unsigned char*)(&secp256k1_test_rng_precomputed[0]), sizeof(secp256k1_test_rng_precomputed)); 29 | secp256k1_test_rng_precomputed_used = 0; 30 | } 31 | return secp256k1_test_rng_precomputed[secp256k1_test_rng_precomputed_used++]; 32 | } 33 | 34 | static uint32_t secp256k1_rand_bits(int bits) { 35 | uint32_t ret; 36 | if (secp256k1_test_rng_integer_bits_left < bits) { 37 | secp256k1_test_rng_integer |= (((uint64_t)secp256k1_rand32()) << secp256k1_test_rng_integer_bits_left); 38 | secp256k1_test_rng_integer_bits_left += 32; 39 | } 40 | ret = secp256k1_test_rng_integer; 41 | secp256k1_test_rng_integer >>= bits; 42 | secp256k1_test_rng_integer_bits_left -= bits; 43 | ret &= ((~((uint32_t)0)) >> (32 - bits)); 44 | return ret; 45 | } 46 | 47 | static uint32_t secp256k1_rand_int(uint32_t range) { 48 | /* We want a uniform integer between 0 and range-1, inclusive. 49 | * B is the smallest number such that range <= 2**B. 50 | * two mechanisms implemented here: 51 | * - generate B bits numbers until one below range is found, and return it 52 | * - find the largest multiple M of range that is <= 2**(B+A), generate B+A 53 | * bits numbers until one below M is found, and return it modulo range 54 | * The second mechanism consumes A more bits of entropy in every iteration, 55 | * but may need fewer iterations due to M being closer to 2**(B+A) then 56 | * range is to 2**B. The array below (indexed by B) contains a 0 when the 57 | * first mechanism is to be used, and the number A otherwise. 58 | */ 59 | static const int addbits[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0}; 60 | uint32_t trange, mult; 61 | int bits = 0; 62 | if (range <= 1) { 63 | return 0; 64 | } 65 | trange = range - 1; 66 | while (trange > 0) { 67 | trange >>= 1; 68 | bits++; 69 | } 70 | if (addbits[bits]) { 71 | bits = bits + addbits[bits]; 72 | mult = ((~((uint32_t)0)) >> (32 - bits)) / range; 73 | trange = range * mult; 74 | } else { 75 | trange = range; 76 | mult = 1; 77 | } 78 | while(1) { 79 | uint32_t x = secp256k1_rand_bits(bits); 80 | if (x < trange) { 81 | return (mult == 1) ? x : (x % range); 82 | } 83 | } 84 | } 85 | 86 | static void secp256k1_rand256(unsigned char *b32) { 87 | secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, b32, 32); 88 | } 89 | 90 | static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len) { 91 | size_t bits = 0; 92 | memset(bytes, 0, len); 93 | while (bits < len * 8) { 94 | int now; 95 | uint32_t val; 96 | now = 1 + (secp256k1_rand_bits(6) * secp256k1_rand_bits(5) + 16) / 31; 97 | val = secp256k1_rand_bits(1); 98 | while (now > 0 && bits < len * 8) { 99 | bytes[bits / 8] |= val << (bits % 8); 100 | now--; 101 | bits++; 102 | } 103 | } 104 | } 105 | 106 | static void secp256k1_rand256_test(unsigned char *b32) { 107 | secp256k1_rand_bytes_test(b32, 32); 108 | } 109 | 110 | #endif /* SECP256K1_TESTRAND_IMPL_H */ 111 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/addresses.hpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2017-2018 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | #ifndef DISABLE_ADDRESSES 9 | 10 | #ifndef BITCOIN_ADDRESSES_HPP 11 | #define BITCOIN_ADDRESSES_HPP 12 | 13 | #include "mutex.hpp" 14 | #include "hash.hpp" 15 | #include "hash_data_set.hpp" 16 | #include "distributed_vector.hpp" 17 | #include "log.hpp" 18 | #include "base.hpp" 19 | #include "transaction.hpp" 20 | #include "info.hpp" 21 | 22 | #include 23 | 24 | #define BITCOIN_ADDRESSES_LOG_NAME "Address" 25 | 26 | 27 | namespace BitCoin 28 | { 29 | class FullOutputData 30 | { 31 | public: 32 | 33 | FullOutputData() {} 34 | FullOutputData(const FullOutputData &pCopy) : transactionID(pCopy.transactionID), 35 | output(pCopy.output) 36 | { 37 | blockHeight = pCopy.blockHeight; 38 | index = pCopy.index; 39 | } 40 | FullOutputData(unsigned int pBlockHeight, const NextCash::Hash &pTransactionID, 41 | unsigned int pIndex, Output &pOutput) 42 | { 43 | blockHeight = pBlockHeight; 44 | transactionID = pTransactionID; 45 | index = pIndex; 46 | output = pOutput; 47 | } 48 | 49 | FullOutputData &operator = (const FullOutputData &pRight) 50 | { 51 | blockHeight = pRight.blockHeight; 52 | transactionID = pRight.transactionID; 53 | index = pRight.index; 54 | output = pRight.output; 55 | return *this; 56 | } 57 | 58 | void print(); 59 | 60 | unsigned int blockHeight; 61 | NextCash::Hash transactionID; 62 | unsigned int index; 63 | Output output; 64 | }; 65 | 66 | class AddressOutputReference : public NextCash::HashData 67 | { 68 | public: 69 | 70 | static const unsigned int SIZE = 12; 71 | 72 | AddressOutputReference() {} 73 | AddressOutputReference(uint32_t pBlockHeight, uint32_t pTransactionOffset, 74 | uint32_t pOutputIndex) 75 | { 76 | blockHeight = pBlockHeight; 77 | transactionOffset = pTransactionOffset; 78 | outputIndex = pOutputIndex; 79 | } 80 | 81 | void set(uint32_t pBlockHeight, uint32_t pTransactionOffset, uint32_t pOutputIndex) 82 | { 83 | blockHeight = pBlockHeight; 84 | transactionOffset = pTransactionOffset; 85 | outputIndex = pOutputIndex; 86 | } 87 | 88 | bool getFullOutput(FullOutputData &pOutput) const; 89 | 90 | NextCash::stream_size size() const { return 12; } 91 | 92 | // Evaluates the relative age of two objects. 93 | // Used to determine which objects to drop from cache 94 | // Negative means this object is older than pRight. 95 | // Zero means both objects are the same age. 96 | // Positive means this object is newer than pRight. 97 | int compareAge(NextCash::HashData *pRight) 98 | { 99 | if(blockHeight < ((AddressOutputReference *)pRight)->blockHeight) 100 | return -1; 101 | else if(blockHeight > ((AddressOutputReference *)pRight)->blockHeight) 102 | return 1; 103 | else 104 | return 0; 105 | } 106 | 107 | // Returns true if the value of this object matches the value pRight references 108 | bool valuesMatch(const HashData *pRight) const 109 | { 110 | return blockHeight == ((AddressOutputReference *)pRight)->blockHeight && 111 | transactionOffset == ((AddressOutputReference *)pRight)->transactionOffset && 112 | outputIndex == ((AddressOutputReference *)pRight)->outputIndex; 113 | } 114 | 115 | // Reads object data from a stream 116 | bool read(NextCash::InputStream *pStream) 117 | { 118 | if(pStream->remaining() < 12) 119 | return false; 120 | blockHeight = pStream->readUnsignedInt(); 121 | transactionOffset = pStream->readUnsignedInt(); 122 | outputIndex = pStream->readUnsignedInt(); 123 | return true; 124 | } 125 | 126 | // Writes object data to a stream 127 | bool write(NextCash::OutputStream *pStream) 128 | { 129 | pStream->writeUnsignedInt(blockHeight); 130 | pStream->writeUnsignedInt(transactionOffset); 131 | pStream->writeUnsignedInt(outputIndex); 132 | return true; 133 | } 134 | 135 | uint32_t blockHeight; 136 | uint32_t transactionOffset; 137 | uint32_t outputIndex; 138 | }; 139 | 140 | /* Data set of address hashes and the transaction outputs associated with them 141 | */ 142 | class Addresses : public NextCash::HashDataSet 143 | { 144 | public: 145 | 146 | unsigned int subSetOffset(const NextCash::Hash &pLookupValue) 147 | { 148 | return pLookupValue.lookup16() & 0x3ff; 149 | } 150 | 151 | Addresses() : HashDataSet("Addresses") 152 | { mNextBlockHeight = 0; mMaxCacheSize = Info::instance().addressesCacheSize; } 153 | ~Addresses() {} 154 | 155 | unsigned int height() 156 | { 157 | if(mNextBlockHeight == 0) 158 | return 0xffffffff; 159 | else 160 | return mNextBlockHeight - 1; 161 | } 162 | 163 | bool add(std::vector &pBlockTransactions, unsigned int pBlockHeight); 164 | bool remove(std::vector &pBlockTransactions, unsigned int pBlockHeight); 165 | 166 | // Get transaction outputs associated with the specified public key address hash 167 | bool getOutputs(const NextCash::Hash &pAddress, std::vector &pOutputs); 168 | 169 | bool needsPurge() { return cacheDataSize() > mMaxCacheSize; } 170 | 171 | bool load(const char *pFilePath, uint64_t pCacheDataTargetSize); 172 | bool save(unsigned int pThreadCount); 173 | 174 | private: 175 | 176 | unsigned int mNextBlockHeight; 177 | uint64_t mMaxCacheSize; 178 | 179 | }; 180 | } 181 | 182 | #endif 183 | 184 | #endif 185 | -------------------------------------------------------------------------------- /src/bloom_filter.hpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2018 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | #ifndef BITCOIN_BLOOM_HPP 9 | #define BITCOIN_BLOOM_HPP 10 | 11 | #include "hash.hpp" 12 | #include "math.hpp" 13 | #include "buffer.hpp" 14 | #include "stream.hpp" 15 | #include "digest.hpp" 16 | #include "transaction.hpp" 17 | 18 | 19 | namespace BitCoin 20 | { 21 | class BloomFilter 22 | { 23 | public: 24 | 25 | enum Format 26 | { 27 | STANDARD, 28 | GRAPHENE 29 | }; 30 | 31 | enum Flags 32 | { 33 | UPDATE_NONE = 0, 34 | UPDATE_ALL = 1, 35 | UPDATE_P2PUBKEY_ONLY = 2, // Only adds outpoints to the filter if the output is a pay-to-pubkey/pay-to-multisig script 36 | UPDATE_MASK = 3 37 | }; 38 | 39 | static const unsigned int MAX_SIZE; // bytes 40 | static const unsigned int MAX_FUNCTIONS; 41 | static const unsigned int MIN_FUNCTIONS; 42 | 43 | BloomFilter(Format pFormat) 44 | { 45 | mFormat = pFormat; 46 | mData = NULL; 47 | mDataSize = 0; 48 | mHashFunctionCount = 0; 49 | mTweak = 0; 50 | mFlags = 0; 51 | mIsFull = false; 52 | mIsEmpty = true; 53 | } 54 | BloomFilter(const BloomFilter &pCopy) 55 | { 56 | mFormat = pCopy.mFormat; 57 | mData = NULL; 58 | mDataSize = pCopy.mDataSize; 59 | mHashFunctionCount = pCopy.mHashFunctionCount; 60 | mTweak = pCopy.mTweak; 61 | mFlags = pCopy.mFlags; 62 | mIsFull = pCopy.mIsFull; 63 | mIsEmpty = pCopy.mIsEmpty; 64 | 65 | if(mDataSize) 66 | { 67 | mData = new unsigned char[mDataSize]; 68 | std::memcpy(mData, pCopy.mData, mDataSize); 69 | } 70 | } 71 | BloomFilter(Format pFormat, unsigned int pElementCount, unsigned char pFlags = UPDATE_NONE, 72 | double pFalsePositiveRate = 0.00001, unsigned int pTweak = NextCash::Math::randomInt()); 73 | ~BloomFilter(); 74 | 75 | const BloomFilter &operator = (const BloomFilter &pRight); 76 | 77 | void setup(unsigned int pElementCount, unsigned char pFlags = UPDATE_NONE, 78 | double pFalsePositiveRate = 0.00001, unsigned int pTweak = NextCash::Math::randomInt()); 79 | 80 | bool isEmpty() const { return mIsEmpty; } 81 | bool isFull() const { return mIsFull; } 82 | 83 | bool flags() const { return mFlags; } 84 | const unsigned char *data() const { return mData; } 85 | unsigned int size() const { return mDataSize; } 86 | unsigned int functionCount() const { return mHashFunctionCount; } 87 | unsigned int tweak() const { return mTweak; } 88 | void updateStatus(); 89 | 90 | void add(const NextCash::Hash &pHash); 91 | void add(Outpoint &pOutpoint); 92 | void addData(NextCash::Buffer &pData); 93 | void addScript(NextCash::Buffer &pScript); 94 | 95 | bool contains(const NextCash::Hash &pHash) const; 96 | bool contains(Outpoint &pOutpoint) const; 97 | bool contains(Transaction &pTransaction) const; 98 | bool contains(TransactionReference &pTransaction) const; 99 | bool containsScript(NextCash::Buffer &pScript) const; 100 | 101 | void write(NextCash::OutputStream *pStream) const; 102 | bool read(NextCash::InputStream *pStream); 103 | 104 | void clear(); 105 | void assign(BloomFilter &pValue); // Removes data from pValue 106 | void copy(BloomFilter &pValue); // Makes equivalent to pValue 107 | 108 | static bool test(); 109 | 110 | private: 111 | 112 | unsigned int bitOffset(unsigned int pHashNum, const NextCash::Hash &pHash) const 113 | { 114 | return NextCash::Digest::murMur3(pHash.data(), pHash.size(), 115 | pHashNum * 0xFBA4C795 + mTweak) % (mDataSize * 8); 116 | } 117 | 118 | unsigned int bitOffset(unsigned int pHashNum, const uint8_t *pData, 119 | NextCash::stream_size pDataSize) const 120 | { 121 | return NextCash::Digest::murMur3(pData, pDataSize, pHashNum * 0xFBA4C795 + mTweak) % 122 | (mDataSize * 8); 123 | } 124 | 125 | unsigned int bitOffset(unsigned int pHashNum, NextCash::Buffer &pData) const 126 | { 127 | return NextCash::Digest::murMur3(pData.begin(), pData.length(), 128 | pHashNum * 0xFBA4C795 + mTweak) % (mDataSize * 8); 129 | } 130 | 131 | Format mFormat; 132 | unsigned char *mData; 133 | unsigned int mDataSize; 134 | unsigned int mHashFunctionCount; 135 | unsigned int mTweak; 136 | unsigned char mFlags; 137 | 138 | bool mIsFull; 139 | bool mIsEmpty; 140 | 141 | }; 142 | } 143 | 144 | #endif 145 | -------------------------------------------------------------------------------- /src/bloom_lookup.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2018 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | #include "bloom_lookup.hpp" 9 | 10 | #include "base.hpp" 11 | #include "digest.hpp" 12 | 13 | 14 | namespace BitCoin 15 | { 16 | bool BloomHashEntry::isPure() const 17 | { 18 | if(mCount != 1 && mCount != -1) 19 | return false; 20 | 21 | NextCash::Digest digest(NextCash::Digest::MURMUR3); 22 | digest.setOutputEndian(NextCash::Endian::LITTLE); 23 | digest.initialize(HASH_CHECK); 24 | digest.writeUnsignedLong(mKeySum); 25 | return mKeyCheck == digest.getResult(); 26 | } 27 | 28 | bool BloomHashEntry::empty() const 29 | { 30 | return mCount == 0 && mKeySum == 0UL && mKeyCheck == 0; 31 | } 32 | 33 | void BloomHashEntry::addValue(NextCash::InputStream *pStream, NextCash::stream_size pSize) 34 | { 35 | if(pSize == 0) 36 | return; 37 | 38 | if(mValueSum.length() < pSize) 39 | { 40 | mValueSum.setSize(pSize); 41 | mValueSum.setWriteOffset(mValueSum.length()); 42 | while(mValueSum.length() < pSize) 43 | mValueSum.writeByte(0); 44 | } 45 | 46 | mValueSum.setReadOffset(0); 47 | mValueSum.setWriteOffset(0); 48 | for(NextCash::stream_size i = 0; i < pSize; ++i) 49 | mValueSum.writeByte(mValueSum.readByte() ^ pStream->readByte()); 50 | } 51 | 52 | void BloomHashEntry::addValue(uint64_t pValue) 53 | { 54 | if(mValueSum.length() < 8) 55 | { 56 | mValueSum.setSize(8); 57 | mValueSum.setWriteOffset(mValueSum.length()); 58 | while(mValueSum.length() < 8) 59 | mValueSum.writeByte(0); 60 | } 61 | 62 | mValueSum.setReadOffset(0); 63 | mValueSum.setWriteOffset(0); 64 | uint8_t *byte = (uint8_t *)&pValue; 65 | if(NextCash::Endian::sSystemType != NextCash::Endian::LITTLE) 66 | { 67 | byte += 7; 68 | for(NextCash::stream_size i = 0; i < 8; ++i, --byte) 69 | mValueSum.writeByte(mValueSum.readByte() ^ *byte); 70 | } 71 | else 72 | { 73 | for(NextCash::stream_size i = 0; i < 8; ++i, ++byte) 74 | mValueSum.writeByte(mValueSum.readByte() ^ *byte); 75 | } 76 | } 77 | 78 | void BloomHashEntry::write(NextCash::OutputStream *pStream) 79 | { 80 | pStream->writeInt(mCount); 81 | pStream->writeUnsignedLong(mKeySum); 82 | pStream->writeUnsignedInt(mKeyCheck); 83 | 84 | writeCompactInteger(pStream, mValueSum.length()); 85 | mValueSum.setReadOffset(0); 86 | pStream->writeStream(&mValueSum, mValueSum.length()); 87 | } 88 | 89 | bool BloomHashEntry::read(NextCash::InputStream *pStream) 90 | { 91 | if(pStream->remaining() < 17) 92 | return false; 93 | mCount = pStream->readInt(); 94 | mKeySum = pStream->readUnsignedLong(); 95 | mKeyCheck = pStream->readUnsignedInt(); 96 | 97 | mValueSum.clear(); 98 | NextCash::stream_size valueSumLength = readCompactInteger(pStream); 99 | if(pStream->remaining() < valueSumLength) 100 | return false; 101 | pStream->readStream(&mValueSum, valueSumLength); 102 | return true; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/bloom_lookup.hpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2018 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | #ifndef BITCOIN_BLOOM_LOOKUP_HPP 9 | #define BITCOIN_BLOOM_LOOKUP_HPP 10 | 11 | #include "buffer.hpp" 12 | #include "stream.hpp" 13 | 14 | #include 15 | 16 | 17 | namespace BitCoin 18 | { 19 | class BloomHashEntry 20 | { 21 | public: 22 | 23 | BloomHashEntry() 24 | { 25 | mCount = 0; 26 | mKeySum = 0UL; 27 | mKeyCheck = 0; 28 | } 29 | BloomHashEntry(const BloomHashEntry &pCopy) : mValueSum(pCopy.mValueSum) 30 | { 31 | mCount = pCopy.mCount; 32 | mKeySum = pCopy.mKeySum; 33 | mKeyCheck = pCopy.mKeyCheck; 34 | } 35 | 36 | bool isPure() const; 37 | bool empty() const; 38 | void addValue(NextCash::InputStream *pStream, NextCash::stream_size pSize); 39 | void addValue(uint64_t pValue); 40 | 41 | void write(NextCash::OutputStream *pStream); 42 | bool read(NextCash::InputStream *pStream); 43 | 44 | private: 45 | 46 | static const uint32_t HASH_CHECK = 11; 47 | 48 | int32_t mCount; 49 | uint64_t mKeySum; 50 | uint32_t mKeyCheck; 51 | NextCash::Buffer mValueSum; 52 | 53 | }; 54 | 55 | class BloomLookup 56 | { 57 | public: 58 | 59 | BloomLookup() 60 | { 61 | mVersion = 0UL; 62 | mHashCount = 0; 63 | mIsModified = false; 64 | } 65 | BloomLookup(const BloomLookup &pCopy) : mTable(pCopy.mTable) 66 | { 67 | mVersion = pCopy.mVersion; 68 | mHashCount = pCopy.mHashCount; 69 | mIsModified = pCopy.mIsModified; 70 | } 71 | BloomLookup(NextCash::stream_size pSize); 72 | 73 | void reset(); 74 | NextCash::stream_size size() const; 75 | void resize(NextCash::stream_size pSize); 76 | 77 | // void insert(uint64_t pKey, ) 78 | 79 | BloomLookup operator - (const BloomLookup &pRight) const; 80 | 81 | 82 | private: 83 | 84 | uint64_t mVersion; 85 | uint8_t mHashCount; 86 | bool mIsModified; 87 | 88 | std::vector mTable; 89 | 90 | }; 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /src/header.hpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2017-2018 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | #ifndef BITCOIN_HEADER_HPP 9 | #define BITCOIN_HEADER_HPP 10 | 11 | #include "hash.hpp" 12 | #include "log.hpp" 13 | #include "stream.hpp" 14 | #include "file_stream.hpp" 15 | #include "base.hpp" 16 | #include "forks.hpp" 17 | 18 | 19 | namespace BitCoin 20 | { 21 | // Statistical information needed from each header. 22 | class HeaderStat 23 | { 24 | public: 25 | 26 | HeaderStat() : accumulatedWork(32) 27 | { 28 | version = 0; 29 | time = 0; 30 | targetBits = 0; 31 | } 32 | HeaderStat(const HeaderStat &pCopy) : accumulatedWork(pCopy.accumulatedWork) 33 | { 34 | version = pCopy.version; 35 | time = pCopy.time; 36 | targetBits = pCopy.targetBits; 37 | } 38 | HeaderStat(int32_t pVersion, Time pTime, uint32_t pTargetBits) : accumulatedWork(32) 39 | { 40 | version = pVersion; 41 | time = pTime; 42 | targetBits = pTargetBits; 43 | 44 | NextCash::Hash target(32); 45 | target.setDifficulty(pTargetBits); 46 | target.getWork(accumulatedWork); 47 | } 48 | HeaderStat(int32_t pVersion, Time pTime, uint32_t pTargetBits, 49 | NextCash::Hash &pPreviousAccumulatedWork) : accumulatedWork(32) 50 | { 51 | version = pVersion; 52 | time = pTime; 53 | targetBits = pTargetBits; 54 | 55 | NextCash::Hash target(32); 56 | target.setDifficulty(pTargetBits); 57 | target.getWork(accumulatedWork); 58 | 59 | accumulatedWork += pPreviousAccumulatedWork; 60 | } 61 | 62 | HeaderStat &operator = (const HeaderStat &pRight) 63 | { 64 | version = pRight.version; 65 | time = pRight.time; 66 | targetBits = pRight.targetBits; 67 | accumulatedWork = pRight.accumulatedWork; 68 | return *this; 69 | } 70 | 71 | int32_t version; 72 | Time time; 73 | uint32_t targetBits; 74 | NextCash::Hash accumulatedWork; 75 | }; 76 | 77 | class Header; 78 | typedef std::vector
HeaderList; 79 | 80 | class Header 81 | { 82 | public: 83 | 84 | Header() : previousHash(32), merkleHash(32) 85 | { 86 | version = 4; 87 | time = 0; 88 | targetBits = 0; 89 | nonce = 0; 90 | transactionCount = 0; 91 | } 92 | Header(const Header &pCopy) : previousHash(pCopy.previousHash), 93 | merkleHash(pCopy.merkleHash), mHash(pCopy.mHash) 94 | { 95 | version = pCopy.version; 96 | time = pCopy.time; 97 | targetBits = pCopy.targetBits; 98 | nonce = pCopy.nonce; 99 | transactionCount = pCopy.transactionCount; 100 | } 101 | 102 | Header &operator = (const Header &pRight) 103 | { 104 | mHash = pRight.mHash; 105 | version = pRight.version; 106 | previousHash = pRight.previousHash; 107 | merkleHash = pRight.merkleHash; 108 | time = pRight.time; 109 | targetBits = pRight.targetBits; 110 | nonce = pRight.nonce; 111 | transactionCount = pRight.transactionCount; 112 | return *this; 113 | } 114 | 115 | // Verify hash is lower than target difficulty specified by targetBits 116 | bool hasProofOfWork(); 117 | 118 | void write(NextCash::OutputStream *pStream, bool pIncludeTransactionCount) const; 119 | 120 | // pCalculateHash will calculate the hash of the block data while it reads it 121 | bool read(NextCash::InputStream *pStream, bool pIncludeTransactionCount); 122 | 123 | void clear(); 124 | 125 | // Print human readable version to log. 126 | void print(NextCash::Log::Level pLevel = NextCash::Log::DEBUG); 127 | 128 | const NextCash::Hash &hash() { if(mHash.isEmpty()) calculateHash(); return mHash; } 129 | 130 | // Header 131 | int32_t version; 132 | NextCash::Hash previousHash; 133 | NextCash::Hash merkleHash; 134 | Time time; 135 | uint32_t targetBits; 136 | uint32_t nonce; 137 | 138 | // Optional transaction count. 139 | uint32_t transactionCount; // Compact Integer, written as 32 bit locally 140 | 141 | void calculateHash(); 142 | 143 | static unsigned int totalCount(); 144 | 145 | // Get header from appropriate header file. 146 | static bool getHeader(unsigned int pHeight, Header &pHeader); 147 | static bool getHeaders(unsigned int pStartHeight, unsigned int pCount, 148 | HeaderList &pHeaders); 149 | 150 | // Get hash 151 | static bool getHash(unsigned int pHeight, NextCash::Hash &pHash); 152 | 153 | // Get hashes 154 | static bool getHashes(unsigned int pStartHeight, unsigned int pCount, 155 | NextCash::HashList &pList); 156 | 157 | // Get target bits 158 | static bool getTargetBits(unsigned int pStartHeight, unsigned int pCount, 159 | std::vector &pTargetBits); 160 | 161 | // Get block stats (in reverse order) 162 | static bool getHeaderStatsReverse(unsigned int pStartHeight, unsigned int pCount, 163 | std::list &pHeaderStats); 164 | 165 | // Add header to appropriate header file. 166 | static bool add(unsigned int pHeight, Header &pHeader); 167 | 168 | static bool revertToHeight(unsigned int pHeight); 169 | 170 | // Validate header file CRCs and revert to last valid. 171 | // Returns valid header count. 172 | static unsigned int validate(bool &pAbort); 173 | 174 | static void save(); // Save any unsaved data in files (i.e. update CRCs) 175 | static void clean(); // Release any static cache data 176 | 177 | private: 178 | 179 | NextCash::Hash mHash; 180 | 181 | }; 182 | } 183 | 184 | #endif 185 | -------------------------------------------------------------------------------- /src/info.hpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2017-2018 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | #ifndef BITCOIN_INFO_HPP 9 | #define BITCOIN_INFO_HPP 10 | 11 | #include "string.hpp" 12 | #include "mutex.hpp" 13 | #include "buffer.hpp" 14 | #include "base.hpp" 15 | #include "peer.hpp" 16 | #include "block.hpp" 17 | #include "sorted_set.hpp" 18 | 19 | #include 20 | #include 21 | 22 | 23 | namespace BitCoin 24 | { 25 | void notify(const char *pSubject, const char *pMessage); 26 | 27 | class Info 28 | { 29 | public: 30 | 31 | static Info &instance(); 32 | static void destroy(); 33 | static void setPath(const char *pPath); 34 | static NextCash::String path() { return sPath; } 35 | 36 | ChainID chainID; 37 | 38 | NextCash::Network::IPAddress ip; 39 | bool spvMode; 40 | 41 | // Maximum number of connections incoming and outgoing. 42 | uint32_t maxConnections; 43 | 44 | // Maximum size in bytes/block count to download and save while waiting for processing. 45 | NextCash::stream_size pendingSize; 46 | uint32_t pendingBlocks; 47 | 48 | // Amount of memory to use to cache transaction output data. 49 | NextCash::stream_size outputsCacheSize; 50 | // Amount of additional memory to use before saving and trimming the outputs data cache. 51 | NextCash::stream_size outputsCacheDelta; 52 | 53 | // Amount of memory to use for transaction outputs before saving to file. 54 | NextCash::stream_size addressesCacheSize; 55 | 56 | // Lowest fee that will be accepted into the mem pool (Satoshis per KB). 57 | uint64_t minFee; 58 | 59 | // When the mem pool size reaches the memPoolLowFeeSize, fees below lowFee will be dropped 60 | // to keep the size under memPoolLowFeeSize. The mem pool size can only grow above 61 | // memPoolLowFeeSize with all fees above lowFee. 62 | NextCash::stream_size memPoolLowFeeSize; 63 | uint64_t lowFee; // (Satoshis per KB). 64 | 65 | // When the mem pool size reaches the memPoolSize, the lowest fee/oldest transactions will 66 | // be dropped to keep the size under memPoolSize. 67 | NextCash::stream_size memPoolSize; 68 | 69 | // Number of merkle blocks per block required from different peers to confirm a block's 70 | // transactions. 71 | // More than one required to prevent data withholding. 72 | uint8_t merkleBlockCountRequired; 73 | 74 | // Number of peers that an unconfirmed transaction must be announced from before it has 75 | // zero confirm trust. 76 | unsigned int spvMemPoolCountRequired; 77 | 78 | // Number of threads used to process and save data. 79 | unsigned int threadCount; 80 | 81 | // The block header hash of the highest pre-approved block. During IBD all blocks below 82 | // this will not be fully validated. They will just be processed to update UTXOs and 83 | // the address database. 84 | NextCash::Hash approvedHash; 85 | 86 | // Block header hashes that will never be considered valid. These can be used to follow a 87 | // minority proof of work chain. 88 | NextCash::HashList invalidHashes; 89 | 90 | // Email address to send notifications to. 91 | NextCash::String notifyEmail; 92 | 93 | void configureChain(ChainID pChainID); 94 | 95 | // Return list of peers in random order 96 | void getRandomizedPeers(std::vector &pPeers, int pMinimumRating, 97 | uint64_t mServicesRequiredMask, ChainID pChainID, int pMaximumRating = 500000); 98 | bool addPeer(const NextCash::Network::IPAddress &pAddress, uint64_t pServices); 99 | void updatePeer(const NextCash::Network::IPAddress &pAddress, const char *pUserAgent, 100 | uint64_t pServices); 101 | void markPeerChain(const NextCash::Network::IPAddress &pAddress, ChainID pChainID); 102 | void addPeerSuccess(const NextCash::Network::IPAddress &pAddress, int pCount = 1); 103 | void addPeerFail(const NextCash::Network::IPAddress &pAddress, int pCount = 1, 104 | int pMinimum = -500); 105 | unsigned int peerCount() const { return mPeers.size(); } 106 | void resetPeers(); 107 | 108 | bool initialBlockDownloadIsComplete() { return mInitialBlockDownloadComplete; } 109 | void setInitialBlockDownloadComplete() 110 | { 111 | if(!mInitialBlockDownloadComplete) 112 | { 113 | mInitialBlockDownloadComplete = true; 114 | mDataModified = true; 115 | } 116 | } 117 | 118 | bool load(); 119 | void save(); 120 | 121 | static bool test(); 122 | 123 | protected: 124 | 125 | Info(); 126 | ~Info(); 127 | 128 | void readSettingsFile(NextCash::InputStream *pStream); 129 | void applyValue(NextCash::Buffer &pName, NextCash::Buffer &pValue); 130 | 131 | void writeDataFile(); 132 | bool readDataFile(); 133 | 134 | void writePeersFile(); 135 | bool readPeersFile(); 136 | 137 | // Peers 138 | bool mPeersModified, mPeersRead; 139 | NextCash::ReadersLock mPeerLock; 140 | NextCash::SortedSet mPeers; 141 | 142 | static NextCash::String sPath; 143 | static Info *sInstance; 144 | static NextCash::MutexWithConstantName sMutex; 145 | 146 | private: 147 | Info(const Info &pCopy); 148 | const Info &operator = (const Info &pRight); 149 | 150 | bool mDataModified; 151 | bool mInitialBlockDownloadComplete; 152 | }; 153 | } 154 | 155 | #endif 156 | -------------------------------------------------------------------------------- /src/output.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2017-2019 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | #include "output.hpp" 9 | 10 | #include "interpreter.hpp" 11 | 12 | 13 | namespace BitCoin 14 | { 15 | void Output::write(NextCash::OutputStream *pStream, bool pTrim) 16 | { 17 | pStream->writeLong(amount); 18 | if(pTrim && ScriptInterpreter::isOPReturn(script)) 19 | { 20 | // Trim OP_RETURN data 21 | writeCompactInteger(pStream, 1); 22 | pStream->writeByte(OP_RETURN); 23 | } 24 | else 25 | { 26 | writeCompactInteger(pStream, script.length()); 27 | pStream->write(script.begin(), script.length()); 28 | } 29 | } 30 | 31 | bool Output::read(NextCash::InputStream *pStream) 32 | { 33 | if(pStream->remaining() < 8) 34 | return false; 35 | 36 | amount = pStream->readLong(); 37 | 38 | NextCash::stream_size bytes = readCompactInteger(pStream); 39 | if(bytes > MAX_SCRIPT_SIZE) 40 | { 41 | NextCash::Log::addFormatted(NextCash::Log::WARNING, BITCOIN_OUTPUT_LOG_NAME, 42 | "Failed to read output. Script too long : %d", bytes); 43 | return false; 44 | } 45 | if(pStream->remaining() < bytes) 46 | return false; 47 | script.setSize(bytes); 48 | script.reset(); 49 | script.writeStreamCompact(*pStream, bytes); 50 | 51 | return true; 52 | } 53 | 54 | bool Output::skip(NextCash::InputStream *pInputStream, NextCash::OutputStream *pOutputStream) 55 | { 56 | // Amount 57 | if(pInputStream->remaining() < 8) 58 | return false; 59 | if(pOutputStream == NULL) 60 | pInputStream->setReadOffset(pInputStream->readOffset() + 8); 61 | else 62 | pOutputStream->writeLong(pInputStream->readLong()); 63 | 64 | // Script 65 | NextCash::stream_size bytes = readCompactInteger(pInputStream); 66 | if(pOutputStream != NULL) 67 | writeCompactInteger(pOutputStream, bytes); 68 | if(pInputStream->remaining() < bytes) 69 | return false; 70 | if(pOutputStream == NULL) 71 | pInputStream->setReadOffset(pInputStream->readOffset() + bytes); 72 | else 73 | pInputStream->readStream(pOutputStream, bytes); 74 | return true; 75 | } 76 | 77 | void Output::print(const Forks &pForks, const char *pLogName, NextCash::Log::Level pLevel) 78 | { 79 | NextCash::Log::addFormatted(pLevel, pLogName, " Amount : %.08f", 80 | bitcoins(amount)); 81 | NextCash::Log::addFormatted(pLevel, pLogName, " Script : (%d bytes)", 82 | script.length()); 83 | script.setReadOffset(0); 84 | ScriptInterpreter::printScript(script, pForks, pLevel); 85 | } 86 | } -------------------------------------------------------------------------------- /src/output.hpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2017-2019 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | #ifndef BITCOIN_OUTPUT_HPP 9 | #define BITCOIN_OUTPUT_HPP 10 | 11 | #include "stream.hpp" 12 | #include "buffer.hpp" 13 | #include "forks.hpp" 14 | 15 | #include 16 | 17 | #define BITCOIN_OUTPUT_LOG_NAME "Output" 18 | 19 | 20 | namespace BitCoin 21 | { 22 | class Output 23 | { 24 | public: 25 | 26 | Output() { } 27 | Output(const Output &pCopy) : script(pCopy.script) 28 | { 29 | amount = pCopy.amount; 30 | } 31 | 32 | Output &operator = (const Output &pRight) 33 | { 34 | amount = pRight.amount; 35 | script = pRight.script; 36 | return *this; 37 | } 38 | 39 | bool operator == (const Output &pRight) 40 | { 41 | return amount == pRight.amount && script == pRight.script; 42 | } 43 | 44 | // 8 amount + script length size + script length 45 | NextCash::stream_size size() const 46 | { return 8 + compactIntegerSize(script.length()) + script.length(); } 47 | 48 | void write(NextCash::OutputStream *pStream, bool pTrim = false); 49 | bool read(NextCash::InputStream *pStream); 50 | 51 | // Skip over output in stream 52 | // (The input stream's read offset must be at the beginning of an output) 53 | static bool skip(NextCash::InputStream *pInputStream, 54 | NextCash::OutputStream *pOutputStream = NULL); 55 | 56 | // Print human readable version to log 57 | void print(const Forks &pForks, const char *pLogName = BITCOIN_OUTPUT_LOG_NAME, 58 | NextCash::Log::Level pLevel = NextCash::Log::VERBOSE); 59 | 60 | int64_t amount; // Number of Satoshis spent (documentation says this should be signed) 61 | NextCash::Buffer script; 62 | 63 | }; 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/peer.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2018 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | #include "peer.hpp" 9 | 10 | #include "base.hpp" 11 | 12 | 13 | namespace BitCoin 14 | { 15 | void Peer::write(NextCash::OutputStream *pStream) const 16 | { 17 | // Validation Header 18 | pStream->writeString(START_STRING); 19 | 20 | // User Agent Bytes 21 | writeCompactInteger(pStream, userAgent.length()); 22 | 23 | // User Agent 24 | pStream->writeString(userAgent); 25 | 26 | // Rating 27 | pStream->writeInt(rating); 28 | 29 | // Time 30 | pStream->writeUnsignedInt(time); 31 | 32 | // Services 33 | pStream->writeUnsignedLong(services); 34 | 35 | // Address 36 | address.write(pStream); 37 | 38 | // Chain ID 39 | pStream->writeUnsignedInt(chainID); 40 | } 41 | 42 | bool Peer::read(NextCash::InputStream *pStream, unsigned int pVersion) 43 | { 44 | static const char *match = START_STRING; 45 | bool matchFound = false; 46 | unsigned int matchOffset = 0; 47 | 48 | // Search for start string 49 | while(pStream->remaining()) 50 | { 51 | if(pStream->readByte() == match[matchOffset]) 52 | { 53 | matchOffset++; 54 | if(matchOffset == 4) 55 | { 56 | matchFound = true; 57 | break; 58 | } 59 | } 60 | else 61 | matchOffset = 0; 62 | } 63 | 64 | if(!matchFound) 65 | return false; 66 | 67 | // User Agent Bytes 68 | uint64_t userAgentLength = readCompactInteger(pStream); 69 | 70 | if(userAgentLength > 256) 71 | return false; 72 | 73 | // User Agent 74 | userAgent = pStream->readString(userAgentLength); 75 | 76 | // Rating 77 | rating = pStream->readInt(); 78 | 79 | // Time 80 | time = pStream->readUnsignedInt(); 81 | 82 | // Services 83 | services = pStream->readUnsignedLong(); 84 | 85 | // Address 86 | if(!address.read(pStream)) 87 | return false; 88 | 89 | if(pVersion > 1) 90 | { 91 | try 92 | { 93 | chainID = static_cast(pStream->readUnsignedInt()); 94 | } 95 | catch(...) 96 | { 97 | return false; 98 | } 99 | } 100 | else 101 | chainID = CHAIN_UNKNOWN; 102 | return true; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/peer.hpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2018 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | #ifndef BITCOIN_PEER_HPP 9 | #define BITCOIN_PEER_HPP 10 | 11 | #include "string.hpp" 12 | #include "network.hpp" 13 | #include "base.hpp" 14 | #include "sorted_set.hpp" 15 | 16 | 17 | namespace BitCoin 18 | { 19 | class Peer : public NextCash::SortedObject 20 | { 21 | public: 22 | 23 | static constexpr const char *START_STRING = "NCPR"; 24 | 25 | Peer() { rating = 0; chainID = CHAIN_UNKNOWN; } 26 | Peer(const Peer &pCopy) 27 | { 28 | time = pCopy.time; 29 | services = pCopy.services; 30 | userAgent = pCopy.userAgent; 31 | rating = pCopy.rating; 32 | address = pCopy.address; 33 | chainID = pCopy.chainID; 34 | } 35 | 36 | void write(NextCash::OutputStream *pStream) const; 37 | bool read(NextCash::InputStream *pStream, unsigned int pVersion); 38 | 39 | // SortedObject virtual function. 40 | int compare(SortedObject *pRight) 41 | { 42 | try 43 | { 44 | const uint8_t *left = address.ipv6Bytes(); 45 | const uint8_t *right = dynamic_cast(pRight)->address.ipv6Bytes(); 46 | for(unsigned int i = 0; i < INET6_ADDRLEN; ++i, ++left, ++right) 47 | { 48 | if(*left < *right) 49 | return -1; 50 | else if(*left > *right) 51 | return 1; 52 | } 53 | 54 | return 0; 55 | } 56 | catch(...) 57 | { 58 | return -1; 59 | } 60 | } 61 | 62 | void updateTime() { time = getTime(); } 63 | 64 | Peer &operator = (const Peer &pRight) 65 | { 66 | time = pRight.time; 67 | services = pRight.services; 68 | userAgent = pRight.userAgent; 69 | rating = pRight.rating; 70 | address = pRight.address; 71 | chainID = pRight.chainID; 72 | return *this; 73 | } 74 | 75 | Time time; 76 | uint64_t services; 77 | NextCash::String userAgent; 78 | int32_t rating; 79 | NextCash::Network::IPAddress address; 80 | ChainID chainID; 81 | }; 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/profiler_setup.hpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2018 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | #ifndef BITCOIN_PROFILER_SETUP_HPP 9 | #define BITCOIN_PROFILER_SETUP_HPP 10 | 11 | #ifdef PROFILER_ON 12 | 13 | static const unsigned int PROFILER_SET = 1; 14 | static unsigned int sNextID = 0; 15 | 16 | static const unsigned int PROFILER_OUTPUTS_PULL_ID = sNextID++; 17 | static const char *PROFILER_OUTPUTS_PULL_NAME __attribute__ ((unused)) = "Outputs::pull"; 18 | static const unsigned int PROFILER_OUTPUTS_SAMPLE_ID = sNextID++; 19 | static const char *PROFILER_OUTPUTS_SAMPLE_NAME __attribute__ ((unused)) = "Outputs::findSample"; 20 | static const unsigned int PROFILER_OUTPUTS_ADD_ID = sNextID++; 21 | static const char *PROFILER_OUTPUTS_ADD_NAME __attribute__ ((unused)) = "Outputs::add"; 22 | static const unsigned int PROFILER_OUTPUTS_INSERT_ID = sNextID++; 23 | static const char *PROFILER_OUTPUTS_INSERT_NAME __attribute__ ((unused)) = "Outputs::insert"; 24 | static const unsigned int PROFILER_OUTPUTS_WRITE_ID = sNextID++; 25 | static const char *PROFILER_OUTPUTS_WRITE_NAME __attribute__ ((unused)) = "Outputs::write"; 26 | static const unsigned int PROFILER_OUTPUTS_GET_ID = sNextID++; 27 | static const char *PROFILER_OUTPUTS_GET_NAME __attribute__ ((unused)) = "Outputs::get"; 28 | static const unsigned int PROFILER_OUTPUTS_CHECK_ID = sNextID++; 29 | static const char *PROFILER_OUTPUTS_CHECK_NAME __attribute__ ((unused)) = "Outputs::checkDuplicate"; 30 | static const unsigned int PROFILER_OUTPUTS_GET_OUTPUT_ID = sNextID++; 31 | static const char *PROFILER_OUTPUTS_GET_OUTPUT_NAME __attribute__ ((unused)) = "Outputs::getOutput"; 32 | static const unsigned int PROFILER_OUTPUTS_IS_UNSPENT_ID = sNextID++; 33 | static const char *PROFILER_OUTPUTS_IS_UNSPENT_NAME __attribute__ ((unused)) = "Outputs::isUnspent"; 34 | static const unsigned int PROFILER_OUTPUTS_UNSPENT_STATUS_ID = sNextID++; 35 | static const char *PROFILER_OUTPUTS_UNSPENT_STATUS_NAME __attribute__ ((unused)) = "Outputs::unspentStatus"; 36 | static const unsigned int PROFILER_OUTPUTS_SPEND_ID = sNextID++; 37 | static const char *PROFILER_OUTPUTS_SPEND_NAME __attribute__ ((unused)) = "Outputs::spend"; 38 | static const unsigned int PROFILER_OUTPUTS_HAS_UNSPENT_ID = sNextID++; 39 | static const char *PROFILER_OUTPUTS_HAS_UNSPENT_NAME __attribute__ ((unused)) = "Outputs::hasUnspent"; 40 | static const unsigned int PROFILER_OUTPUTS_EXISTS_ID = sNextID++; 41 | static const char *PROFILER_OUTPUTS_EXISTS_NAME __attribute__ ((unused)) = "Outputs::exists"; 42 | 43 | static const unsigned int PROFILER_INTERP_PROCESS_ID = sNextID++; 44 | static const char *PROFILER_INTERP_PROCESS_NAME __attribute__ ((unused)) = "Interpreter::process"; 45 | 46 | static const unsigned int PROFILER_TRANS_READ_ID = sNextID++; 47 | static const char *PROFILER_TRANS_READ_NAME __attribute__ ((unused)) = "Transaction::read (B)"; 48 | static const unsigned int PROFILER_TRANS_WRITE_SIG_ID = sNextID++; 49 | static const char *PROFILER_TRANS_WRITE_SIG_NAME __attribute__ ((unused)) = "Transaction::writeSigData"; 50 | 51 | static const unsigned int PROFILER_BLOCK_READ_ID = sNextID++; 52 | static const char *PROFILER_BLOCK_READ_NAME __attribute__ ((unused)) = "Block::read (B)"; 53 | static const unsigned int PROFILER_BLOCK_GET_ID = sNextID++; 54 | static const char *PROFILER_BLOCK_GET_NAME __attribute__ ((unused)) = "Block::get (B)"; 55 | static const unsigned int PROFILER_BLOCK_PROCESS_ID = sNextID++; 56 | static const char *PROFILER_BLOCK_PROCESS_NAME __attribute__ ((unused)) = "Block::process (B)"; // hits are bytes 57 | static const unsigned int PROFILER_BLOCK_MERKLE_CALC_ID = sNextID++; 58 | static const char *PROFILER_BLOCK_MERKLE_CALC_NAME __attribute__ ((unused)) = "Block::merkleCalc"; 59 | 60 | static const unsigned int PROFILER_KEY_SIGN_ID = sNextID++; 61 | static const char *PROFILER_KEY_SIGN_NAME __attribute__ ((unused)) = "Key::sign"; 62 | static const unsigned int PROFILER_KEY_VERIFY_SIG_ID = sNextID++; 63 | static const char *PROFILER_KEY_VERIFY_SIG_NAME __attribute__ ((unused)) = "Key::verifySig"; 64 | static const unsigned int PROFILER_KEY_STATIC_VERIFY_SIG_ID = sNextID++; 65 | static const char *PROFILER_KEY_STATIC_VERIFY_SIG_NAME __attribute__ ((unused)) = "Key::verifySigStatic"; 66 | 67 | static const unsigned int PROFILER_MEMPOOL_STATUS_ID = sNextID++; 68 | static const char *PROFILER_MEMPOOL_STATUS_NAME __attribute__ ((unused)) = "MemPool::status"; 69 | static const unsigned int PROFILER_MEMPOOL_ADD_ID = sNextID++; 70 | static const char *PROFILER_MEMPOOL_ADD_NAME __attribute__ ((unused)) = "MemPool::add"; 71 | static const unsigned int PROFILER_MEMPOOL_ADD_INTERNAL_ID = sNextID++; 72 | static const char *PROFILER_MEMPOOL_ADD_INTERNAL_NAME __attribute__ ((unused)) = "MemPool::addInternal"; 73 | static const unsigned int PROFILER_MEMPOOL_ADD_INTERNAL_B_ID = sNextID++; 74 | static const char *PROFILER_MEMPOOL_ADD_INTERNAL_B_NAME __attribute__ ((unused)) = "MemPool::addInternal (B)"; // hits are bytes 75 | static const unsigned int PROFILER_MEMPOOL_ADD_DUP_B_ID = sNextID++; 76 | static const char *PROFILER_MEMPOOL_ADD_DUP_B_NAME __attribute__ ((unused)) = "MemPool::add (dup B)"; // hits are bytes 77 | static const unsigned int PROFILER_MEMPOOL_PENDING_ID = sNextID++; 78 | static const char *PROFILER_MEMPOOL_PENDING_NAME __attribute__ ((unused)) = "MemPool::checkPending"; 79 | static const unsigned int PROFILER_MEMPOOL_GET_TRANS_ID = sNextID++; 80 | static const char *PROFILER_MEMPOOL_GET_TRANS_NAME __attribute__ ((unused)) = "MemPool::getTrans"; 81 | static const unsigned int PROFILER_MEMPOOL_GET_TRANS_COPY_ID = sNextID++; 82 | static const char *PROFILER_MEMPOOL_GET_TRANS_COPY_NAME __attribute__ ((unused)) = "MemPool::getTransCopy"; 83 | static const unsigned int PROFILER_MEMPOOL_GET_COMPACT_TRANS_CALC_ID = sNextID++; 84 | static const char *PROFILER_MEMPOOL_GET_COMPACT_TRANS_CALC_NAME __attribute__ ((unused)) = "MemPool::calcShortIDs"; 85 | static const unsigned int PROFILER_MEMPOOL_GET_OUTPUT_ID = sNextID++; 86 | static const char *PROFILER_MEMPOOL_GET_OUTPUT_NAME __attribute__ ((unused)) = "MemPool::getOutput"; 87 | static const unsigned int PROFILER_MEMPOOL_PULL_ID = sNextID++; 88 | static const char *PROFILER_MEMPOOL_PULL_NAME __attribute__ ((unused)) = "MemPool::pull"; 89 | static const unsigned int PROFILER_MEMPOOL_FINALIZE_ID = sNextID++; 90 | static const char *PROFILER_MEMPOOL_FINALIZE_NAME __attribute__ ((unused)) = "MemPool::finalize"; 91 | 92 | static const unsigned int PROFILER_NODE_FILL_COMPACT_ID = sNextID++; 93 | static const char *PROFILER_NODE_FILL_COMPACT_NAME __attribute__ ((unused)) = "Node::fillCompactBlock"; 94 | static const unsigned int PROFILER_NODE_COMPACT_ADD_TRANS_ID = sNextID++; 95 | static const char *PROFILER_NODE_COMPACT_ADD_TRANS_NAME __attribute__ ((unused)) = "Node::compactAddTrans"; 96 | 97 | #endif 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /src/requests.hpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * Copyright 2017-2018 NextCash, LLC * 3 | * Contributors : * 4 | * Curtis Ellis * 5 | * Distributed under the MIT software license, see the accompanying * 6 | * file license.txt or http://www.opensource.org/licenses/mit-license.php * 7 | **************************************************************************/ 8 | #ifndef BITCOIN_REQUESTS_HPP 9 | #define BITCOIN_REQUESTS_HPP 10 | 11 | #include "mutex.hpp" 12 | #include "thread.hpp" 13 | #include "network.hpp" 14 | #include "buffer.hpp" 15 | 16 | #include "chain.hpp" 17 | 18 | 19 | namespace BitCoin 20 | { 21 | class RequestChannel 22 | { 23 | public: 24 | 25 | RequestChannel(NextCash::Network::Connection *pConnection, Chain *pChain); 26 | ~RequestChannel(); 27 | 28 | static void run(void *pParameter); 29 | 30 | void requestStop(); 31 | 32 | bool isStopped() { return mStopped; } 33 | 34 | private: 35 | 36 | void process(); 37 | 38 | unsigned int mID; 39 | NextCash::String mName; 40 | NextCash::Thread *mThread; 41 | NextCash::MutexWithConstantName mConnectionMutex; 42 | NextCash::Network::Connection *mConnection; 43 | NextCash::Buffer mReceiveBuffer; 44 | bool mStop, mStopped, mAuthenticated; 45 | 46 | Time mLastReceiveTime; 47 | Time mConnectedTime; 48 | 49 | Chain *mChain; 50 | 51 | unsigned int mPreviousStatisticsHeight; 52 | unsigned int mPreviousStatisticsHours; 53 | NextCash::Buffer mPreviousStatisticsResult; 54 | 55 | static unsigned int mNextID; 56 | 57 | RequestChannel(const RequestChannel &pCopy); 58 | const RequestChannel &operator = (const RequestChannel &pRight); 59 | 60 | }; 61 | } 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /tests/06128e87be8b1b4dea47a7247d5528d2702c96826c7a648497e773b800000000.pending_block: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcashtech/bitcoin/15f62465e909ef676d1cd41515776d0db2eeefc1/tests/06128e87be8b1b4dea47a7247d5528d2702c96826c7a648497e773b800000000.pending_block --------------------------------------------------------------------------------