]> Git Repo - secp256k1.git/commitdiff
Merge #930: Add ARM32/ARM64 CI
authorJonas Nick <[email protected]>
Thu, 13 May 2021 19:31:49 +0000 (19:31 +0000)
committerJonas Nick <[email protected]>
Thu, 13 May 2021 19:31:56 +0000 (19:31 +0000)
8bbad7a18e5dc5054b27ae44ea0c8dffe050f6bf Add asm build to ARM32 CI (Pieter Wuille)
7d65ed5214273275841f5aa272ad561df7ea7f21 Add ARM32/ARM64 CI (Pieter Wuille)

Pull request description:

ACKs for top commit:
  real-or-random:
    ACK 8bbad7a18e5dc5054b27ae44ea0c8dffe050f6bf CI output looks fine
  jonasnick:
    ACK 8bbad7a18e5dc5054b27ae44ea0c8dffe050f6bf

Tree-SHA512: 090a52af6914cf9fb659f9626a8224d82c8da81f6e628b7300e34851e198d8299dfd25789c0f1d6f2c79f58b5413be498f9fba43bc50238480fe6524b640538a

29 files changed:
Makefile.am
contrib/lax_der_parsing.c
contrib/lax_der_parsing.h
contrib/lax_der_privatekey_parsing.c
contrib/lax_der_privatekey_parsing.h
include/secp256k1.h
include/secp256k1_extrakeys.h
src/bench_ecdh.c
src/bench_ecmult.c
src/bench_internal.c
src/bench_recover.c
src/bench_schnorrsig.c
src/bench_sign.c
src/bench_verify.c
src/gen_context.c
src/group_impl.h
src/modules/ecdh/main_impl.h
src/modules/extrakeys/main_impl.h
src/modules/extrakeys/tests_exhaustive_impl.h
src/modules/extrakeys/tests_impl.h
src/modules/recovery/main_impl.h
src/modules/recovery/tests_exhaustive_impl.h
src/modules/schnorrsig/main_impl.h
src/modules/schnorrsig/tests_exhaustive_impl.h
src/modules/schnorrsig/tests_impl.h
src/secp256k1.c
src/tests.c
src/tests_exhaustive.c
src/valgrind_ctime_test.c

index 053e435fb3b4c941144172b37dfb4ddc7cf63ca1..23b29281df882a2b96448c6c65b2edced6d39c00 100644 (file)
@@ -101,7 +101,7 @@ if VALGRIND_ENABLED
 tests_CPPFLAGS += -DVALGRIND
 noinst_PROGRAMS += valgrind_ctime_test
 valgrind_ctime_test_SOURCES = src/valgrind_ctime_test.c
-valgrind_ctime_test_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_LIBS) $(COMMON_LIB)
+valgrind_ctime_test_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB)
 endif
 if !ENABLE_COVERAGE
 tests_CPPFLAGS += -DVERIFY
@@ -129,7 +129,7 @@ CPPFLAGS_FOR_BUILD +=-I$(top_srcdir) -I$(builddir)/src
 gen_context_OBJECTS = gen_context.o
 gen_context_BIN = gen_context$(BUILD_EXEEXT)
 gen_%.o: src/gen_%.c src/libsecp256k1-config.h
