]>
Commit | Line | Data |
---|---|---|
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_MAIN_ | |
8 | #define _SECP256K1_MODULE_EXTRAKEYS_MAIN_ | |
9 | ||
10 | #include "include/secp256k1.h" | |
11 | #include "include/secp256k1_extrakeys.h" | |
12 | ||
4cd2ee47 JN |
13 | static SECP256K1_INLINE int secp256k1_xonly_pubkey_load(const secp256k1_context* ctx, secp256k1_ge *ge, const secp256k1_xonly_pubkey *pubkey) { |
14 | return secp256k1_pubkey_load(ctx, ge, (const secp256k1_pubkey *) pubkey); | |
15 | } | |
16 | ||
17 | static SECP256K1_INLINE void secp256k1_xonly_pubkey_save(secp256k1_xonly_pubkey *pubkey, secp256k1_ge *ge) { | |
18 | secp256k1_pubkey_save((secp256k1_pubkey *) pubkey, ge); | |
19 | } | |
20 | ||
21 | int secp256k1_xonly_pubkey_parse(const secp256k1_context* ctx, secp256k1_xonly_pubkey *pubkey, const unsigned char *input32) { | |
22 | secp256k1_ge pk; | |
23 | secp256k1_fe x; | |
24 | ||
25 | VERIFY_CHECK(ctx != NULL); | |
26 | ARG_CHECK(pubkey != NULL); | |
27 | memset(pubkey, 0, sizeof(*pubkey)); | |
28 | ARG_CHECK(input32 != NULL); | |
29 | ||
30 | if (!secp256k1_fe_set_b32(&x, input32)) { | |
31 | return 0; | |
32 | } | |
33 | if (!secp256k1_ge_set_xo_var(&pk, &x, 0)) { | |
34 | return 0; | |
35 | } | |
36 | secp256k1_xonly_pubkey_save(pubkey, &pk); | |
37 | return 1; | |
38 | } | |
39 | ||
40 | int secp256k1_xonly_pubkey_serialize(const secp256k1_context* ctx, unsigned char *output32, const secp256k1_xonly_pubkey *pubkey) { | |
41 | secp256k1_ge pk; | |
42 | ||
43 | VERIFY_CHECK(ctx != NULL); | |
44 | ARG_CHECK(output32 != NULL); | |
45 | memset(output32, 0, 32); | |
46 | ARG_CHECK(pubkey != NULL); | |
47 | ||
48 | if (!secp256k1_xonly_pubkey_load(ctx, &pk, pubkey)) { | |
49 | return 0; | |
50 | } | |
51 | secp256k1_fe_get_b32(output32, &pk.x); | |
52 | return 1; | |
53 | } | |
54 | ||
55 | /** Keeps a group element as is if it has an even Y and otherwise negates it. | |
56 | * y_parity is set to 0 in the former case and to 1 in the latter case. | |
57 | * Requires that the coordinates of r are normalized. */ | |
58 | static int secp256k1_extrakeys_ge_even_y(secp256k1_ge *r) { | |
59 | int y_parity = 0; | |
60 | VERIFY_CHECK(!secp256k1_ge_is_infinity(r)); | |
61 | ||
62 | if (secp256k1_fe_is_odd(&r->y)) { | |
63 | secp256k1_fe_negate(&r->y, &r->y, 1); | |
64 | y_parity = 1; | |
65 | } | |
66 | return y_parity; | |
67 | } | |
68 | ||
69 | int secp256k1_xonly_pubkey_from_pubkey(const secp256k1_context* ctx, secp256k1_xonly_pubkey *xonly_pubkey, int *pk_parity, const secp256k1_pubkey *pubkey) { | |
70 | secp256k1_ge pk; | |
71 | int tmp; | |
72 | ||
73 | VERIFY_CHECK(ctx != NULL); | |
74 | ARG_CHECK(xonly_pubkey != NULL); | |
75 | ARG_CHECK(pubkey != NULL); | |
76 | ||
77 | if (!secp256k1_pubkey_load(ctx, &pk, pubkey)) { | |
78 | return 0; | |
79 | } | |
80 | tmp = secp256k1_extrakeys_ge_even_y(&pk); | |
81 | if (pk_parity != NULL) { | |
82 | *pk_parity = tmp; | |
83 | } | |
84 | secp256k1_xonly_pubkey_save(xonly_pubkey, &pk); | |
85 | return 1; | |
86 | } | |
87 | ||
47e6618e | 88 | #endif |