Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding random tests against a naive implementation #641

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ build-aux/compile
build-aux/test-driver
src/stamp-h1
libsecp256k1.pc
ecc-secp256k1
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
language: c
language: rust
os: linux
addons:
apt:
Expand Down Expand Up @@ -65,4 +65,4 @@ before_script: ./autogen.sh
script:
- if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi
- if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi
- ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-recovery=$RECOVERY --enable-jni=$JNI $EXTRAFLAGS $USE_HOST && make -j2 $BUILD
- ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-recovery=$RECOVERY --enable-jni=$JNI $EXTRAFLAGS $USE_HOST && make -j2 V=1 $BUILD
27 changes: 25 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ noinst_HEADERS += contrib/lax_der_parsing.c
noinst_HEADERS += contrib/lax_der_privatekey_parsing.h
noinst_HEADERS += contrib/lax_der_privatekey_parsing.c

NAIVE_SECP=ecc-secp256k1


if USE_EXTERNAL_ASM
COMMON_LIB = libsecp256k1_common.la
noinst_LTLIBRARIES = $(COMMON_LIB)
Expand Down Expand Up @@ -103,7 +106,7 @@ tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src -I$(top_srcdir)/include $
if !ENABLE_COVERAGE
tests_CPPFLAGS += -DVERIFY
endif
tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB)
tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) $(SECP_TEST_ONLY_LIBS)
tests_LDFLAGS = -static
TESTS += tests
endif
Expand Down Expand Up @@ -150,6 +153,8 @@ check-java: libsecp256k1.la $(JAVA_GUAVA) .stamp-java
endif
endif


TESTS_OBJS =
if USE_ECMULT_STATIC_PRECOMPUTATION
CPPFLAGS_FOR_BUILD +=-I$(top_srcdir)

Expand All @@ -162,7 +167,7 @@ $(gen_context_BIN): $(gen_context_OBJECTS)
$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) $^ -o $@

$(libsecp256k1_la_OBJECTS): src/ecmult_static_context.h
$(tests_OBJECTS): src/ecmult_static_context.h
TESTS_OBJS += src/ecmult_static_context.h
$(bench_internal_OBJECTS): src/ecmult_static_context.h
$(bench_ecmult_OBJECTS): src/ecmult_static_context.h

Expand All @@ -181,3 +186,21 @@ endif
if ENABLE_MODULE_RECOVERY
include src/modules/recovery/Makefile.am.include
endif


if ENABLE_RUST_NAIVETESTS
TESTS_OBJS += $(NAIVE_SECP)
$(NAIVE_SECP):
@echo "IMPORTANT"
wget -O ecc-secp256k1.tar.gz https://github.com/elichai/ecc-secp256k1/archive/v0.2.0.tar.gz
sha256sum -c --status ecc-secp256k1.tar.gz.sha256 # Should fail the building if doesn't pass
tar xf ecc-secp256k1.tar.gz && mv ecc-secp256k1-0.2.0 ecc-secp256k1
cd ecc-secp256k1 && RUSTFLAGS="-C opt-level=0" cargo build --release --features=ffi # No need for optimizations. tests only.
cp ./ecc-secp256k1/ecc_secp256k1.h ./src/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copying libraries and header files around will be confusing. Can't you avoid it by directly linking to the files in the ecc-secp256k1 dir?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it was simpler by yeah it's possible to link directly into the files there.
about the header, don't you want it to be under source control here?



clean-local:
cargo clean --manifest-path="./ecc-secp256k1/Cargo.toml" 2> /dev/null | true
endif

$(tests_OBJECTS): $(TESTS_OBJS)
14 changes: 14 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ AC_ARG_ENABLE(openssl_tests,
[enable_openssl_tests=$enableval],
[enable_openssl_tests=auto])

AC_ARG_ENABLE(rust_naivetests,
AS_HELP_STRING([--enable-rust-naivetests],[enable tests against naive rust implementation [default=auto]]),
[enable_rust_naivetests=$enableval],
[enable_rust_naivetests=auto])