-       $(CC_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@
+       $(CC_FOR_BUILD) $(DEFS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@
 
 $(gen_context_BIN): $(gen_context_OBJECTS)
        $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) $^ -o $@
index c1627e37e9e11900796d426eae58056c525b1a11..885a817169a5d383533d77e30460c7bdf152832b 100644 (file)
@@ -5,7 +5,6 @@
  ***********************************************************************/
 
 #include <string.h>
-#include <secp256k1.h>
 
 #include "lax_der_parsing.h"
 
index 6b7255e28f5bc78ffdc48940821d8fed062eaa55..034a38e6a0e1d0fb303c78bb9fd0ac20ecd44358 100644 (file)
 #ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H
 #define SECP256K1_CONTRIB_LAX_DER_PARSING_H
 
+/* #include secp256k1.h only when it hasn't been included yet.
+   This enables this file to be #included directly in other project
+   files (such as tests.c) without the need to set an explicit -I flag,
+   which would be necessary to locate secp256k1.h. */
+#ifndef SECP256K1_H
 #include <secp256k1.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
index 429760fbb6d19ab0afff7c36d4f37431b8ecd932..372e84ea4eb04251e73257d1070a372b15520a9a 100644 (file)
@@ -5,7 +5,6 @@
  ***********************************************************************/
 
 #include <string.h>
-#include <secp256k1.h>
 
 #include "lax_der_privatekey_parsing.h"
 
index 602c7c556ad153a06459222663db08b1c4e8df7c..1a8ad8ae0c3b0835d19c4c7cc7df519557a1c33d 100644 (file)
 #ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H
 #define SECP256K1_CONTRIB_BER_PRIVATEKEY_H
 
+/* #include secp256k1.h only when it hasn't been included yet.
+   This enables this file to be #included directly in other project
+   files (such as tests.c) without the need to set an explicit -I flag,
+   which would be necessary to locate secp256k1.h. */
+#ifndef SECP256K1_H
 #include <secp256k1.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
index b616fc11ec38c5c1444bb3968d10d741a84162ad..c05a06d29dd21646fcebc4e72c3fb0e84cb524e3 100644 (file)
@@ -7,7 +7,9 @@ extern "C" {
 
 #include <stddef.h>
 
-/* These rules specify the order of arguments in API calls:
+/* Unless explicitly stated all pointer arguments must not be NULL.
+ *
+ * The following rules specify the order of arguments in API calls:
  *
  * 1. Context pointers go first, followed by output arguments, combined
  *    output/input arguments, and finally input-only arguments.
@@ -61,8 +63,9 @@ typedef struct secp256k1_scratch_space_struct secp256k1_scratch_space;
  *  The exact representation of data inside is implementation defined and not
  *  guaranteed to be portable between different platforms or versions. It is
  *  however guaranteed to be 64 bytes in size, and can be safely copied/moved.
- *  If you need to convert to a format suitable for storage, transmission, or
- *  comparison, use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse.
+ *  If you need to convert to a format suitable for storage or transmission,
+ *  use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. To
+ *  compare keys, use secp256k1_ec_pubkey_cmp.
  */
 typedef struct {
     unsigned char data[64];
@@ -381,6 +384,21 @@ SECP256K1_API int secp256k1_ec_pubkey_serialize(
     unsigned int flags
 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
 
+/** Compare two public keys using lexicographic (of compressed serialization) order
+ *
+ *  Returns: <0 if the first public key is less than the second
+ *           >0 if the first public key is greater than the second
+ *           0 if the two public keys are equal
+ *  Args: ctx:      a secp256k1 context object.
+ *  In:   pubkey1:  first public key to compare
+ *        pubkey2:  second public key to compare
+ */
+SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp(
+    const secp256k1_context* ctx,
+    const secp256k1_pubkey* pubkey1,
+    const secp256k1_pubkey* pubkey2
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
+
 /** Parse an ECDSA signature in compact (64 bytes) format.
  *
  *  Returns: 1 when the signature could be parsed, 0 otherwise.
index 6fc7b290f8cae62afaaf9e81b60ecc29a9341186..0a37fb6b9d31809fed5e674c2e035d80ea2db7d8 100644 (file)
@@ -15,9 +15,9 @@ extern "C" {
  *  The exact representation of data inside is implementation defined and not
  *  guaranteed to be portable between different platforms or versions. It is
  *  however guaranteed to be 64 bytes in size, and can be safely copied/moved.
- *  If you need to convert to a format suitable for storage, transmission, or
- *  comparison, use secp256k1_xonly_pubkey_serialize and
- *  secp256k1_xonly_pubkey_parse.
+ *  If you need to convert to a format suitable for storage, transmission, use
+ *  use secp256k1_xonly_pubkey_serialize and secp256k1_xonly_pubkey_parse. To
+ *  compare keys, use secp256k1_xonly_pubkey_cmp.
  */
 typedef struct {
     unsigned char data[64];
@@ -67,6 +67,21 @@ SECP256K1_API int secp256k1_xonly_pubkey_serialize(
     const secp256k1_xonly_pubkey* pubkey
 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
 
+/** Compare two x-only public keys using lexicographic order
+ *
+ *  Returns: <0 if the first public key is less than the second
+ *           >0 if the first public key is greater than the second
+ *           0 if the two public keys are equal
+ *  Args: ctx:      a secp256k1 context object.
+ *  In:   pubkey1:  first public key to compare
+ *        pubkey2:  second public key to compare
+ */
+SECP256K1_API int secp256k1_xonly_pubkey_cmp(
+    const secp256k1_context* ctx,
+    const secp256k1_xonly_pubkey* pk1,
+    const secp256k1_xonly_pubkey* pk2
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
+
 /** Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
  *
  *  Returns: 1 if the public key was successfully converted
index ab4b8f4244f2b54539b0f4a5d5caf2cfd33a4055..cb020d26b4d9969cb54c5e4a9c5476bd70090f04 100644 (file)
@@ -6,8 +6,8 @@
 
 #include <string.h>
 
-#include "include/secp256k1.h"
-#include "include/secp256k1_ecdh.h"
+#include "../include/secp256k1.h"
+#include "../include/secp256k1_ecdh.h"
 #include "util.h"
 #include "bench.h"
 
index a536ab2aec4de2db6147ea1bcbd401ee3d374c0c..68eff676edacc11dbaa124fc8ed37dfa017d4c49 100644 (file)
@@ -6,8 +6,8 @@
 #include <stdio.h>
 
 #include "secp256k1.c"
+#include "../include/secp256k1.h"
 
-#include "include/secp256k1.h"
 #include "util.h"
 #include "hash_impl.h"
 #include "field_impl.h"
index dfe99cf3a77a389587d42a98b36f8e11a889df07..161b1c4a47666e88b36310fc79675a8f3f13d6c9 100644 (file)
@@ -6,8 +6,8 @@
 #include <stdio.h>
 
 #include "secp256k1.c"
+#include "../include/secp256k1.h"
 
-#include "include/secp256k1.h"
 #include "assumptions.h"
 #include "util.h"
 #include "hash_impl.h"
index 3f6270ce84fd5ad497c5a2904b0b8e026838feb4..4bcac19dc0a398669a53c55da6ac4b248f98546b 100644 (file)
@@ -4,8 +4,8 @@
  * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
  ***********************************************************************/
 
-#include "include/secp256k1.h"
-#include "include/secp256k1_recovery.h"
+#include "../include/secp256k1.h"
+#include "../include/secp256k1_recovery.h"
 #include "util.h"
 #include "bench.h"
 
index f7f591c41dcea51e3219b1eea959dc2958e46dde..dfea1441484eb730de1f829f2439853efe749818 100644 (file)
@@ -8,8 +8,8 @@
 #include <stdlib.h>
 
 
-#include "include/secp256k1.h"
-#include "include/secp256k1_schnorrsig.h"
+#include "../include/secp256k1.h"
+#include "../include/secp256k1_schnorrsig.h"
 #include "util.h"
 #include "bench.h"
 
index 933f367c4b6a65a03699f31ae61d91e21ca0e370..f659c18c92d0bd20fee399b2c1a0f3ca1a27a41b 100644 (file)
@@ -4,7 +4,7 @@
  * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
  ***********************************************************************/
 
-#include "include/secp256k1.h"
+#include "../include/secp256k1.h"
 #include "util.h"
 #include "bench.h"
 
index c56aefd3699c06d6bf5bf4022801387b7762ca64..565ae4beec8a5726b267cd141d61ecf50c101c4f 100644 (file)
@@ -7,7 +7,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "include/secp256k1.h"
+#include "../include/secp256k1.h"
 #include "util.h"
 #include "bench.h"
 
index 024c55726170f044e1a760921389d0b7e150ac67..8fab7aa49d80c1c13c9e30e854297c6e5f90a13b 100644 (file)
 /* We can't require the precomputed tables when creating them. */
 #undef USE_ECMULT_STATIC_PRECOMPUTATION
 
-#include "include/secp256k1.h"
+/* In principle we could use external ASM, but this yields only a minor speedup in
+   build time and it's very complicated. In particular when cross-compiling, we'd
+   need to build the external ASM for the build and the host machine. */
+#undef USE_EXTERNAL_ASM
+
+#include "../include/secp256k1.h"
 #include "assumptions.h"
 #include "util.h"
 #include "field_impl.h"
index 19ebd8f44ee384b9715704dc3eec48466f42458f..47aea32be184a0f401403ffbf98067d7f4f5bb9d 100644 (file)
@@ -100,8 +100,8 @@ static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a) {
 
 static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) {
     secp256k1_fe z2, z3;
-    r->infinity = a->infinity;
     if (a->infinity) {
+        secp256k1_ge_set_infinity(r);
         return;
     }
     secp256k1_fe_inv_var(&a->z, &a->z);
@@ -110,8 +110,7 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) {
     secp256k1_fe_mul(&a->x, &a->x, &z2);
     secp256k1_fe_mul(&a->y, &a->y, &z3);
     secp256k1_fe_set_int(&a->z, 1);
-    r->x = a->x;
-    r->y = a->y;
+    secp256k1_ge_set_xy(r, &a->x, &a->y);
 }
 
 static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len) {
@@ -120,7 +119,9 @@ static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a
     size_t last_i = SIZE_MAX;
 
     for (i = 0; i < len; i++) {
-        if (!a[i].infinity) {
+        if (a[i].infinity) {
+            secp256k1_ge_set_infinity(&r[i]);
+        } else {
             /* Use destination's x coordinates as scratch space */
             if (last_i == SIZE_MAX) {
                 r[i].x = a[i].z;
@@ -148,7 +149,6 @@ static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a
     r[last_i].x = u;
 
     for (i = 0; i < len; i++) {
-        r[i].infinity = a[i].infinity;
         if (!a[i].infinity) {
             secp256k1_ge_set_gej_zinv(&r[i], &a[i], &r[i].x);
         }
@@ -311,7 +311,7 @@ static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, s
      *  point will be gibberish (z = 0 but infinity = 0).
      */
     if (a->infinity) {
-        r->infinity = 1;
+        secp256k1_gej_set_infinity(r);
         if (rzr != NULL) {
             secp256k1_fe_set_int(rzr, 1);
         }
index 1ac67086beccac5d2e28f74f747d37f483492dc9..5408c9de707107eef78d0e7a6707f30535333f7d 100644 (file)
@@ -7,8 +7,8 @@
 #ifndef SECP256K1_MODULE_ECDH_MAIN_H
 #define SECP256K1_MODULE_ECDH_MAIN_H
 
-#include "include/secp256k1_ecdh.h"
-#include "ecmult_const_impl.h"
+#include "../../../include/secp256k1_ecdh.h"
+#include "../../ecmult_const_impl.h"
 
 static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) {
     unsigned char version = (y32[31] & 0x01) | 0x02;
index 7390b227182fe33181d111b580be47100d5558eb..8607bbede73022a40db8f0c60227d61b4f447b90 100644 (file)
@@ -7,8 +7,8 @@
 #ifndef SECP256K1_MODULE_EXTRAKEYS_MAIN_H
 #define SECP256K1_MODULE_EXTRAKEYS_MAIN_H
 
-#include "include/secp256k1.h"
-#include "include/secp256k1_extrakeys.h"
+#include "../../../include/secp256k1.h"
+#include "../../../include/secp256k1_extrakeys.h"
 
 static SECP256K1_INLINE int secp256k1_xonly_pubkey_load(const secp256k1_context* ctx, secp256k1_ge *ge, const secp256k1_xonly_pubkey *pubkey) {
     return secp256k1_pubkey_load(ctx, ge, (const secp256k1_pubkey *) pubkey);
@@ -55,6 +55,32 @@ int secp256k1_xonly_pubkey_serialize(const secp256k1_context* ctx, unsigned char
     return 1;
 }
 
+int secp256k1_xonly_pubkey_cmp(const secp256k1_context* ctx, const secp256k1_xonly_pubkey* pk0, const secp256k1_xonly_pubkey* pk1) {
+    unsigned char out[2][32];
+    const secp256k1_xonly_pubkey* pk[2];
+    int i;
+
+    VERIFY_CHECK(ctx != NULL);
+    pk[0] = pk0; pk[1] = pk1;
+    for (i = 0; i < 2; i++) {
+        /* If the public key is NULL or invalid, xonly_pubkey_serialize will
+         * call the illegal_callback and return 0. In that case we will
+         * serialize the key as all zeros which is less than any valid public
+         * key. This results in consistent comparisons even if NULL or invalid
+         * pubkeys are involved and prevents edge cases such as sorting
+         * algorithms that use this function and do not terminate as a
+         * result. */
+        if (!secp256k1_xonly_pubkey_serialize(ctx, out[i], pk[i])) {
+            /* Note that xonly_pubkey_serialize should already set the output to
+             * zero in that case, but it's not guaranteed by the API, we can't
+             * test it and writing a VERIFY_CHECK is more complex than
+             * explicitly memsetting (again). */
+            memset(out[i], 0, sizeof(out[i]));
+        }
+    }
+    return secp256k1_memcmp_var(out[0], out[1], sizeof(out[1]));
+}
+
 /** Keeps a group element as is if it has an even Y and otherwise negates it.
  *  y_parity is set to 0 in the former case and to 1 in the latter case.
  *  Requires that the coordinates of r are normalized. */
index 0aca4fb72d781095c243401bda4a4e70c83afcfb..d4a2f5bdf4050e821218816585d4d0a3edfdaf3c 100644 (file)
@@ -8,7 +8,7 @@
 #define SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_H
 
 #include "src/modules/extrakeys/main_impl.h"
-#include "include/secp256k1_extrakeys.h"
+#include "../../../include/secp256k1_extrakeys.h"
 
 static void test_exhaustive_extrakeys(const secp256k1_context *ctx, const secp256k1_ge* group) {
     secp256k1_keypair keypair[EXHAUSTIVE_TEST_ORDER - 1];
index 9473a7dd4852e66f2ad7b30adbc10b41fabb4bb1..4a5952714c41c5147b9ccf48914f18d196c51531 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef SECP256K1_MODULE_EXTRAKEYS_TESTS_H
 #define SECP256K1_MODULE_EXTRAKEYS_TESTS_H
 
-#include "secp256k1_extrakeys.h"
+#include "../../../include/secp256k1_extrakeys.h"
 
 static secp256k1_context* api_test_context(int flags, int *ecount) {
     secp256k1_context *ctx0 = secp256k1_context_create(flags);
@@ -137,6 +137,43 @@ void test_xonly_pubkey(void) {
     secp256k1_context_destroy(verify);
 }
 
+void test_xonly_pubkey_comparison(void) {
+    unsigned char pk1_ser[32] = {
+        0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11,
+        0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23
+    };
+    const unsigned char pk2_ser[32] = {
+        0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d,
+        0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c
+    };
+    secp256k1_xonly_pubkey pk1;
+    secp256k1_xonly_pubkey pk2;
+    int ecount = 0;
+    secp256k1_context *none = api_test_context(SECP256K1_CONTEXT_NONE, &ecount);
+
+    CHECK(secp256k1_xonly_pubkey_parse(none, &pk1, pk1_ser) == 1);
+    CHECK(secp256k1_xonly_pubkey_parse(none, &pk2, pk2_ser) == 1);
+
+    CHECK(secp256k1_xonly_pubkey_cmp(none, NULL, &pk2) < 0);
+    CHECK(ecount == 1);
+    CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, NULL) > 0);
+    CHECK(ecount == 2);
+    CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk2) < 0);
+    CHECK(secp256k1_xonly_pubkey_cmp(none, &pk2, &pk1) > 0);
+    CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk1) == 0);
+    CHECK(secp256k1_xonly_pubkey_cmp(none, &pk2, &pk2) == 0);
+    CHECK(ecount == 2);
+    memset(&pk1, 0, sizeof(pk1)); /* illegal pubkey */
+    CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk2) < 0);
+    CHECK(ecount == 3);
+    CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk1) == 0);
+    CHECK(ecount == 5);
+    CHECK(secp256k1_xonly_pubkey_cmp(none, &pk2, &pk1) > 0);
+    CHECK(ecount == 6);
+
+    secp256k1_context_destroy(none);
+}
+
 void test_xonly_pubkey_tweak(void) {
     unsigned char zeros64[64] = { 0 };
     unsigned char overflows[32];
@@ -540,6 +577,7 @@ void run_extrakeys_tests(void) {
     test_xonly_pubkey_tweak();
     test_xonly_pubkey_tweak_check();
     test_xonly_pubkey_tweak_recursive();
+    test_xonly_pubkey_comparison();
 
     /* keypair tests */
     test_keypair();
index 7a440a729bf9644162e94651e6c222972dc30ec1..9e19f2a2dc9c880fd80c48108d46ee4ac5f9a618 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef SECP256K1_MODULE_RECOVERY_MAIN_H
 #define SECP256K1_MODULE_RECOVERY_MAIN_H
 
-#include "include/secp256k1_recovery.h"
+#include "../../../include/secp256k1_recovery.h"
 
 static void secp256k1_ecdsa_recoverable_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const secp256k1_ecdsa_recoverable_signature* sig) {
     (void)ctx;
index 0ba9409c691d0f251a55bbc699ac745712004edd..590a972ed3f74a9e24978ee373895bab5dad8128 100644 (file)
@@ -8,7 +8,7 @@
 #define SECP256K1_MODULE_RECOVERY_EXHAUSTIVE_TESTS_H
 
 #include "src/modules/recovery/main_impl.h"
-#include "include/secp256k1_recovery.h"
+#include "../../../include/secp256k1_recovery.h"
 
 void test_exhaustive_recovery_sign(const secp256k1_context *ctx, const secp256k1_ge *group) {
     int i, j, k;
index 22e1b33a5a48e63b0c701f243802d7d32e5b6dda..af503bf5ebed1ff9170f345132674fc99cc37b2e 100644 (file)
@@ -7,9 +7,9 @@
 #ifndef SECP256K1_MODULE_SCHNORRSIG_MAIN_H
 #define SECP256K1_MODULE_SCHNORRSIG_MAIN_H
 
-#include "include/secp256k1.h"
-#include "include/secp256k1_schnorrsig.h"
-#include "hash.h"
+#include "../../../include/secp256k1.h"
+#include "../../../include/secp256k1_schnorrsig.h"
+#include "../../hash.h"
 
 /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
  * SHA256 to SHA256("BIP0340/nonce")||SHA256("BIP0340/nonce"). */
index b4a428729f9a0b823e5b005be7314521d601367c..affabd23a67e715066f7b3867af0549337446863 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_H
 #define SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_H
 
-#include "include/secp256k1_schnorrsig.h"
+#include "../../../include/secp256k1_schnorrsig.h"
 #include "src/modules/schnorrsig/main_impl.h"
 
 static const unsigned char invalid_pubkey_bytes[][32] = {
index 6f960cf6a86ae7fd8670bae6de3d32e1ebcd7dca..f4fa5b4d846db13d526201627e108e146ce1aadc 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef SECP256K1_MODULE_SCHNORRSIG_TESTS_H
 #define SECP256K1_MODULE_SCHNORRSIG_TESTS_H
 
-#include "secp256k1_schnorrsig.h"
+#include "../../../include/secp256k1_schnorrsig.h"
 
 /* Checks that a bit flip in the n_flip-th argument (that has n_bytes many
  * bytes) changes the hash function
index 8d2d08722fa3da3568cdd78ea2f35dab63c6e9e8..81b1d6eb249b09b978006c554d7faa62d7c5ed9b 100644 (file)
@@ -6,8 +6,8 @@
 
 #define SECP256K1_BUILD
 
-#include "include/secp256k1.h"
-#include "include/secp256k1_preallocated.h"
+#include "../include/secp256k1.h"
+#include "../include/secp256k1_preallocated.h"
 
 #include "assumptions.h"
 #include "util.h"
@@ -322,6 +322,32 @@ int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *o
     return ret;
 }
 
+int secp256k1_ec_pubkey_cmp(const secp256k1_context* ctx, const secp256k1_pubkey* pubkey0, const secp256k1_pubkey* pubkey1) {
+    unsigned char out[2][33];
+    const secp256k1_pubkey* pk[2];
+    int i;
+
+    VERIFY_CHECK(ctx != NULL);
+    pk[0] = pubkey0; pk[1] = pubkey1;
+    for (i = 0; i < 2; i++) {
+        size_t out_size = sizeof(out[i]);
+        /* If the public key is NULL or invalid, ec_pubkey_serialize will call
+         * the illegal_callback and return 0. In that case we will serialize the
+         * key as all zeros which is less than any valid public key. This
+         * results in consistent comparisons even if NULL or invalid pubkeys are
+         * involved and prevents edge cases such as sorting algorithms that use
+         * this function and do not terminate as a result. */
+        if (!secp256k1_ec_pubkey_serialize(ctx, out[i], &out_size, pk[i], SECP256K1_EC_COMPRESSED)) {
+            /* Note that ec_pubkey_serialize should already set the output to
+             * zero in that case, but it's not guaranteed by the API, we can't
+             * test it and writing a VERIFY_CHECK is more complex than
+             * explicitly memsetting (again). */
+            memset(out[i], 0, sizeof(out[i]));
+        }
+    }
+    return secp256k1_memcmp_var(out[0], out[1], sizeof(out[0]));
+}
+
 static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig) {
     (void)ctx;
     if (sizeof(secp256k1_scalar) == 32) {
index a146394305cb67f07faa998b17fb3ba095a3d372..9c2d6cbf89db103b9a8a655bdc81cd5b7509fd08 100644 (file)
@@ -15,8 +15,8 @@
 #include <time.h>
 
 #include "secp256k1.c"
-#include "include/secp256k1.h"
-#include "include/secp256k1_preallocated.h"
+#include "../include/secp256k1.h"
+#include "../include/secp256k1_preallocated.h"
 #include "testrand_impl.h"
 #include "util.h"
 
@@ -30,8 +30,8 @@ void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
 # endif
 #endif
 
-#include "contrib/lax_der_parsing.c"
-#include "contrib/lax_der_privatekey_parsing.c"
+#include "../contrib/lax_der_parsing.c"
+#include "../contrib/lax_der_privatekey_parsing.c"
 
 #include "modinv32_impl.h"
 #ifdef SECP256K1_WIDEMUL_INT128
@@ -3101,20 +3101,34 @@ void test_ge(void) {
 
     /* Test batch gej -> ge conversion with many infinities. */
     for (i = 0; i < 4 * runs + 1; i++) {
+        int odd;
         random_group_element_test(&ge[i]);
+        odd = secp256k1_fe_is_odd(&ge[i].x);
+        CHECK(odd == 0 || odd == 1);
         /* randomly set half the points to infinity */
-        if(secp256k1_fe_is_odd(&ge[i].x)) {
+        if (odd == i % 2) {
             secp256k1_ge_set_infinity(&ge[i]);
         }
         secp256k1_gej_set_ge(&gej[i], &ge[i]);
     }
-    /* batch invert */
+    /* batch convert */
     secp256k1_ge_set_all_gej_var(ge, gej, 4 * runs + 1);
     /* check result */
     for (i = 0; i < 4 * runs + 1; i++) {
         ge_equals_gej(&ge[i], &gej[i]);
     }
 
+    /* Test batch gej -> ge conversion with all infinities. */
+    for (i = 0; i < 4 * runs + 1; i++) {
+        secp256k1_gej_set_infinity(&gej[i]);
+    }
+    /* batch convert */
+    secp256k1_ge_set_all_gej_var(ge, gej, 4 * runs + 1);
+    /* check result */
+    for (i = 0; i < 4 * runs + 1; i++) {
+        CHECK(secp256k1_ge_is_infinity(&ge[i]));
+    }
+
     free(ge);
     free(gej);
 }
@@ -5434,6 +5448,55 @@ void test_random_pubkeys(void) {
     }
 }
 
+void run_pubkey_comparison(void) {
+    unsigned char pk1_ser[33] = {
+        0x02,
+        0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11,
+        0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23
+    };
+    const unsigned char pk2_ser[33] = {
+        0x02,
+        0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d,
+        0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c
+    };
+    secp256k1_pubkey pk1;
+    secp256k1_pubkey pk2;
+    int32_t ecount = 0;
+
+    CHECK(secp256k1_ec_pubkey_parse(ctx, &pk1, pk1_ser, sizeof(pk1_ser)) == 1);
+    CHECK(secp256k1_ec_pubkey_parse(ctx, &pk2, pk2_ser, sizeof(pk2_ser)) == 1);
+
+    secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount);
+    CHECK(secp256k1_ec_pubkey_cmp(ctx, NULL, &pk2) < 0);
+    CHECK(ecount == 1);
+    CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk1, NULL) > 0);
+    CHECK(ecount == 2);
+    CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk1, &pk2) < 0);
+    CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk2, &pk1) > 0);
+    CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk1, &pk1) == 0);
+    CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk2, &pk2) == 0);
+    CHECK(ecount == 2);
+    {
+        secp256k1_pubkey pk_tmp;
+        memset(&pk_tmp, 0, sizeof(pk_tmp)); /* illegal pubkey */
+        CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk_tmp, &pk2) < 0);
+        CHECK(ecount == 3);
+        CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk_tmp, &pk_tmp) == 0);
+        CHECK(ecount == 5);
+        CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk2, &pk_tmp) > 0);
+        CHECK(ecount == 6);
+    }
+
+    secp256k1_context_set_illegal_callback(ctx, NULL, NULL);
+
+    /* Make pk2 the same as pk1 but with 3 rather than 2. Note that in
+     * an uncompressed encoding, these would have the opposite ordering */
+    pk1_ser[0] = 3;
+    CHECK(secp256k1_ec_pubkey_parse(ctx, &pk2, pk1_ser, sizeof(pk1_ser)) == 1);
+    CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk1, &pk2) < 0);
+    CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk2, &pk1) > 0);
+}
+
 void run_random_pubkeys(void) {
     int i;
     for (i = 0; i < 10*count; i++) {
@@ -6485,6 +6548,7 @@ int main(int argc, char **argv) {
 #endif
 
     /* ecdsa tests */
+    run_pubkey_comparison();
     run_random_pubkeys();
     run_ecdsa_der_parse();
     run_ecdsa_sign_verify();
index a8074d44fc2e5a5df0043360b7974f518380c001..b7c7828995f2e0123c09384d2d793f4e8869b15d 100644 (file)
@@ -10,7 +10,6 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-
 #include <time.h>
 
 #undef USE_ECMULT_STATIC_PRECOMPUTATION
@@ -21,7 +20,7 @@
 #endif
 
 #include "secp256k1.c"
-#include "include/secp256k1.h"
+#include "../include/secp256k1.h"
 #include "assumptions.h"
 #include "group.h"
 #include "testrand_impl.h"
index cfca5a196e0cad9718451945d4169852f9956d0a..4ac0f011bd3adbc6c2e45bc2eab2a57adcf92371 100644 (file)
@@ -7,24 +7,24 @@
 #include <valgrind/memcheck.h>
 #include <stdio.h>
 
-#include "include/secp256k1.h"
+#include "../include/secp256k1.h"
 #include "assumptions.h"
 #include "util.h"
 
 #ifdef ENABLE_MODULE_ECDH
-# include "include/secp256k1_ecdh.h"
+# include "../include/secp256k1_ecdh.h"
 #endif
 
 #ifdef ENABLE_MODULE_RECOVERY
-# include "include/secp256k1_recovery.h"
+# include "../include/secp256k1_recovery.h"
 #endif
 
 #ifdef ENABLE_MODULE_EXTRAKEYS
-# include "include/secp256k1_extrakeys.h"
+# include "../include/secp256k1_extrakeys.h"
 #endif
 
 #ifdef ENABLE_MODULE_SCHNORRSIG
-#include "include/secp256k1_schnorrsig.h"
+#include "../include/secp256k1_schnorrsig.h"
 #endif
 
 void run_tests(secp256k1_context *ctx, unsigned char *key);
This page took 0.064193 seconds and 4 git commands to generate.