├── .gitignore ├── .travis.yml ├── 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 ├── builds └── msvc │ ├── .gitignore │ ├── build │ ├── buildall.bat │ └── buildbase.bat │ ├── properties │ ├── Common.props │ ├── DLL.props │ ├── Debug.props │ ├── DebugDEXE.props │ ├── DebugDLL.props │ ├── DebugLEXE.props │ ├── DebugLIB.props │ ├── DebugLTCG.props │ ├── DebugSEXE.props │ ├── EXE.props │ ├── LIB.props │ ├── LTCG.props │ ├── Link.props │ ├── Messages.props │ ├── Output.props │ ├── Release.props │ ├── ReleaseDEXE.props │ ├── ReleaseDLL.props │ ├── ReleaseLEXE.props │ ├── ReleaseLIB.props │ ├── ReleaseLTCG.props │ ├── ReleaseSEXE.props │ ├── Win32.props │ └── x64.props │ ├── resource.h │ ├── resource.rc │ ├── vs2013 │ ├── secp256k1.import.props │ ├── secp256k1.import.xml │ ├── secp256k1.sln │ ├── secp256k1 │ │ ├── secp256k1.props │ │ ├── secp256k1.vcxproj │ │ ├── secp256k1.vcxproj.filters │ │ └── secp256k1.xml │ ├── secp256k1_bench │ │ ├── secp256k1_bench.props │ │ ├── secp256k1_bench.vcxproj │ │ ├── secp256k1_bench.vcxproj.filters │ │ └── secp256k1_bench.xml │ └── secp256k1_tests │ │ ├── secp256k1_tests.props │ │ ├── secp256k1_tests.vcxproj │ │ ├── secp256k1_tests.vcxproj.filters │ │ └── secp256k1_tests.xml │ ├── vs2015 │ ├── secp256k1.import.props │ ├── secp256k1.import.xml │ ├── secp256k1.sln │ ├── secp256k1 │ │ ├── secp256k1.props │ │ ├── secp256k1.vcxproj │ │ ├── secp256k1.vcxproj.filters │ │ └── secp256k1.xml │ ├── secp256k1_bench │ │ ├── secp256k1_bench.props │ │ ├── secp256k1_bench.vcxproj │ │ ├── secp256k1_bench.vcxproj.filters │ │ └── secp256k1_bench.xml │ └── secp256k1_tests │ │ ├── secp256k1_tests.props │ │ ├── secp256k1_tests.vcxproj │ │ ├── secp256k1_tests.vcxproj.filters │ │ └── secp256k1_tests.xml │ └── vs2017 │ ├── secp256k1.import.props │ ├── secp256k1.import.xml │ ├── secp256k1.sln │ ├── secp256k1 │ ├── secp256k1.props │ ├── secp256k1.vcxproj │ ├── secp256k1.vcxproj.filters │ └── secp256k1.xml │ ├── secp256k1_bench │ ├── secp256k1_bench.props │ ├── secp256k1_bench.vcxproj │ ├── secp256k1_bench.vcxproj.filters │ └── secp256k1_bench.xml │ └── secp256k1_tests │ ├── secp256k1_tests.props │ ├── secp256k1_tests.vcxproj │ ├── secp256k1_tests.vcxproj.filters │ └── secp256k1_tests.xml ├── 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_preallocated.h └── secp256k1_recovery.h ├── libsecp256k1.pc.in ├── packaging └── nuget │ ├── .gitignore │ ├── gmp │ ├── package.bat │ └── package.config │ ├── package.bat │ ├── package.config │ ├── package.gsl │ ├── package.nuspec │ ├── package.targets │ └── package.xml ├── sage ├── group_prover.sage ├── secp256k1.sage └── weierstrass_prover.sage └── src ├── asm └── field_10x26_arm.s ├── basic-config.h ├── bench.h ├── bench_ecdh.c ├── bench_ecmult.c ├── bench_internal.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.java │ │ ├── NativeSecp256k1Test.java │ │ ├── NativeSecp256k1Util.java │ │ └── Secp256k1Context.java ├── org_bitcoin_NativeSecp256k1.c ├── org_bitcoin_NativeSecp256k1.h ├── org_bitcoin_Secp256k1Context.c └── org_bitcoin_Secp256k1Context.h ├── modules ├── ecdh │ ├── Makefile.am.include │ ├── 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 ├── scratch.h ├── scratch_impl.h ├── secp256k1.c ├── testrand.h ├── testrand_impl.h ├── tests.c ├── tests_exhaustive.c └── util.h /.gitignore: -------------------------------------------------------------------------------- 1 | bench_inv 2 | bench_ecdh 3 | bench_ecmult 4 | bench_sign 5 | bench_verify 6 | bench_schnorr_verify 7 | bench_recover 8 | bench_internal 9 | tests 10 | exhaustive_tests 11 | gen_context 12 | *.exe 13 | *.so 14 | *.a 15 | !.gitignore 16 | 17 | Makefile 18 | configure 19 | .libs/ 20 | Makefile.in 21 | aclocal.m4 22 | autom4te.cache/ 23 | config.log 24 | config.status 25 | *.tar.gz 26 | *.la 27 | libtool 28 | .deps/ 29 | .dirstamp 30 | *.lo 31 | *.o 32 | *~ 33 | src/libsecp256k1-config.h 34 | src/libsecp256k1-config.h.in 35 | src/ecmult_static_context.h 36 | build-aux/config.guess 37 | build-aux/config.sub 38 | build-aux/depcomp 39 | build-aux/install-sh 40 | build-aux/ltmain.sh 41 | build-aux/m4/libtool.m4 42 | build-aux/m4/lt~obsolete.m4 43 | build-aux/m4/ltoptions.m4 44 | build-aux/m4/ltsugar.m4 45 | build-aux/m4/ltversion.m4 46 | build-aux/missing 47 | build-aux/compile 48 | build-aux/test-driver 49 | src/stamp-h1 50 | libsecp256k1.pc 51 | /bin/ 52 | /obj/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | os: linux 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 ECMULTGENPRECISION=auto 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 | - ECMULTGENPRECISION=2 34 | - ECMULTGENPRECISION=8 35 | matrix: 36 | fast_finish: true 37 | include: 38 | - compiler: clang 39 | env: HOST=i686-linux-gnu ENDOMORPHISM=yes 40 | addons: 41 | apt: 42 | packages: 43 | - gcc-multilib 44 | - libgmp-dev:i386 45 | - compiler: clang 46 | env: HOST=i686-linux-gnu 47 | addons: 48 | apt: 49 | packages: 50 | - gcc-multilib 51 | - compiler: gcc 52 | env: HOST=i686-linux-gnu ENDOMORPHISM=yes 53 | addons: 54 | apt: 55 | packages: 56 | - gcc-multilib 57 | - compiler: gcc 58 | env: HOST=i686-linux-gnu 59 | addons: 60 | apt: 61 | packages: 62 | - gcc-multilib 63 | - libgmp-dev:i386 64 | before_install: mkdir -p `dirname $GUAVA_JAR` 65 | install: if [ ! -f $GUAVA_JAR ]; then wget $GUAVA_URL -O $GUAVA_JAR; fi 66 | before_script: ./autogen.sh 67 | script: 68 | - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi 69 | - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi 70 | - ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --with-ecmult-gen-precision=$ECMULTGENPRECISION --enable-module-ecdh=$ECDH --enable-module-recovery=$RECOVERY --enable-jni=$JNI $EXTRAFLAGS $USE_HOST && make -j2 $BUILD 71 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | * Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains) 49 | * Access the table with branch-free conditional moves so memory access is uniform. 50 | * No data-dependent branches 51 | * Optional runtime blinding which attempts to frustrate differential power analysis. 52 | * 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. 53 | 54 | Build steps 55 | ----------- 56 | 57 | libsecp256k1 is built using autotools: 58 | 59 | $ ./autogen.sh 60 | $ ./configure 61 | $ make 62 | $ make check 63 | $ sudo make install # optional 64 | 65 | Exhaustive tests 66 | ----------- 67 | 68 | $ ./exhaustive_tests 69 | 70 | With valgrind, you might need to increase the max stack size: 71 | 72 | $ valgrind --max-stackframe=2500000 ./exhaustive_tests 73 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | autoreconf -if --warnings=all 4 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /builds/msvc/.gitignore: -------------------------------------------------------------------------------- 1 | *.suo 2 | *.opensdf 3 | *.sdf 4 | *.aps 5 | *.user 6 | *.log 7 | *.db 8 | *.db-* 9 | *.opendb -------------------------------------------------------------------------------- /builds/msvc/build/buildall.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | :: Usage: buildall.bat 3 | 4 | :: Build all configurations for all solutions. 5 | call buildbase.bat ..\vs2017\secp256k1.sln 15 6 | ECHO. 7 | CALL buildbase.bat ..\vs2015\secp256k1.sln 14 8 | ECHO. 9 | CALL buildbase.bat ..\vs2013\secp256k1.sln 12 10 | ECHO. 11 | 12 | PAUSE 13 | -------------------------------------------------------------------------------- /builds/msvc/build/buildbase.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | REM Usage: [buildbase.bat ..\vs2013\mysolution.sln 12] 3 | 4 | SET solution=%1 5 | SET version=%2 6 | SET log=build_%version%.log 7 | SET tools=Microsoft Visual Studio %version%.0\VC\vcvarsall.bat 8 | IF %version% == 15 SET tools=Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat 9 | SET environment="%programfiles(x86)%\%tools%" 10 | IF NOT EXIST %environment% SET environment="%programfiles%\%tools%" 11 | IF NOT EXIST %environment% GOTO no_tools 12 | 13 | ECHO Building: %solution% 14 | 15 | CALL %environment% x86 > nul 16 | ECHO Platform=x86 17 | 18 | ECHO Configuration=DynDebug 19 | msbuild /m /v:n /p:Configuration=DynDebug /p:Platform=Win32 %solution% >> %log% 20 | IF errorlevel 1 GOTO error 21 | ECHO Configuration=DynRelease 22 | msbuild /m /v:n /p:Configuration=DynRelease /p:Platform=Win32 %solution% >> %log% 23 | IF errorlevel 1 GOTO error 24 | ECHO Configuration=LtcgDebug 25 | msbuild /m /v:n /p:Configuration=LtcgDebug /p:Platform=Win32 %solution% >> %log% 26 | IF errorlevel 1 GOTO error 27 | ECHO Configuration=LtcgRelease 28 | msbuild /m /v:n /p:Configuration=LtcgRelease /p:Platform=Win32 %solution% >> %log% 29 | IF errorlevel 1 GOTO error 30 | ECHO Configuration=StaticDebug 31 | msbuild /m /v:n /p:Configuration=StaticDebug /p:Platform=Win32 %solution% >> %log% 32 | IF errorlevel 1 GOTO error 33 | ECHO Configuration=StaticRelease 34 | msbuild /m /v:n /p:Configuration=StaticRelease /p:Platform=Win32 %solution% >> %log% 35 | IF errorlevel 1 GOTO error 36 | 37 | CALL %environment% x86_amd64 > nul 38 | ECHO Platform=x64 39 | 40 | ECHO Configuration=DynDebug 41 | msbuild /m /v:n /p:Configuration=DynDebug /p:Platform=x64 %solution% >> %log% 42 | IF errorlevel 1 GOTO error 43 | ECHO Configuration=DynRelease 44 | msbuild /m /v:n /p:Configuration=DynRelease /p:Platform=x64 %solution% >> %log% 45 | IF errorlevel 1 GOTO error 46 | ECHO Configuration=LtcgDebug 47 | msbuild /m /v:n /p:Configuration=LtcgDebug /p:Platform=x64 %solution% >> %log% 48 | IF errorlevel 1 GOTO error 49 | ECHO Configuration=LtcgRelease 50 | msbuild /m /v:n /p:Configuration=LtcgRelease /p:Platform=x64 %solution% >> %log% 51 | IF errorlevel 1 GOTO error 52 | ECHO Configuration=StaticDebug 53 | msbuild /m /v:n /p:Configuration=StaticDebug /p:Platform=x64 %solution% >> %log% 54 | IF errorlevel 1 GOTO error 55 | ECHO Configuration=StaticRelease 56 | msbuild /m /v:n /p:Configuration=StaticRelease /p:Platform=x64 %solution% >> %log% 57 | IF errorlevel 1 GOTO error 58 | 59 | ECHO Complete: %solution% 60 | GOTO end 61 | 62 | :error 63 | ECHO *** ERROR, build terminated early, see: %log% 64 | GOTO end 65 | 66 | :no_tools 67 | ECHO *** ERROR, build tools not found: %tools% 68 | 69 | :end 70 | 71 | -------------------------------------------------------------------------------- /builds/msvc/properties/Common.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Common Settings 6 | Unicode 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | true 16 | UNICODE;_UNICODE;%(PreprocessorDefinitions) 17 | Level3 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /builds/msvc/properties/DLL.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Dynamic Library 6 | dynamic 7 | .dll 8 | 9 | 10 | 11 | 12 | _DLL;_WINDLL;%(PreprocessorDefinitions) 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /builds/msvc/properties/Debug.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <_PropertySheetDisplayName>Debug Settings 10 | Debug 11 | 12 | 13 | 14 | 15 | EnableFastChecks 16 | ProgramDatabase 17 | true 18 | Disabled 19 | _DEBUG;%(PreprocessorDefinitions) 20 | 21 | 22 | _DEBUG;%(PreprocessorDefinitions) 23 | 24 | 25 | true 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /builds/msvc/properties/DebugDEXE.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Console Debug Dynamic 6 | dynamic 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | MultiThreadedDebugDLL 17 | true 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /builds/msvc/properties/DebugDLL.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Dynamic Debug Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | MultiThreadedDebugDLL 16 | true 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /builds/msvc/properties/DebugLEXE.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Console Debug Link Time Code Generation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | MultiThreadedDebug 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /builds/msvc/properties/DebugLIB.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Static Debug Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | OldStyle 16 | MultiThreadedDebug 17 | true 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /builds/msvc/properties/DebugLTCG.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Static Debug Link Time Code Generation Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | OldStyle 16 | MultiThreadedDebug 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /builds/msvc/properties/DebugSEXE.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Console Debug Static 6 | static 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | MultiThreadedDebug 17 | true 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /builds/msvc/properties/EXE.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Console Application 6 | true 7 | 8 | 9 | 10 | 11 | _CONSOLE;%(PreprocessorDefinitions) 12 | 13 | 14 | Console 15 | 16 | 17 | -------------------------------------------------------------------------------- /builds/msvc/properties/LIB.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Static Library 6 | static 7 | .lib 8 | 9 | 10 | 11 | 12 | _LIB;%(PreprocessorDefinitions) 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /builds/msvc/properties/LTCG.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Link Time Code Generation Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /builds/msvc/properties/Link.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Link Time Code Generation Settings 6 | ltcg 7 | 8 | 9 | 10 | 11 | true 12 | 13 | 14 | UseLinkTimeCodeGeneration 15 | 16 | 17 | true 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /builds/msvc/properties/Messages.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Build Messages 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /builds/msvc/properties/Output.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Output Settings 6 | 7 | $(ProjectDir)..\..\ 8 | $(ProjectDir)..\..\..\..\ 9 | $(ProjectDir)..\..\..\..\..\ 10 | $(ProjectDir)..\..\..\..\bin\$(PlatformName)\$(DebugOrRelease)\$(PlatformToolset)\$(DefaultLinkage)\ 11 | $(ProjectDir)..\..\..\..\obj\$(TargetName)\$(PlatformName)\$(DebugOrRelease)\$(PlatformToolset)\$(DefaultLinkage)\ 12 | $(OutDir) 13 | $(TargetName) 14 | $(TargetDir)$(TargetName)$(TargetExt) 15 | 16 | 17 | 18 | 19 | $(OutDir)$(TargetName).lib 20 | 21 | 22 | $(OutDir)$(TargetName).log 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /builds/msvc/properties/Release.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <_PropertySheetDisplayName>Release Settings 10 | Release 11 | false 12 | 13 | 14 | 15 | 16 | /Oy- %(AdditionalOptions) 17 | 18 | true 19 | true 20 | OnlyExplicitInline 21 | false 22 | MaxSpeed 23 | NDEBUG;%(PreprocessorDefinitions) 24 | 25 | 26 | NDEBUG;%(PreprocessorDefinitions) 27 | 28 | 29 | true 30 | 31 | true 32 | 33 | 34 | 35 | 36 | 37 | StreamingSIMDExtensions2 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /builds/msvc/properties/ReleaseDEXE.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Console Release Dynamic 6 | dynamic 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | MultiThreadedDLL 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /builds/msvc/properties/ReleaseDLL.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Dynamic Release Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | MultiThreadedDLL 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /builds/msvc/properties/ReleaseLEXE.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Console Release Link Time Code Generation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | MultiThreaded 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /builds/msvc/properties/ReleaseLIB.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Static Release Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | MultiThreaded 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /builds/msvc/properties/ReleaseLTCG.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Static Release Link Time Code Generation Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | MultiThreaded 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /builds/msvc/properties/ReleaseSEXE.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>Console Release Static 6 | static 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | MultiThreaded 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /builds/msvc/properties/Win32.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>x86 Settings 6 | 7 | 8 | 9 | 10 | WIN32;_WIN32;%(PreprocessorDefinitions) 11 | 12 | 13 | MachineX86 14 | 15 | 16 | /MACHINE:X86 %(AdditionalOptions) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /builds/msvc/properties/x64.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>x64 Settings 6 | 7 | 8 | 9 | 10 | 13 | WIN32;_WIN32;WIN64;_WIN64;%(PreprocessorDefinitions) 14 | 15 | 16 | MachineX64 17 | 18 | 19 | /MACHINE:X64 %(AdditionalOptions) 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /builds/msvc/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by resource.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /builds/msvc/resource.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libbitcoin/secp256k1/1c3616f9f6f8ec4cd88eaccbae08b8cbb04ea326/builds/msvc/resource.rc -------------------------------------------------------------------------------- /builds/msvc/vs2013/secp256k1.import.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>secp256k1 Import Settings 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | $(ProjectDir)..\..\..\..\..\secp256k1\;%(AdditionalIncludeDirectories) 19 | inline=__inline;%(PreprocessorDefinitions) 20 | ECMULT_GEN_PREC_BITS=4;ECMULT_WINDOW_SIZE=15;%(PreprocessorDefinitions) 21 | 22 | 23 | secp256k1.lib;%(AdditionalDependencies) 24 | $(ProjectDir)..\..\..\..\..\secp256k1\bin\$(PlatformName)\Debug\$(PlatformToolset)\$(Linkage-secp256k1)\;%(AdditionalLibraryDirectories) 25 | $(ProjectDir)..\..\..\..\..\secp256k1\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-secp256k1)\;%(AdditionalLibraryDirectories) 26 | 27 | 28 | 29 | 30 | 31 | 32 | 36 | 40 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /builds/msvc/vs2013/secp256k1.import.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /builds/msvc/vs2013/secp256k1/secp256k1.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>SECP256K1 Common Settings 6 | AllRules.ruleset 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | $(RepoRoot)src\;$(RepoRoot)\include\;$(RepoRoot);%(AdditionalIncludeDirectories) 21 | 4244;4267;%(DisableSpecificWarnings) 22 | false 23 | inline=__inline;%(PreprocessorDefinitions) 24 | ECMULT_GEN_PREC_BITS=4;ECMULT_WINDOW_SIZE=15;%(PreprocessorDefinitions) 25 | SECP256K1_BUILD;%(PreprocessorDefinitions) 26 | 27 | USE_NUM_NONE;USE_FIELD_INV_BUILTIN;USE_SCALAR_INV_BUILTIN;%(PreprocessorDefinitions) 28 | USE_NUM_GMP;USE_FIELD_INV_NUM;USE_SCALAR_INV_NUM;%(PreprocessorDefinitions) 29 | 30 | 31 | USE_ASM_X86_64;%(PreprocessorDefinitions) 32 | 33 | 34 | USE_ENDOMORPHISM;%(PreprocessorDefinitions) 35 | 36 | HAVE_CONFIG_H;%(PreprocessorDefinitions) 37 | 38 | 39 | USE_FIELD_10X26;%(PreprocessorDefinitions) 40 | USE_FIELD_5X52;%(PreprocessorDefinitions) 41 | 42 | 43 | USE_SCALAR_8X32;%(PreprocessorDefinitions) 44 | USE_SCALAR_4X64;%(PreprocessorDefinitions) 45 | 46 | 47 | ENABLE_MODULE_ECDH;%(PreprocessorDefinitions) 48 | ENABLE_MODULE_RECOVERY;%(PreprocessorDefinitions) 49 | 50 | 51 | 52 | 53 | 54 | 55 | dynamic 56 | 57 | 58 | static 59 | 60 | 61 | static 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /builds/msvc/vs2013/secp256k1/secp256k1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /builds/msvc/vs2013/secp256k1_bench/secp256k1_bench.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Application 5 | {0D4BC36A-0418-44B5-86FD-17A649316D6B} 6 | secp256k1_bench 7 | v120 8 | 02ad7ae2 9 | 10 | 11 | 12 | DebugDEXE 13 | Win32 14 | 15 | 16 | ReleaseDEXE 17 | Win32 18 | 19 | 20 | DebugDEXE 21 | x64 22 | 23 | 24 | ReleaseDEXE 25 | x64 26 | 27 | 28 | DebugLEXE 29 | Win32 30 | 31 | 32 | ReleaseLEXE 33 | Win32 34 | 35 | 36 | DebugLEXE 37 | x64 38 | 39 | 40 | ReleaseLEXE 41 | x64 42 | 43 | 44 | DebugSEXE 45 | Win32 46 | 47 | 48 | ReleaseSEXE 49 | Win32 50 | 51 | 52 | DebugSEXE 53 | x64 54 | 55 | 56 | ReleaseSEXE 57 | x64 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | true 69 | 70 | 71 | 72 | true 73 | 74 | 75 | true 76 | 77 | 78 | true 79 | 80 | 81 | true 82 | 83 | 84 | true 85 | 86 | 87 | true 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | {148600EA-561B-4C78-A80A-2EB5046D0420} 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /builds/msvc/vs2013/secp256k1_bench/secp256k1_bench.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | src 6 | 7 | 8 | src 9 | 10 | 11 | src 12 | 13 | 14 | src 15 | 16 | 17 | src 18 | 19 | 20 | src 21 | 22 | 23 | src 24 | 25 | 26 | 27 | 28 | {578c6a1d-8a88-4f0c-89bd-57bb1ef79644} 29 | 30 | 31 | 32 | 33 | src 34 | 35 | 36 | -------------------------------------------------------------------------------- /builds/msvc/vs2013/secp256k1_bench/secp256k1_bench.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /builds/msvc/vs2013/secp256k1_tests/secp256k1_tests.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Application 5 | {9F8CD353-5F8B-46D7-9DA3-17A06CCA634F} 6 | secp256k1_tests 7 | v120 8 | ae87ffba 9 | 10 | 11 | 12 | DebugDEXE 13 | Win32 14 | 15 | 16 | ReleaseDEXE 17 | Win32 18 | 19 | 20 | DebugDEXE 21 | x64 22 | 23 | 24 | ReleaseDEXE 25 | x64 26 | 27 | 28 | DebugLEXE 29 | Win32 30 | 31 | 32 | ReleaseLEXE 33 | Win32 34 | 35 | 36 | DebugLEXE 37 | x64 38 | 39 | 40 | ReleaseLEXE 41 | x64 42 | 43 | 44 | DebugSEXE 45 | Win32 46 | 47 | 48 | ReleaseSEXE 49 | Win32 50 | 51 | 52 | DebugSEXE 53 | x64 54 | 55 | 56 | ReleaseSEXE 57 | x64 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | true 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | {148600EA-561B-4C78-A80A-2EB5046D0420} 85 | 86 | 87 | -------------------------------------------------------------------------------- /builds/msvc/vs2013/secp256k1_tests/secp256k1_tests.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | src 6 | 7 | 8 | src 9 | 10 | 11 | 12 | 13 | {578c6a1d-8a88-4f0c-89bd-57bb1ef79644} 14 | 15 | 16 | 17 | 18 | src 19 | 20 | 21 | src 22 | 23 | 24 | -------------------------------------------------------------------------------- /builds/msvc/vs2013/secp256k1_tests/secp256k1_tests.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /builds/msvc/vs2015/secp256k1.import.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>secp256k1 Import Settings 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | $(ProjectDir)..\..\..\..\..\secp256k1\;%(AdditionalIncludeDirectories) 19 | inline=__inline;%(PreprocessorDefinitions) 20 | ECMULT_GEN_PREC_BITS=4;ECMULT_WINDOW_SIZE=15;%(PreprocessorDefinitions) 21 | 22 | 23 | secp256k1.lib;%(AdditionalDependencies) 24 | $(ProjectDir)..\..\..\..\..\secp256k1\bin\$(PlatformName)\Debug\$(PlatformToolset)\$(Linkage-secp256k1)\;%(AdditionalLibraryDirectories) 25 | $(ProjectDir)..\..\..\..\..\secp256k1\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-secp256k1)\;%(AdditionalLibraryDirectories) 26 | 27 | 28 | 29 | 30 | 31 | 32 | 36 | 40 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /builds/msvc/vs2015/secp256k1.import.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /builds/msvc/vs2015/secp256k1/secp256k1.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>SECP256K1 Common Settings 6 | AllRules.ruleset 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | $(RepoRoot)src\;$(RepoRoot)\include\;$(RepoRoot);%(AdditionalIncludeDirectories) 21 | 4244;4267;%(DisableSpecificWarnings) 22 | false 23 | inline=__inline;%(PreprocessorDefinitions) 24 | ECMULT_GEN_PREC_BITS=4;ECMULT_WINDOW_SIZE=15;%(PreprocessorDefinitions) 25 | SECP256K1_BUILD;%(PreprocessorDefinitions) 26 | 27 | USE_NUM_NONE;USE_FIELD_INV_BUILTIN;USE_SCALAR_INV_BUILTIN;%(PreprocessorDefinitions) 28 | USE_NUM_GMP;USE_FIELD_INV_NUM;USE_SCALAR_INV_NUM;%(PreprocessorDefinitions) 29 | 30 | 31 | USE_ASM_X86_64;%(PreprocessorDefinitions) 32 | 33 | 34 | USE_ENDOMORPHISM;%(PreprocessorDefinitions) 35 | 36 | HAVE_CONFIG_H;%(PreprocessorDefinitions) 37 | 38 | 39 | USE_FIELD_10X26;%(PreprocessorDefinitions) 40 | USE_FIELD_5X52;%(PreprocessorDefinitions) 41 | 42 | 43 | USE_SCALAR_8X32;%(PreprocessorDefinitions) 44 | USE_SCALAR_4X64;%(PreprocessorDefinitions) 45 | 46 | 47 | ENABLE_MODULE_ECDH;%(PreprocessorDefinitions) 48 | ENABLE_MODULE_RECOVERY;%(PreprocessorDefinitions) 49 | 50 | 51 | 52 | 53 | 54 | 55 | dynamic 56 | 57 | 58 | static 59 | 60 | 61 | static 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /builds/msvc/vs2015/secp256k1/secp256k1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /builds/msvc/vs2015/secp256k1_bench/secp256k1_bench.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Application 5 | {0D4BC36A-0418-44B5-86FD-17A649316D6B} 6 | secp256k1_bench 7 | v140 8 | 02ad7ae2 9 | 10 | 11 | 12 | DebugDEXE 13 | Win32 14 | 15 | 16 | ReleaseDEXE 17 | Win32 18 | 19 | 20 | DebugDEXE 21 | x64 22 | 23 | 24 | ReleaseDEXE 25 | x64 26 | 27 | 28 | DebugLEXE 29 | Win32 30 | 31 | 32 | ReleaseLEXE 33 | Win32 34 | 35 | 36 | DebugLEXE 37 | x64 38 | 39 | 40 | ReleaseLEXE 41 | x64 42 | 43 | 44 | DebugSEXE 45 | Win32 46 | 47 | 48 | ReleaseSEXE 49 | Win32 50 | 51 | 52 | DebugSEXE 53 | x64 54 | 55 | 56 | ReleaseSEXE 57 | x64 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | true 69 | 70 | 71 | 72 | true 73 | 74 | 75 | true 76 | 77 | 78 | true 79 | 80 | 81 | true 82 | 83 | 84 | true 85 | 86 | 87 | true 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | {148600EA-561B-4C78-A80A-2EB5046D0420} 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /builds/msvc/vs2015/secp256k1_bench/secp256k1_bench.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | src 6 | 7 | 8 | src 9 | 10 | 11 | src 12 | 13 | 14 | src 15 | 16 | 17 | src 18 | 19 | 20 | src 21 | 22 | 23 | src 24 | 25 | 26 | 27 | 28 | {578c6a1d-8a88-4f0c-89bd-57bb1ef79644} 29 | 30 | 31 | 32 | 33 | src 34 | 35 | 36 | -------------------------------------------------------------------------------- /builds/msvc/vs2015/secp256k1_bench/secp256k1_bench.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /builds/msvc/vs2015/secp256k1_tests/secp256k1_tests.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Application 5 | {9F8CD353-5F8B-46D7-9DA3-17A06CCA634F} 6 | secp256k1_tests 7 | v140 8 | ae87ffba 9 | 10 | 11 | 12 | DebugDEXE 13 | Win32 14 | 15 | 16 | ReleaseDEXE 17 | Win32 18 | 19 | 20 | DebugDEXE 21 | x64 22 | 23 | 24 | ReleaseDEXE 25 | x64 26 | 27 | 28 | DebugLEXE 29 | Win32 30 | 31 | 32 | ReleaseLEXE 33 | Win32 34 | 35 | 36 | DebugLEXE 37 | x64 38 | 39 | 40 | ReleaseLEXE 41 | x64 42 | 43 | 44 | DebugSEXE 45 | Win32 46 | 47 | 48 | ReleaseSEXE 49 | Win32 50 | 51 | 52 | DebugSEXE 53 | x64 54 | 55 | 56 | ReleaseSEXE 57 | x64 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | true 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | {148600EA-561B-4C78-A80A-2EB5046D0420} 85 | 86 | 87 | -------------------------------------------------------------------------------- /builds/msvc/vs2015/secp256k1_tests/secp256k1_tests.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | src 6 | 7 | 8 | src 9 | 10 | 11 | 12 | 13 | {578c6a1d-8a88-4f0c-89bd-57bb1ef79644} 14 | 15 | 16 | 17 | 18 | src 19 | 20 | 21 | src 22 | 23 | 24 | -------------------------------------------------------------------------------- /builds/msvc/vs2015/secp256k1_tests/secp256k1_tests.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /builds/msvc/vs2017/secp256k1.import.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>secp256k1 Import Settings 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | $(ProjectDir)..\..\..\..\..\secp256k1\;%(AdditionalIncludeDirectories) 19 | inline=__inline;%(PreprocessorDefinitions) 20 | ECMULT_GEN_PREC_BITS=4;ECMULT_WINDOW_SIZE=15;%(PreprocessorDefinitions) 21 | 22 | 23 | secp256k1.lib;%(AdditionalDependencies) 24 | $(ProjectDir)..\..\..\..\..\secp256k1\bin\$(PlatformName)\Debug\$(PlatformToolset)\$(Linkage-secp256k1)\;%(AdditionalLibraryDirectories) 25 | $(ProjectDir)..\..\..\..\..\secp256k1\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-secp256k1)\;%(AdditionalLibraryDirectories) 26 | 27 | 28 | 29 | 30 | 31 | 32 | 36 | 40 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /builds/msvc/vs2017/secp256k1.import.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /builds/msvc/vs2017/secp256k1/secp256k1.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | <_PropertySheetDisplayName>SECP256K1 Common Settings 6 | AllRules.ruleset 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | $(RepoRoot)src\;$(RepoRoot)\include\;$(RepoRoot);%(AdditionalIncludeDirectories) 21 | 4244;4267;%(DisableSpecificWarnings) 22 | false 23 | inline=__inline;%(PreprocessorDefinitions) 24 | ECMULT_GEN_PREC_BITS=4;ECMULT_WINDOW_SIZE=15;%(PreprocessorDefinitions) 25 | SECP256K1_BUILD;%(PreprocessorDefinitions) 26 | 27 | USE_NUM_NONE;USE_FIELD_INV_BUILTIN;USE_SCALAR_INV_BUILTIN;%(PreprocessorDefinitions) 28 | USE_NUM_GMP;USE_FIELD_INV_NUM;USE_SCALAR_INV_NUM;%(PreprocessorDefinitions) 29 | 30 | 31 | USE_ASM_X86_64;%(PreprocessorDefinitions) 32 | 33 | 34 | USE_ENDOMORPHISM;%(PreprocessorDefinitions) 35 | 36 | HAVE_CONFIG_H;%(PreprocessorDefinitions) 37 | 38 | 39 | USE_FIELD_10X26;%(PreprocessorDefinitions) 40 | USE_FIELD_5X52;%(PreprocessorDefinitions) 41 | 42 | 43 | USE_SCALAR_8X32;%(PreprocessorDefinitions) 44 | USE_SCALAR_4X64;%(PreprocessorDefinitions) 45 | 46 | 47 | ENABLE_MODULE_ECDH;%(PreprocessorDefinitions) 48 | ENABLE_MODULE_RECOVERY;%(PreprocessorDefinitions) 49 | 50 | 51 | 52 | 53 | 54 | 55 | dynamic 56 | 57 | 58 | static 59 | 60 | 61 | static 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /builds/msvc/vs2017/secp256k1/secp256k1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /builds/msvc/vs2017/secp256k1_bench/secp256k1_bench.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Application 5 | {0D4BC36A-0418-44B5-86FD-17A649316D6B} 6 | secp256k1_bench 7 | v141 8 | 02ad7ae2 9 | 10 | 11 | 12 | DebugDEXE 13 | Win32 14 | 15 | 16 | ReleaseDEXE 17 | Win32 18 | 19 | 20 | DebugDEXE 21 | x64 22 | 23 | 24 | ReleaseDEXE 25 | x64 26 | 27 | 28 | DebugLEXE 29 | Win32 30 | 31 | 32 | ReleaseLEXE 33 | Win32 34 | 35 | 36 | DebugLEXE 37 | x64 38 | 39 | 40 | ReleaseLEXE 41 | x64 42 | 43 | 44 | DebugSEXE 45 | Win32 46 | 47 | 48 | ReleaseSEXE 49 | Win32 50 | 51 | 52 | DebugSEXE 53 | x64 54 | 55 | 56 | ReleaseSEXE 57 | x64 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | true 69 | 70 | 71 | 72 | true 73 | 74 | 75 | true 76 | 77 | 78 | true 79 | 80 | 81 | true 82 | 83 | 84 | true 85 | 86 | 87 | true 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | {148600EA-561B-4C78-A80A-2EB5046D0420} 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /builds/msvc/vs2017/secp256k1_bench/secp256k1_bench.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | src 6 | 7 | 8 | src 9 | 10 | 11 | src 12 | 13 | 14 | src 15 | 16 | 17 | src 18 | 19 | 20 | src 21 | 22 | 23 | src 24 | 25 | 26 | 27 | 28 | {578c6a1d-8a88-4f0c-89bd-57bb1ef79644} 29 | 30 | 31 | 32 | 33 | src 34 | 35 | 36 | -------------------------------------------------------------------------------- /builds/msvc/vs2017/secp256k1_bench/secp256k1_bench.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /builds/msvc/vs2017/secp256k1_tests/secp256k1_tests.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Application 5 | {9F8CD353-5F8B-46D7-9DA3-17A06CCA634F} 6 | secp256k1_tests 7 | v141 8 | ae87ffba 9 | 10 | 11 | 12 | DebugDEXE 13 | Win32 14 | 15 | 16 | ReleaseDEXE 17 | Win32 18 | 19 | 20 | DebugDEXE 21 | x64 22 | 23 | 24 | ReleaseDEXE 25 | x64 26 | 27 | 28 | DebugLEXE 29 | Win32 30 | 31 | 32 | ReleaseLEXE 33 | Win32 34 | 35 | 36 | DebugLEXE 37 | x64 38 | 39 | 40 | ReleaseLEXE 41 | x64 42 | 43 | 44 | DebugSEXE 45 | Win32 46 | 47 | 48 | ReleaseSEXE 49 | Win32 50 | 51 | 52 | DebugSEXE 53 | x64 54 | 55 | 56 | ReleaseSEXE 57 | x64 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | true 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | {148600EA-561B-4C78-A80A-2EB5046D0420} 85 | 86 | 87 | -------------------------------------------------------------------------------- /builds/msvc/vs2017/secp256k1_tests/secp256k1_tests.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | src 6 | 7 | 8 | src 9 | 10 | 11 | 12 | 13 | {578c6a1d-8a88-4f0c-89bd-57bb1ef79644} 14 | 15 | 16 | 17 | 18 | src 19 | 20 | 21 | src 22 | 23 | 24 | -------------------------------------------------------------------------------- /builds/msvc/vs2017/secp256k1_tests/secp256k1_tests.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /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 (lenbyte > inputlen - pos) { 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 (lenbyte > inputlen - pos) { 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 (lenbyte > inputlen - pos) { 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | /** A pointer to a function that applies hash function to a point 11 | * 12 | * Returns: 1 if a point was successfully hashed. 0 will cause ecdh to fail 13 | * Out: output: pointer to an array to be filled by the function 14 | * In: x: pointer to a 32-byte x coordinate 15 | * y: pointer to a 32-byte y coordinate 16 | * data: Arbitrary data pointer that is passed through 17 | */ 18 | typedef int (*secp256k1_ecdh_hash_function)( 19 | unsigned char *output, 20 | const unsigned char *x, 21 | const unsigned char *y, 22 | void *data 23 | ); 24 | 25 | /** An implementation of SHA256 hash function that applies to compressed public key. */ 26 | SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256; 27 | 28 | /** A default ecdh hash function (currently equal to secp256k1_ecdh_hash_function_sha256). */ 29 | SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default; 30 | 31 | /** Compute an EC Diffie-Hellman secret in constant time 32 | * Returns: 1: exponentiation was successful 33 | * 0: scalar was invalid (zero or overflow) 34 | * Args: ctx: pointer to a context object (cannot be NULL) 35 | * Out: output: pointer to an array to be filled by the function 36 | * In: pubkey: a pointer to a secp256k1_pubkey containing an 37 | * initialized public key 38 | * privkey: a 32-byte scalar with which to multiply the point 39 | * hashfp: pointer to a hash function. If NULL, secp256k1_ecdh_hash_function_sha256 is used 40 | * data: Arbitrary data pointer that is passed through 41 | */ 42 | SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( 43 | const secp256k1_context* ctx, 44 | unsigned char *output, 45 | const secp256k1_pubkey *pubkey, 46 | const unsigned char *privkey, 47 | secp256k1_ecdh_hash_function hashfp, 48 | void *data 49 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif /* SECP256K1_ECDH_H */ 56 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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: -L${libdir} -lsecp256k1 12 | Libs.private: @SECP_LIBS@ 13 | 14 | -------------------------------------------------------------------------------- /packaging/nuget/.gitignore: -------------------------------------------------------------------------------- 1 | *.nupkg 2 | -------------------------------------------------------------------------------- /packaging/nuget/gmp/package.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | ECHO Started nuget packaging build. 3 | ECHO. 4 | CD ..\ 5 | REM http://www.nuget.org/packages/gsl 6 | gsl -q -script:package.gsl gmp\package.config 7 | ECHO. 8 | REM http://nuget.codeplex.com/releases 9 | nuget pack package.nuspec -verbosity detailed 10 | ECHO. 11 | ECHO NOTE: Ignore warnings not applicable to native code: "Issue: Assembly outside lib folder." 12 | ECHO. 13 | ECHO Completed nuget packaging build. The package is in the following folder: 14 | CD -------------------------------------------------------------------------------- /packaging/nuget/gmp/package.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packaging/nuget/package.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | ECHO Started nuget packaging build. 3 | ECHO. 4 | REM http://www.nuget.org/packages/gsl 5 | gsl -q -script:package.gsl package.config 6 | ECHO. 7 | REM http://nuget.codeplex.com/releases 8 | nuget pack package.nuspec -verbosity detailed 9 | ECHO. 10 | ECHO NOTE: Ignore warnings not applicable to native code: "Issue: Assembly outside lib folder." 11 | ECHO. 12 | ECHO Completed nuget packaging build. The package is in the following folder: 13 | CD 14 | PAUSE -------------------------------------------------------------------------------- /packaging/nuget/package.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packaging/nuget/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /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_ECMULT_STATIC_PRECOMPUTATION 14 | #undef USE_ENDOMORPHISM 15 | #undef USE_EXTERNAL_ASM 16 | #undef USE_EXTERNAL_DEFAULT_CALLBACKS 17 | #undef USE_FIELD_10X26 18 | #undef USE_FIELD_5X52 19 | #undef USE_FIELD_INV_BUILTIN 20 | #undef USE_FIELD_INV_NUM 21 | #undef USE_NUM_GMP 22 | #undef USE_NUM_NONE 23 | #undef USE_SCALAR_4X64 24 | #undef USE_SCALAR_8X32 25 | #undef USE_SCALAR_INV_BUILTIN 26 | #undef USE_SCALAR_INV_NUM 27 | #undef ECMULT_WINDOW_SIZE 28 | 29 | #define USE_NUM_NONE 1 30 | #define USE_FIELD_INV_BUILTIN 1 31 | #define USE_SCALAR_INV_BUILTIN 1 32 | #define USE_FIELD_10X26 1 33 | #define USE_SCALAR_8X32 1 34 | #define ECMULT_WINDOW_SIZE 15 35 | 36 | #endif /* USE_BASIC_CONFIG */ 37 | 38 | #endif /* SECP256K1_BASIC_CONFIG_H */ 39 | -------------------------------------------------------------------------------- /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 13 | 14 | #ifndef _MSC_VER 15 | #include 16 | #else 17 | #include 18 | 19 | // TODO: implement gettimeofday for windows builds. 20 | static double gettimeofday(struct timeval* tv, void* unused) { 21 | return 0.0; 22 | } 23 | #endif 24 | 25 | static double gettimedouble(void) { 26 | struct timeval tv; 27 | gettimeofday(&tv, NULL); 28 | return tv.tv_usec * 0.000001 + tv.tv_sec; 29 | } 30 | 31 | void print_number(double x) { 32 | double y = x; 33 | int c = 0; 34 | if (y < 0.0) { 35 | y = -y; 36 | } 37 | while (y > 0 && y < 100.0) { 38 | y *= 10.0; 39 | c++; 40 | } 41 | printf("%.*f", c, x); 42 | } 43 | 44 | void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) { 45 | int i; 46 | double min = HUGE_VAL; 47 | double sum = 0.0; 48 | double max = 0.0; 49 | for (i = 0; i < count; i++) { 50 | double begin, total; 51 | if (setup != NULL) { 52 | setup(data); 53 | } 54 | begin = gettimedouble(); 55 | benchmark(data); 56 | total = gettimedouble() - begin; 57 | if (teardown != NULL) { 58 | teardown(data); 59 | } 60 | if (total < min) { 61 | min = total; 62 | } 63 | if (total > max) { 64 | max = total; 65 | } 66 | sum += total; 67 | } 68 | printf("%s: min ", name); 69 | print_number(min * 1000000.0 / iter); 70 | printf("us / avg "); 71 | print_number((sum / count) * 1000000.0 / iter); 72 | printf("us / max "); 73 | print_number(max * 1000000.0 / iter); 74 | printf("us\n"); 75 | } 76 | 77 | int have_flag(int argc, char** argv, char *flag) { 78 | char** argm = argv + argc; 79 | argv++; 80 | if (argv == argm) { 81 | return 1; 82 | } 83 | while (argv != NULL && argv != argm) { 84 | if (strcmp(*argv, flag) == 0) { 85 | return 1; 86 | } 87 | argv++; 88 | } 89 | return 0; 90 | } 91 | 92 | #endif /* SECP256K1_BENCH_H */ 93 | -------------------------------------------------------------------------------- /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, NULL, NULL) == 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/eckey.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECKEY_H 8 | #define SECP256K1_ECKEY_H 9 | 10 | #include 11 | 12 | #include "group.h" 13 | #include "scalar.h" 14 | #include "ecmult.h" 15 | #include "ecmult_gen.h" 16 | 17 | static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size); 18 | static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed); 19 | 20 | static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak); 21 | static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); 22 | static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak); 23 | static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); 24 | 25 | #endif /* SECP256K1_ECKEY_H */ 26 | -------------------------------------------------------------------------------- /src/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] == SECP256K1_TAG_PUBKEY_UNCOMPRESSED || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { 22 | secp256k1_fe x, y; 23 | if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { 24 | return 0; 25 | } 26 | secp256k1_ge_set_xy(elem, &x, &y); 27 | if ((pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD) && 28 | secp256k1_fe_is_odd(&y) != (pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { 29 | return 0; 30 | } 31 | return secp256k1_ge_is_valid_var(elem); 32 | } else { 33 | return 0; 34 | } 35 | } 36 | 37 | static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) { 38 | if (secp256k1_ge_is_infinity(elem)) { 39 | return 0; 40 | } 41 | secp256k1_fe_normalize_var(&elem->x); 42 | secp256k1_fe_normalize_var(&elem->y); 43 | secp256k1_fe_get_b32(&pub[1], &elem->x); 44 | if (compressed) { 45 | *size = 33; 46 | pub[0] = secp256k1_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN; 47 | } else { 48 | *size = 65; 49 | pub[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED; 50 | secp256k1_fe_get_b32(&pub[33], &elem->y); 51 | } 52 | return 1; 53 | } 54 | 55 | static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) { 56 | secp256k1_scalar_add(key, key, tweak); 57 | if (secp256k1_scalar_is_zero(key)) { 58 | return 0; 59 | } 60 | return 1; 61 | } 62 | 63 | static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { 64 | secp256k1_gej pt; 65 | secp256k1_scalar one; 66 | secp256k1_gej_set_ge(&pt, key); 67 | secp256k1_scalar_set_int(&one, 1); 68 | secp256k1_ecmult(ctx, &pt, &pt, &one, tweak); 69 | 70 | if (secp256k1_gej_is_infinity(&pt)) { 71 | return 0; 72 | } 73 | secp256k1_ge_set_gej(key, &pt); 74 | return 1; 75 | } 76 | 77 | static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak) { 78 | if (secp256k1_scalar_is_zero(tweak)) { 79 | return 0; 80 | } 81 | 82 | secp256k1_scalar_mul(key, key, tweak); 83 | return 1; 84 | } 85 | 86 | static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { 87 | secp256k1_scalar zero; 88 | secp256k1_gej pt; 89 | if (secp256k1_scalar_is_zero(tweak)) { 90 | return 0; 91 | } 92 | 93 | secp256k1_scalar_set_int(&zero, 0); 94 | secp256k1_gej_set_ge(&pt, key); 95 | secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero); 96 | secp256k1_ge_set_gej(key, &pt); 97 | return 1; 98 | } 99 | 100 | #endif /* SECP256K1_ECKEY_IMPL_H */ 101 | -------------------------------------------------------------------------------- /src/ecmult.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_H 8 | #define SECP256K1_ECMULT_H 9 | 10 | #include "num.h" 11 | #include "group.h" 12 | #include "scalar.h" 13 | #include "scratch.h" 14 | 15 | typedef struct { 16 | /* For accelerating the computation of a*P + b*G: */ 17 | secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */ 18 | #ifdef USE_ENDOMORPHISM 19 | secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */ 20 | #endif 21 | } secp256k1_ecmult_context; 22 | 23 | static const size_t SECP256K1_ECMULT_CONTEXT_PREALLOCATED_SIZE; 24 | static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx); 25 | static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, void **prealloc); 26 | static void secp256k1_ecmult_context_finalize_memcpy(secp256k1_ecmult_context *dst, const secp256k1_ecmult_context *src); 27 | static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx); 28 | static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx); 29 | 30 | /** Double multiply: R = na*A + ng*G */ 31 | static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng); 32 | 33 | typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data); 34 | 35 | /** 36 | * Multi-multiply: R = inp_g_sc * G + sum_i ni * Ai. 37 | * Chooses the right algorithm for a given number of points and scratch space 38 | * size. Resets and overwrites the given scratch space. If the points do not 39 | * fit in the scratch space the algorithm is repeatedly run with batches of 40 | * points. If no scratch space is given then a simple algorithm is used that 41 | * simply multiplies the points with the corresponding scalars and adds them up. 42 | * Returns: 1 on success (including when inp_g_sc is NULL and n is 0) 43 | * 0 if there is not enough scratch space for a single point or 44 | * callback returns 0 45 | */ 46 | static int secp256k1_ecmult_multi_var(const secp256k1_callback* error_callback, const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n); 47 | 48 | #endif /* SECP256K1_ECMULT_H */ 49 | -------------------------------------------------------------------------------- /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 | /** 14 | * Multiply: R = q*A (in constant-time) 15 | * Here `bits` should be set to the maximum bitlength of the _absolute value_ of `q`, plus 16 | * one because we internally sometimes add 2 to the number during the WNAF conversion. 17 | */ 18 | static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q, int bits); 19 | 20 | #endif /* SECP256K1_ECMULT_CONST_H */ 21 | -------------------------------------------------------------------------------- /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 | #if ECMULT_GEN_PREC_BITS != 2 && ECMULT_GEN_PREC_BITS != 4 && ECMULT_GEN_PREC_BITS != 8 14 | # error "Set ECMULT_GEN_PREC_BITS to 2, 4 or 8." 15 | #endif 16 | #define ECMULT_GEN_PREC_B ECMULT_GEN_PREC_BITS 17 | #define ECMULT_GEN_PREC_G (1 << ECMULT_GEN_PREC_B) 18 | #define ECMULT_GEN_PREC_N (256 / ECMULT_GEN_PREC_B) 19 | 20 | typedef struct { 21 | /* For accelerating the computation of a*G: 22 | * To harden against timing attacks, use the following mechanism: 23 | * * Break up the multiplicand into groups of PREC_B bits, called n_0, n_1, n_2, ..., n_(PREC_N-1). 24 | * * Compute sum(n_i * (PREC_G)^i * G + U_i, i=0 ... PREC_N-1), where: 25 | * * U_i = U * 2^i, for i=0 ... PREC_N-2 26 | * * U_i = U * (1-2^(PREC_N-1)), for i=PREC_N-1 27 | * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0 ... PREC_N-1) = 0. 28 | * For each i, and each of the PREC_G possible values of n_i, (n_i * (PREC_G)^i * G + U_i) is 29 | * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0 ... PREC_N-1). 30 | * None of the resulting prec group elements have a known scalar, and neither do any of 31 | * the intermediate sums while computing a*G. 32 | */ 33 | secp256k1_ge_storage (*prec)[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G]; /* prec[j][i] = (PREC_G)^j * i * G + U_i */ 34 | secp256k1_scalar blind; 35 | secp256k1_gej initial; 36 | } secp256k1_ecmult_gen_context; 37 | 38 | static const size_t SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE; 39 | static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context* ctx); 40 | static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, void **prealloc); 41 | static void secp256k1_ecmult_gen_context_finalize_memcpy(secp256k1_ecmult_gen_context *dst, const secp256k1_ecmult_gen_context* src); 42 | static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); 43 | static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx); 44 | 45 | /** Multiply with the generator: R = a*G */ 46 | static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); 47 | 48 | static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32); 49 | 50 | #endif /* SECP256K1_ECMULT_GEN_H */ 51 | -------------------------------------------------------------------------------- /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, n[i]*2^(i*26)) mod p 14 | * where p = 2^256 - 0x1000003D1 15 | */ 16 | uint32_t n[10]; 17 | #ifdef VERIFY 18 | int magnitude; 19 | int normalized; 20 | #endif 21 | } secp256k1_fe; 22 | 23 | /* Unpacks a constant into a overlapping multi-limbed FE element. */ 24 | #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ 25 | (d0) & 0x3FFFFFFUL, \ 26 | (((uint32_t)d0) >> 26) | (((uint32_t)(d1) & 0xFFFFFUL) << 6), \ 27 | (((uint32_t)d1) >> 20) | (((uint32_t)(d2) & 0x3FFFUL) << 12), \ 28 | (((uint32_t)d2) >> 14) | (((uint32_t)(d3) & 0xFFUL) << 18), \ 29 | (((uint32_t)d3) >> 8) | (((uint32_t)(d4) & 0x3UL) << 24), \ 30 | (((uint32_t)d4) >> 2) & 0x3FFFFFFUL, \ 31 | (((uint32_t)d4) >> 28) | (((uint32_t)(d5) & 0x3FFFFFUL) << 4), \ 32 | (((uint32_t)d5) >> 22) | (((uint32_t)(d6) & 0xFFFFUL) << 10), \ 33 | (((uint32_t)d6) >> 16) | (((uint32_t)(d7) & 0x3FFUL) << 16), \ 34 | (((uint32_t)d7) >> 10) \ 35 | } 36 | 37 | #ifdef VERIFY 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)), 1, 1} 39 | #else 40 | #define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} 41 | #endif 42 | 43 | typedef struct { 44 | uint32_t n[8]; 45 | } secp256k1_fe_storage; 46 | 47 | #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }} 48 | #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] 49 | 50 | #endif /* SECP256K1_FIELD_REPR_H */ 51 | -------------------------------------------------------------------------------- /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, n[i]*2^(i*52)) mod p 14 | * where p = 2^256 - 0x1000003D1 15 | */ 16 | uint64_t n[5]; 17 | #ifdef VERIFY 18 | int magnitude; 19 | int normalized; 20 | #endif 21 | } secp256k1_fe; 22 | 23 | /* Unpacks a constant into a overlapping multi-limbed FE element. */ 24 | #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ 25 | (d0) | (((uint64_t)(d1) & 0xFFFFFUL) << 32), \ 26 | ((uint64_t)(d1) >> 20) | (((uint64_t)(d2)) << 12) | (((uint64_t)(d3) & 0xFFUL) << 44), \ 27 | ((uint64_t)(d3) >> 8) | (((uint64_t)(d4) & 0xFFFFFFFUL) << 24), \ 28 | ((uint64_t)(d4) >> 28) | (((uint64_t)(d5)) << 4) | (((uint64_t)(d6) & 0xFFFFUL) << 36), \ 29 | ((uint64_t)(d6) >> 16) | (((uint64_t)(d7)) << 16) \ 30 | } 31 | 32 | #ifdef VERIFY 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)), 1, 1} 34 | #else 35 | #define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} 36 | #endif 37 | 38 | typedef struct { 39 | uint64_t n[4]; 40 | } secp256k1_fe_storage; 41 | 42 | #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \ 43 | (d0) | (((uint64_t)(d1)) << 32), \ 44 | (d2) | (((uint64_t)(d3)) << 32), \ 45 | (d4) | (((uint64_t)(d5)) << 32), \ 46 | (d6) | (((uint64_t)(d7)) << 32) \ 47 | }} 48 | 49 | #endif /* SECP256K1_FIELD_REPR_H */ 50 | -------------------------------------------------------------------------------- /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 | // Autotools creates libsecp256k1-config.h, of which ECMULT_GEN_PREC_BITS is needed. 8 | // ifndef guard so downstream users can define their own if they do not use autotools. 9 | #if !defined(ECMULT_GEN_PREC_BITS) 10 | #include "libsecp256k1-config.h" 11 | #endif 12 | #define USE_BASIC_CONFIG 1 13 | #include "basic-config.h" 14 | 15 | #include "include/secp256k1.h" 16 | #include "util.h" 17 | #include "field_impl.h" 18 | #include "scalar_impl.h" 19 | #include "group_impl.h" 20 | #include "ecmult_gen_impl.h" 21 | 22 | static void default_error_callback_fn(const char* str, void* data) { 23 | (void)data; 24 | fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); 25 | abort(); 26 | } 27 | 28 | static const secp256k1_callback default_error_callback = { 29 | default_error_callback_fn, 30 | NULL 31 | }; 32 | 33 | int main(int argc, char **argv) { 34 | secp256k1_ecmult_gen_context ctx; 35 | void *prealloc, *base; 36 | int inner; 37 | int outer; 38 | FILE* fp; 39 | 40 | (void)argc; 41 | (void)argv; 42 | 43 | fp = fopen("src/ecmult_static_context.h","w"); 44 | if (fp == NULL) { 45 | fprintf(stderr, "Could not open src/ecmult_static_context.h for writing!\n"); 46 | return -1; 47 | } 48 | 49 | fprintf(fp, "#ifndef _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); 50 | fprintf(fp, "#define _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); 51 | fprintf(fp, "#include \"src/group.h\"\n"); 52 | fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n"); 53 | fprintf(fp, "#if ECMULT_GEN_PREC_N != %d || ECMULT_GEN_PREC_G != %d\n", ECMULT_GEN_PREC_N, ECMULT_GEN_PREC_G); 54 | fprintf(fp, " #error configuration mismatch, invalid ECMULT_GEN_PREC_N, ECMULT_GEN_PREC_G. Try deleting ecmult_static_context.h before the build.\n"); 55 | fprintf(fp, "#endif\n"); 56 | fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_static_context[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G] = {\n"); 57 | 58 | base = checked_malloc(&default_error_callback, SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE); 59 | prealloc = base; 60 | secp256k1_ecmult_gen_context_init(&ctx); 61 | secp256k1_ecmult_gen_context_build(&ctx, &prealloc); 62 | for(outer = 0; outer != ECMULT_GEN_PREC_N; outer++) { 63 | fprintf(fp,"{\n"); 64 | for(inner = 0; inner != ECMULT_GEN_PREC_G; inner++) { 65 | 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])); 66 | if (inner != ECMULT_GEN_PREC_G - 1) { 67 | fprintf(fp,",\n"); 68 | } else { 69 | fprintf(fp,"\n"); 70 | } 71 | } 72 | if (outer != ECMULT_GEN_PREC_N - 1) { 73 | fprintf(fp,"},\n"); 74 | } else { 75 | fprintf(fp,"}\n"); 76 | } 77 | } 78 | fprintf(fp,"};\n"); 79 | secp256k1_ecmult_gen_context_clear(&ctx); 80 | free(base); 81 | 82 | fprintf(fp, "#undef SC\n"); 83 | fprintf(fp, "#endif\n"); 84 | fclose(fp); 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/java/org/bitcoin/NativeSecp256k1Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 the libsecp256k1 contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.bitcoin; 18 | 19 | public class NativeSecp256k1Util{ 20 | 21 | public static void assertEquals( int val, int val2, String message ) throws AssertFailException{ 22 | if( val != val2 ) 23 | throw new AssertFailException("FAIL: " + message); 24 | } 25 | 26 | public static void assertEquals( boolean val, boolean val2, String message ) throws AssertFailException{ 27 | if( val != val2 ) 28 | throw new AssertFailException("FAIL: " + message); 29 | else 30 | System.out.println("PASS: " + message); 31 | } 32 | 33 | public static void assertEquals( String val, String val2, String message ) throws AssertFailException{ 34 | if( !val.equals(val2) ) 35 | throw new AssertFailException("FAIL: " + message); 36 | else 37 | System.out.println("PASS: " + message); 38 | } 39 | 40 | public static class AssertFailException extends Exception { 41 | public AssertFailException(String message) { 42 | super( message ); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/java/org/bitcoin/Secp256k1Context.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 the libsecp256k1 contributors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.bitcoin; 18 | 19 | /** 20 | * This class holds the context reference used in native methods 21 | * to handle ECDSA operations. 22 | */ 23 | public class Secp256k1Context { 24 | private static final boolean enabled; //true if the library is loaded 25 | private static final long context; //ref to pointer to context obj 26 | 27 | static { //static initializer 28 | boolean isEnabled = true; 29 | long contextRef = -1; 30 | try { 31 | System.loadLibrary("secp256k1"); 32 | contextRef = secp256k1_init_context(); 33 | } catch (UnsatisfiedLinkError e) { 34 | System.out.println("UnsatisfiedLinkError: " + e.toString()); 35 | isEnabled = false; 36 | } 37 | enabled = isEnabled; 38 | context = contextRef; 39 | } 40 | 41 | public static boolean isEnabled() { 42 | return enabled; 43 | } 44 | 45 | public static long getContext() { 46 | if(!enabled) return -1; //sanity check 47 | return context; 48 | } 49 | 50 | private static native long secp256k1_init_context(); 51 | } 52 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) { 14 | unsigned char version = (y[31] & 0x01) | 0x02; 15 | secp256k1_sha256 sha; 16 | (void)data; 17 | 18 | secp256k1_sha256_initialize(&sha); 19 | secp256k1_sha256_write(&sha, &version, 1); 20 | secp256k1_sha256_write(&sha, x, 32); 21 | secp256k1_sha256_finalize(&sha, output); 22 | 23 | return 1; 24 | } 25 | 26 | const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256 = ecdh_hash_function_sha256; 27 | const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default = ecdh_hash_function_sha256; 28 | 29 | int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *output, const secp256k1_pubkey *point, const unsigned char *scalar, secp256k1_ecdh_hash_function hashfp, void *data) { 30 | int ret = 0; 31 | int overflow = 0; 32 | secp256k1_gej res; 33 | secp256k1_ge pt; 34 | secp256k1_scalar s; 35 | VERIFY_CHECK(ctx != NULL); 36 | ARG_CHECK(output != NULL); 37 | ARG_CHECK(point != NULL); 38 | ARG_CHECK(scalar != NULL); 39 | if (hashfp == NULL) { 40 | hashfp = secp256k1_ecdh_hash_function_default; 41 | } 42 | 43 | secp256k1_pubkey_load(ctx, &pt, point); 44 | secp256k1_scalar_set_b32(&s, scalar, &overflow); 45 | if (overflow || secp256k1_scalar_is_zero(&s)) { 46 | ret = 0; 47 | } else { 48 | unsigned char x[32]; 49 | unsigned char y[32]; 50 | 51 | secp256k1_ecmult_const(&res, &pt, &s, 256); 52 | secp256k1_ge_set_gej(&pt, &res); 53 | 54 | /* Compute a hash of the point */ 55 | secp256k1_fe_normalize(&pt.x); 56 | secp256k1_fe_normalize(&pt.y); 57 | secp256k1_fe_get_b32(x, &pt.x); 58 | secp256k1_fe_get_b32(y, &pt.y); 59 | 60 | ret = hashfp(output, x, y, data); 61 | } 62 | 63 | secp256k1_scalar_clear(&s); 64 | return ret; 65 | } 66 | 67 | #endif /* SECP256K1_MODULE_ECDH_MAIN_H */ 68 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/num_gmp.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_NUM_REPR_H 8 | #define SECP256K1_NUM_REPR_H 9 | 10 | #include 11 | 12 | #define NUM_LIMBS ((256+GMP_NUMB_BITS-1)/GMP_NUMB_BITS) 13 | 14 | typedef struct { 15 | mp_limb_t data[2*NUM_LIMBS]; 16 | int neg; 17 | int limbs; 18 | } secp256k1_num; 19 | 20 | #endif /* SECP256K1_NUM_REPR_H */ 21 | -------------------------------------------------------------------------------- /src/num_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_NUM_IMPL_H 8 | #define SECP256K1_NUM_IMPL_H 9 | 10 | #if defined HAVE_CONFIG_H 11 | #include "libsecp256k1-config.h" 12 | #endif 13 | 14 | #include "num.h" 15 | 16 | #if defined(USE_NUM_GMP) 17 | #include "num_gmp_impl.h" 18 | #elif defined(USE_NUM_NONE) 19 | /* Nothing. */ 20 | #else 21 | #error "Please select num implementation" 22 | #endif 23 | 24 | #endif /* SECP256K1_NUM_IMPL_H */ 25 | -------------------------------------------------------------------------------- /src/scalar_4x64.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef struct { 14 | uint64_t d[4]; 15 | } secp256k1_scalar; 16 | 17 | #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}} 18 | 19 | #endif /* SECP256K1_SCALAR_REPR_H */ 20 | -------------------------------------------------------------------------------- /src/scalar_8x32.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef struct { 14 | uint32_t d[8]; 15 | } secp256k1_scalar; 16 | 17 | #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)}} 18 | 19 | #endif /* SECP256K1_SCALAR_REPR_H */ 20 | -------------------------------------------------------------------------------- /src/scalar_low.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef uint32_t secp256k1_scalar; 14 | 15 | #endif /* SECP256K1_SCALAR_REPR_H */ 16 | -------------------------------------------------------------------------------- /src/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 | -------------------------------------------------------------------------------- /src/scratch.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2017 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef _SECP256K1_SCRATCH_ 8 | #define _SECP256K1_SCRATCH_ 9 | 10 | /* The typedef is used internally; the struct name is used in the public API 11 | * (where it is exposed as a different typedef) */ 12 | typedef struct secp256k1_scratch_space_struct { 13 | /** guard against interpreting this object as other types */ 14 | unsigned char magic[8]; 15 | /** actual allocated data */ 16 | void *data; 17 | /** amount that has been allocated (i.e. `data + offset` is the next 18 | * available pointer) */ 19 | size_t alloc_size; 20 | /** maximum size available to allocate */ 21 | size_t max_size; 22 | } secp256k1_scratch; 23 | 24 | static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size); 25 | 26 | static void secp256k1_scratch_destroy(const secp256k1_callback* error_callback, secp256k1_scratch* scratch); 27 | 28 | /** Returns an opaque object used to "checkpoint" a scratch space. Used 29 | * with `secp256k1_scratch_apply_checkpoint` to undo allocations. */ 30 | static size_t secp256k1_scratch_checkpoint(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch); 31 | 32 | /** Applies a check point received from `secp256k1_scratch_checkpoint`, 33 | * undoing all allocations since that point. */ 34 | static void secp256k1_scratch_apply_checkpoint(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t checkpoint); 35 | 36 | /** Returns the maximum allocation the scratch space will allow */ 37 | static size_t secp256k1_scratch_max_allocation(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch, size_t n_objects); 38 | 39 | /** Returns a pointer into the most recently allocated frame, or NULL if there is insufficient available space */ 40 | static void *secp256k1_scratch_alloc(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t n); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/scratch_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2017 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef _SECP256K1_SCRATCH_IMPL_H_ 8 | #define _SECP256K1_SCRATCH_IMPL_H_ 9 | 10 | #include "util.h" 11 | #include "scratch.h" 12 | 13 | static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t size) { 14 | const size_t base_alloc = ((sizeof(secp256k1_scratch) + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT; 15 | void *alloc = checked_malloc(error_callback, base_alloc + size); 16 | secp256k1_scratch* ret = (secp256k1_scratch *)alloc; 17 | if (ret != NULL) { 18 | memset(ret, 0, sizeof(*ret)); 19 | memcpy(ret->magic, "scratch", 8); 20 | ret->data = (void *) ((char *) alloc + base_alloc); 21 | ret->max_size = size; 22 | } 23 | return ret; 24 | } 25 | 26 | static void secp256k1_scratch_destroy(const secp256k1_callback* error_callback, secp256k1_scratch* scratch) { 27 | if (scratch != NULL) { 28 | VERIFY_CHECK(scratch->alloc_size == 0); /* all checkpoints should be applied */ 29 | if (memcmp(scratch->magic, "scratch", 8) != 0) { 30 | secp256k1_callback_call(error_callback, "invalid scratch space"); 31 | return; 32 | } 33 | memset(scratch->magic, 0, sizeof(scratch->magic)); 34 | free(scratch); 35 | } 36 | } 37 | 38 | static size_t secp256k1_scratch_checkpoint(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch) { 39 | if (memcmp(scratch->magic, "scratch", 8) != 0) { 40 | secp256k1_callback_call(error_callback, "invalid scratch space"); 41 | return 0; 42 | } 43 | return scratch->alloc_size; 44 | } 45 | 46 | static void secp256k1_scratch_apply_checkpoint(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t checkpoint) { 47 | if (memcmp(scratch->magic, "scratch", 8) != 0) { 48 | secp256k1_callback_call(error_callback, "invalid scratch space"); 49 | return; 50 | } 51 | if (checkpoint > scratch->alloc_size) { 52 | secp256k1_callback_call(error_callback, "invalid checkpoint"); 53 | return; 54 | } 55 | scratch->alloc_size = checkpoint; 56 | } 57 | 58 | static size_t secp256k1_scratch_max_allocation(const secp256k1_callback* error_callback, const secp256k1_scratch* scratch, size_t objects) { 59 | if (memcmp(scratch->magic, "scratch", 8) != 0) { 60 | secp256k1_callback_call(error_callback, "invalid scratch space"); 61 | return 0; 62 | } 63 | if (scratch->max_size - scratch->alloc_size <= objects * (ALIGNMENT - 1)) { 64 | return 0; 65 | } 66 | return scratch->max_size - scratch->alloc_size - objects * (ALIGNMENT - 1); 67 | } 68 | 69 | static void *secp256k1_scratch_alloc(const secp256k1_callback* error_callback, secp256k1_scratch* scratch, size_t size) { 70 | void *ret; 71 | size = ROUND_TO_ALIGN(size); 72 | 73 | if (memcmp(scratch->magic, "scratch", 8) != 0) { 74 | secp256k1_callback_call(error_callback, "invalid scratch space"); 75 | return NULL; 76 | } 77 | 78 | if (size > scratch->max_size - scratch->alloc_size) { 79 | return NULL; 80 | } 81 | ret = (void *) ((char *) scratch->data + scratch->alloc_size); 82 | memset(ret, 0, size); 83 | scratch->alloc_size += size; 84 | 85 | return ret; 86 | } 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------