]> Git Repo - secp256k1.git/blame - src/modules/extrakeys/tests_impl.h
extrakeys: Add xonly_pubkey with serialize, parse and from_pubkey
[secp256k1.git] / src / modules / extrakeys / tests_impl.h
CommitLineData
47e6618e
JN
1/**********************************************************************
2 * Copyright (c) 2020 Jonas Nick *
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_EXTRAKEYS_TESTS_
8#define _SECP256K1_MODULE_EXTRAKEYS_TESTS_
9
10#include "secp256k1_extrakeys.h"
11
4cd2ee47
JN
12static secp256k1_context* api_test_context(int flags, int *ecount) {
13 secp256k1_context *ctx0 = secp256k1_context_create(flags);
14 secp256k1_context_set_error_callback(ctx0, counting_illegal_callback_fn, ecount);
15 secp256k1_context_set_illegal_callback(ctx0, counting_illegal_callback_fn, ecount);
16 return ctx0;
17}
18
19void test_xonly_pubkey(void) {
20 secp256k1_pubkey pk;
21 secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
22 secp256k1_ge pk1;
23 secp256k1_ge pk2;
24 secp256k1_fe y;
25 unsigned char sk[32];
26 unsigned char xy_sk[32];
27 unsigned char buf32[32];
28 unsigned char ones32[32];
29 unsigned char zeros64[64] = { 0 };
30 int pk_parity;
31 int i;
32
33 int ecount;
34 secp256k1_context *none = api_test_context(SECP256K1_CONTEXT_NONE, &ecount);
35 secp256k1_context *sign = api_test_context(SECP256K1_CONTEXT_SIGN, &ecount);
36 secp256k1_context *verify = api_test_context(SECP256K1_CONTEXT_VERIFY, &ecount);
37
38 secp256k1_rand256(sk);
39 memset(ones32, 0xFF, 32);
40 secp256k1_rand256(xy_sk);
41 CHECK(secp256k1_ec_pubkey_create(sign, &pk, sk) == 1);
42 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
43
44 /* Test xonly_pubkey_from_pubkey */
45 ecount = 0;
46 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
47 CHECK(secp256k1_xonly_pubkey_from_pubkey(sign, &xonly_pk, &pk_parity, &pk) == 1);
48 CHECK(secp256k1_xonly_pubkey_from_pubkey(verify, &xonly_pk, &pk_parity, &pk) == 1);
49 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, NULL, &pk_parity, &pk) == 0);
50 CHECK(ecount == 1);
51 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, NULL, &pk) == 1);
52 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, NULL) == 0);
53 CHECK(ecount == 2);
54 memset(&pk, 0, sizeof(pk));
55 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 0);
56 CHECK(ecount == 3);
57
58 /* Choose a secret key such that the resulting pubkey and xonly_pubkey match. */
59 memset(sk, 0, sizeof(sk));
60 sk[0] = 1;
61 CHECK(secp256k1_ec_pubkey_create(ctx, &pk, sk) == 1);
62 CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk) == 1);
63 CHECK(memcmp(&pk, &xonly_pk, sizeof(pk)) == 0);
64 CHECK(pk_parity == 0);
65
66 /* Choose a secret key such that pubkey and xonly_pubkey are each others
67 * negation. */
68 sk[0] = 2;
69 CHECK(secp256k1_ec_pubkey_create(ctx, &pk, sk) == 1);
70 CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk) == 1);
71 CHECK(memcmp(&xonly_pk, &pk, sizeof(xonly_pk)) != 0);
72 CHECK(pk_parity == 1);
73 secp256k1_pubkey_load(ctx, &pk1, &pk);
74 secp256k1_pubkey_load(ctx, &pk2, (secp256k1_pubkey *) &xonly_pk);
75 CHECK(secp256k1_fe_equal(&pk1.x, &pk2.x) == 1);
76 secp256k1_fe_negate(&y, &pk2.y, 1);
77 CHECK(secp256k1_fe_equal(&pk1.y, &y) == 1);
78
79 /* Test xonly_pubkey_serialize and xonly_pubkey_parse */
80 ecount = 0;
81 CHECK(secp256k1_xonly_pubkey_serialize(none, NULL, &xonly_pk) == 0);
82 CHECK(ecount == 1);
83 CHECK(secp256k1_xonly_pubkey_serialize(none, buf32, NULL) == 0);
84 CHECK(memcmp(buf32, zeros64, 32) == 0);
85 CHECK(ecount == 2);
86 {
87 /* A pubkey filled with 0s will fail to serialize due to pubkey_load
88 * special casing. */
89 secp256k1_xonly_pubkey pk_tmp;
90 memset(&pk_tmp, 0, sizeof(pk_tmp));
91 CHECK(secp256k1_xonly_pubkey_serialize(none, buf32, &pk_tmp) == 0);
92 }
93 /* pubkey_load called illegal callback */
94 CHECK(ecount == 3);
95
96 CHECK(secp256k1_xonly_pubkey_serialize(none, buf32, &xonly_pk) == 1);
97 ecount = 0;
98 CHECK(secp256k1_xonly_pubkey_parse(none, NULL, buf32) == 0);
99 CHECK(ecount == 1);
100 CHECK(secp256k1_xonly_pubkey_parse(none, &xonly_pk, NULL) == 0);
101 CHECK(ecount == 2);
102
103 /* Serialization and parse roundtrip */
104 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, NULL, &pk) == 1);
105 CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf32, &xonly_pk) == 1);
106 CHECK(secp256k1_xonly_pubkey_parse(ctx, &xonly_pk_tmp, buf32) == 1);
107 CHECK(memcmp(&xonly_pk, &xonly_pk_tmp, sizeof(xonly_pk)) == 0);
108
109 /* Test parsing invalid field elements */
110 memset(&xonly_pk, 1, sizeof(xonly_pk));
111 /* Overflowing field element */
112 CHECK(secp256k1_xonly_pubkey_parse(none, &xonly_pk, ones32) == 0);
113 CHECK(memcmp(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
114 memset(&xonly_pk, 1, sizeof(xonly_pk));
115 /* There's no point with x-coordinate 0 on secp256k1 */
116 CHECK(secp256k1_xonly_pubkey_parse(none, &xonly_pk, zeros64) == 0);
117 CHECK(memcmp(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
118 /* If a random 32-byte string can not be parsed with ec_pubkey_parse
119 * (because interpreted as X coordinate it does not correspond to a point on
120 * the curve) then xonly_pubkey_parse should fail as well. */
121 for (i = 0; i < count; i++) {
122 unsigned char rand33[33];
123 secp256k1_rand256(&rand33[1]);
124 rand33[0] = SECP256K1_TAG_PUBKEY_EVEN;
125 if (!secp256k1_ec_pubkey_parse(ctx, &pk, rand33, 33)) {
126 memset(&xonly_pk, 1, sizeof(xonly_pk));
127 CHECK(secp256k1_xonly_pubkey_parse(ctx, &xonly_pk, &rand33[1]) == 0);
128 CHECK(memcmp(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
129 } else {
130 CHECK(secp256k1_xonly_pubkey_parse(ctx, &xonly_pk, &rand33[1]) == 1);
131 }
132 }
133 CHECK(ecount == 2);
134
135 secp256k1_context_destroy(none);
136 secp256k1_context_destroy(sign);
137 secp256k1_context_destroy(verify);
138}
139
47e6618e 140void run_extrakeys_tests(void) {
4cd2ee47
JN
141 /* xonly key test cases */
142 test_xonly_pubkey();
47e6618e
JN
143}
144
145#endif
This page took 0.035687 seconds and 4 git commands to generate.