AC_ARG_ENABLE(experimental,
AS_HELP_STRING([--enable-experimental],[allow experimental configure options [default=no]]),
[use_experimental=$enableval],
Expand Down Expand Up @@ -442,10 +447,17 @@ if test x"$use_tests" = x"yes"; then
AC_MSG_ERROR([OpenSSL tests requested but OpenSSL with EC support is not available])
fi
fi
if test x"$enable_rust_naivetests" != x"no"; then
AC_DEFINE(ENABLE_RUST_NAIVETESTS, 1, [Define this symbol if you want to build the rust tests])
SECP_TEST_ONLY_LIBS="$SECP_TEST_ONLY_LIBS -lecc_secp256k1 -ldl -lpthread -lm -L./ecc-secp256k1/target/release"
fi
else
if test x"$enable_openssl_tests" = x"yes"; then
AC_MSG_ERROR([OpenSSL tests requested but tests are not enabled])
fi
if test x"$enable_rust_naivetests" = x"yes"; then
AC_MSG_ERROR([Rust naiveTests requested but tests are not enabled])
fi
fi

if test x"$use_jni" != x"no"; then
Expand Down Expand Up @@ -523,6 +535,7 @@ AC_SUBST(JNI_INCLUDES)
AC_SUBST(SECP_INCLUDES)
AC_SUBST(SECP_LIBS)
AC_SUBST(SECP_TEST_LIBS)
AC_SUBST(SECP_TEST_ONLY_LIBS)
AC_SUBST(SECP_TEST_INCLUDES)
AM_CONDITIONAL([ENABLE_COVERAGE], [test x"$enable_coverage" = x"yes"])
AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"])
Expand All @@ -534,6 +547,7 @@ AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"ye
AM_CONDITIONAL([USE_JNI], [test x"$use_jni" = x"yes"])
AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$use_external_asm" = x"yes"])
AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm"])
AM_CONDITIONAL([ENABLE_RUST_NAIVETESTS], [test x"$enable_rust_naivetests" != x"no"])

dnl make sure nothing new is exported so that we don't break the cache
PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH"
Expand Down
1 change: 1 addition & 0 deletions ecc-secp256k1.tar.gz.sha256
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5df36775e75973184332352108340a033cc8971c37f91bed7986e7a18b18a387 ecc-secp256k1.tar.gz
61 changes: 61 additions & 0 deletions src/ecc_secp256k1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Sign an ECDSA Signature
* The message should be a hashed 32 bytes.
* Input: msg -> pointer to 32 bytes message.
* privkey -> pointer to 32 bytes private key.
* Output: sig_out -> pointer to a 64 bytes buffer.
* Returns:
* 1 - Finished successfully.
* 0 - Failed.
*/
int ecc_secp256k1_ecdsa_sign(unsigned char *sig_out,
const unsigned char *msg,
const unsigned char *privkey);

/**
* Verify a ECDSA Signature
* Accepts either compressed(33 btes) or uncompressed(65 bytes) public key. using the flag (1==compressed, 0==uncompressed).
* Input: sig -> pointer to 64 bytes signature.
* msg -> 32 bytes result of a hash. (***Make Sure you hash the message yourself! otherwise it's easily broken***)
* pubkey -> pointer to 33 or 65 bytes pubkey depending on the compressed flag.
* compressed -> 1 for compressed, 0 for uncompressed.
* Returns:
* 1 - The signature is valid.
* 0 - Signature is not valid.
* -1 - Some other problem.
*/
int ecc_secp256k1_ecdsa_verify(const unsigned char *sig,
const unsigned char *msg,
const unsigned char *pubkey,
int compressed);

/**
* Sign a Schnorr Signature
* The message should be a hashed 32 bytes.
* Input: msg -> pointer to 32 bytes message.
* privkey -> pointer to 32 bytes private key.
* Output: sig_out -> pointer to a 64 bytes buffer.
* Returns:
* 1 - Finished successfully.
* 0 - Failed.
*/
int ecc_secp256k1_schnorr_sign(unsigned char *sig_out,
const unsigned char *msg,
const unsigned char *privkey);

/**
* Verify a Schnorr Signature
* Accepts either compressed(33 btes) or uncompressed(65 bytes) public key. using the flag (1==compressed, 0==uncompressed).
* Input: sig -> pointer to 64 bytes signature.
* msg -> 32 bytes result of a hash. (***Make Sure you hash the message yourself! otherwise it's easily broken***)
* pubkey -> pointer to 33 or 65 bytes pubkey depending on the compressed flag.
* compressed -> 1 for compressed, 0 for uncompressed.
* Returns:
* 1 - The signature is valid.
* 0 - Signature is not valid.
* -1 - Some other problem.
*/
int ecc_secp256k1_schnorr_verify(const unsigned char *sig,
const unsigned char *msg,
const unsigned char *pubkey,
int compressed);
52 changes: 52 additions & 0 deletions src/tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#include "include/secp256k1_preallocated.h"
#include "testrand_impl.h"

#ifdef ENABLE_RUST_NAIVETESTS
#include "ecc_secp256k1.h"
#endif

#ifdef ENABLE_OPENSSL_TESTS
#include "openssl/bn.h"
#include "openssl/ec.h"
Expand Down Expand Up @@ -4134,6 +4138,50 @@ void test_ecdsa_sign_verify(void) {
CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &pub, &msg));
}

#ifdef ENABLE_RUST_NAIVETESTS
void test_ecdsa_sign_verify_rust(void) {

secp256k1_scalar msg, key;
unsigned char raw_key[32];
unsigned char raw_msg[32];
unsigned char raw_pubkey[65];
unsigned char raw_sig[64];
size_t pubkey_len = sizeof(raw_pubkey);
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;

random_scalar_order_test(&msg);
random_scalar_order_test(&key);

secp256k1_scalar_get_b32(raw_msg, &msg);
secp256k1_scalar_get_b32(raw_key, &key);

CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, raw_key) == 1);
secp256k1_ec_pubkey_serialize(ctx, raw_pubkey, &pubkey_len, &pubkey, SECP256K1_EC_UNCOMPRESSED);
/* Sign with secp256k1 */
CHECK(secp256k1_ecdsa_sign(ctx, &sig, raw_msg, raw_key, NULL, NULL) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, &sig, raw_msg, &pubkey) == 1);
secp256k1_ecdsa_signature_serialize_compact(ctx, raw_sig, &sig);
/* Verify with ecc-secp256k1(rust) */
CHECK(ecc_secp256k1_ecdsa_verify(raw_sig, raw_msg, raw_pubkey, 0) == 1);
/* Sign with ecc-secp256k1(rust) */
CHECK(ecc_secp256k1_ecdsa_sign(raw_sig, raw_msg, raw_key) == 1);
/* Verify with secp256k1 */
CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, raw_sig) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, &sig, raw_msg, &pubkey) == 1);
}


void run_ecdsa_sign_verify_rust(void) {
int i;
for (i = 0; i < 10*count; i++) {
test_ecdsa_sign_verify_rust();
}
}

#endif


void run_ecdsa_sign_verify(void) {
int i;
for (i = 0; i < 10*count; i++) {
Expand Down Expand Up @@ -5290,6 +5338,10 @@ int main(int argc, char **argv) {
run_recovery_tests();
#endif

#ifdef ENABLE_RUST_NAIVETESTS
run_ecdsa_sign_verify_rust();
#endif

secp256k1_rand256(run32);
printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]);

Expand Down