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
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 $@
***********************************************************************/
#include <string.h>
-#include <secp256k1.h>
#include "lax_der_parsing.h"
#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" {
***********************************************************************/
#include <string.h>
-#include <secp256k1.h>
#include "lax_der_privatekey_parsing.h"
#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" {
#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.
* 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];
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.
* 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];
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
#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"
#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"
#include <stdio.h>
#include "secp256k1.c"
+#include "../include/secp256k1.h"
-#include "include/secp256k1.h"
#include "assumptions.h"
#include "util.h"
#include "hash_impl.h"
* 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"
#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"
* 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"
#include <stdio.h>
#include <string.h>
-#include "include/secp256k1.h"
+#include "../include/secp256k1.h"
#include "util.h"
#include "bench.h"
/* 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"
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);
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) {
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;
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);
}
* 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);
}
#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;
#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);
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. */
#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];
#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);
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];
test_xonly_pubkey_tweak();
test_xonly_pubkey_tweak_check();
test_xonly_pubkey_tweak_recursive();
+ test_xonly_pubkey_comparison();
/* keypair tests */
test_keypair();
#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;
#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;
#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"). */
#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] = {
#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
#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"
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) {
#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"
# 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
/* 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);
}
}
}
+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++) {
#endif
/* ecdsa tests */
+ run_pubkey_comparison();
run_random_pubkeys();
run_ecdsa_der_parse();
run_ecdsa_sign_verify();
#include <stdio.h>
#include <stdlib.h>
-
#include <time.h>
#undef USE_ECMULT_STATIC_PRECOMPUTATION
#endif
#include "secp256k1.c"
-#include "include/secp256k1.h"
+#include "../include/secp256k1.h"
#include "assumptions.h"
#include "group.h"
#include "testrand_impl.h"
#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);