main_impl.h (11753B)
1 /*********************************************************************** 2 * Copyright (c) 2020 Jonas Nick * 3 * Distributed under the MIT software license, see the accompanying * 4 * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 ***********************************************************************/ 6 7 #ifndef SECP256K1_MODULE_EXTRAKEYS_MAIN_H 8 #define SECP256K1_MODULE_EXTRAKEYS_MAIN_H 9 10 #include "../../../include/secp256k1.h" 11 #include "../../../include/secp256k1_extrakeys.h" 12 #include "../../util.h" 13 14 static SECP256K1_INLINE int haskellsecp256k1_v0_1_0_xonly_pubkey_load(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_ge *ge, const haskellsecp256k1_v0_1_0_xonly_pubkey *pubkey) { 15 return haskellsecp256k1_v0_1_0_pubkey_load(ctx, ge, (const haskellsecp256k1_v0_1_0_pubkey *) pubkey); 16 } 17 18 static SECP256K1_INLINE void haskellsecp256k1_v0_1_0_xonly_pubkey_save(haskellsecp256k1_v0_1_0_xonly_pubkey *pubkey, haskellsecp256k1_v0_1_0_ge *ge) { 19 haskellsecp256k1_v0_1_0_pubkey_save((haskellsecp256k1_v0_1_0_pubkey *) pubkey, ge); 20 } 21 22 int haskellsecp256k1_v0_1_0_xonly_pubkey_parse(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_xonly_pubkey *pubkey, const unsigned char *input32) { 23 haskellsecp256k1_v0_1_0_ge pk; 24 haskellsecp256k1_v0_1_0_fe x; 25 26 VERIFY_CHECK(ctx != NULL); 27 ARG_CHECK(pubkey != NULL); 28 memset(pubkey, 0, sizeof(*pubkey)); 29 ARG_CHECK(input32 != NULL); 30 31 if (!haskellsecp256k1_v0_1_0_fe_set_b32_limit(&x, input32)) { 32 return 0; 33 } 34 if (!haskellsecp256k1_v0_1_0_ge_set_xo_var(&pk, &x, 0)) { 35 return 0; 36 } 37 if (!haskellsecp256k1_v0_1_0_ge_is_in_correct_subgroup(&pk)) { 38 return 0; 39 } 40 haskellsecp256k1_v0_1_0_xonly_pubkey_save(pubkey, &pk); 41 return 1; 42 } 43 44 int haskellsecp256k1_v0_1_0_xonly_pubkey_serialize(const haskellsecp256k1_v0_1_0_context* ctx, unsigned char *output32, const haskellsecp256k1_v0_1_0_xonly_pubkey *pubkey) { 45 haskellsecp256k1_v0_1_0_ge pk; 46 47 VERIFY_CHECK(ctx != NULL); 48 ARG_CHECK(output32 != NULL); 49 memset(output32, 0, 32); 50 ARG_CHECK(pubkey != NULL); 51 52 if (!haskellsecp256k1_v0_1_0_xonly_pubkey_load(ctx, &pk, pubkey)) { 53 return 0; 54 } 55 haskellsecp256k1_v0_1_0_fe_get_b32(output32, &pk.x); 56 return 1; 57 } 58 59 int haskellsecp256k1_v0_1_0_xonly_pubkey_cmp(const haskellsecp256k1_v0_1_0_context* ctx, const haskellsecp256k1_v0_1_0_xonly_pubkey* pk0, const haskellsecp256k1_v0_1_0_xonly_pubkey* pk1) { 60 unsigned char out[2][32]; 61 const haskellsecp256k1_v0_1_0_xonly_pubkey* pk[2]; 62 int i; 63 64 VERIFY_CHECK(ctx != NULL); 65 pk[0] = pk0; pk[1] = pk1; 66 for (i = 0; i < 2; i++) { 67 /* If the public key is NULL or invalid, xonly_pubkey_serialize will 68 * call the illegal_callback and return 0. In that case we will 69 * serialize the key as all zeros which is less than any valid public 70 * key. This results in consistent comparisons even if NULL or invalid 71 * pubkeys are involved and prevents edge cases such as sorting 72 * algorithms that use this function and do not terminate as a 73 * result. */ 74 if (!haskellsecp256k1_v0_1_0_xonly_pubkey_serialize(ctx, out[i], pk[i])) { 75 /* Note that xonly_pubkey_serialize should already set the output to 76 * zero in that case, but it's not guaranteed by the API, we can't 77 * test it and writing a VERIFY_CHECK is more complex than 78 * explicitly memsetting (again). */ 79 memset(out[i], 0, sizeof(out[i])); 80 } 81 } 82 return haskellsecp256k1_v0_1_0_memcmp_var(out[0], out[1], sizeof(out[1])); 83 } 84 85 /** Keeps a group element as is if it has an even Y and otherwise negates it. 86 * y_parity is set to 0 in the former case and to 1 in the latter case. 87 * Requires that the coordinates of r are normalized. */ 88 static int haskellsecp256k1_v0_1_0_extrakeys_ge_even_y(haskellsecp256k1_v0_1_0_ge *r) { 89 int y_parity = 0; 90 VERIFY_CHECK(!haskellsecp256k1_v0_1_0_ge_is_infinity(r)); 91 92 if (haskellsecp256k1_v0_1_0_fe_is_odd(&r->y)) { 93 haskellsecp256k1_v0_1_0_fe_negate(&r->y, &r->y, 1); 94 y_parity = 1; 95 } 96 return y_parity; 97 } 98 99 int haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_xonly_pubkey *xonly_pubkey, int *pk_parity, const haskellsecp256k1_v0_1_0_pubkey *pubkey) { 100 haskellsecp256k1_v0_1_0_ge pk; 101 int tmp; 102 103 VERIFY_CHECK(ctx != NULL); 104 ARG_CHECK(xonly_pubkey != NULL); 105 ARG_CHECK(pubkey != NULL); 106 107 if (!haskellsecp256k1_v0_1_0_pubkey_load(ctx, &pk, pubkey)) { 108 return 0; 109 } 110 tmp = haskellsecp256k1_v0_1_0_extrakeys_ge_even_y(&pk); 111 if (pk_parity != NULL) { 112 *pk_parity = tmp; 113 } 114 haskellsecp256k1_v0_1_0_xonly_pubkey_save(xonly_pubkey, &pk); 115 return 1; 116 } 117 118 int haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_pubkey *output_pubkey, const haskellsecp256k1_v0_1_0_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) { 119 haskellsecp256k1_v0_1_0_ge pk; 120 121 VERIFY_CHECK(ctx != NULL); 122 ARG_CHECK(output_pubkey != NULL); 123 memset(output_pubkey, 0, sizeof(*output_pubkey)); 124 ARG_CHECK(internal_pubkey != NULL); 125 ARG_CHECK(tweak32 != NULL); 126 127 if (!haskellsecp256k1_v0_1_0_xonly_pubkey_load(ctx, &pk, internal_pubkey) 128 || !haskellsecp256k1_v0_1_0_ec_pubkey_tweak_add_helper(&pk, tweak32)) { 129 return 0; 130 } 131 haskellsecp256k1_v0_1_0_pubkey_save(output_pubkey, &pk); 132 return 1; 133 } 134 135 int haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check(const haskellsecp256k1_v0_1_0_context* ctx, const unsigned char *tweaked_pubkey32, int tweaked_pk_parity, const haskellsecp256k1_v0_1_0_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) { 136 haskellsecp256k1_v0_1_0_ge pk; 137 unsigned char pk_expected32[32]; 138 139 VERIFY_CHECK(ctx != NULL); 140 ARG_CHECK(internal_pubkey != NULL); 141 ARG_CHECK(tweaked_pubkey32 != NULL); 142 ARG_CHECK(tweak32 != NULL); 143 144 if (!haskellsecp256k1_v0_1_0_xonly_pubkey_load(ctx, &pk, internal_pubkey) 145 || !haskellsecp256k1_v0_1_0_ec_pubkey_tweak_add_helper(&pk, tweak32)) { 146 return 0; 147 } 148 haskellsecp256k1_v0_1_0_fe_normalize_var(&pk.x); 149 haskellsecp256k1_v0_1_0_fe_normalize_var(&pk.y); 150 haskellsecp256k1_v0_1_0_fe_get_b32(pk_expected32, &pk.x); 151 152 return haskellsecp256k1_v0_1_0_memcmp_var(&pk_expected32, tweaked_pubkey32, 32) == 0 153 && haskellsecp256k1_v0_1_0_fe_is_odd(&pk.y) == tweaked_pk_parity; 154 } 155 156 static void haskellsecp256k1_v0_1_0_keypair_save(haskellsecp256k1_v0_1_0_keypair *keypair, const haskellsecp256k1_v0_1_0_scalar *sk, haskellsecp256k1_v0_1_0_ge *pk) { 157 haskellsecp256k1_v0_1_0_scalar_get_b32(&keypair->data[0], sk); 158 haskellsecp256k1_v0_1_0_pubkey_save((haskellsecp256k1_v0_1_0_pubkey *)&keypair->data[32], pk); 159 } 160 161 162 static int haskellsecp256k1_v0_1_0_keypair_seckey_load(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_scalar *sk, const haskellsecp256k1_v0_1_0_keypair *keypair) { 163 int ret; 164 165 ret = haskellsecp256k1_v0_1_0_scalar_set_b32_seckey(sk, &keypair->data[0]); 166 /* We can declassify ret here because sk is only zero if a keypair function 167 * failed (which zeroes the keypair) and its return value is ignored. */ 168 haskellsecp256k1_v0_1_0_declassify(ctx, &ret, sizeof(ret)); 169 ARG_CHECK(ret); 170 return ret; 171 } 172 173 /* Load a keypair into pk and sk (if non-NULL). This function declassifies pk 174 * and ARG_CHECKs that the keypair is not invalid. It always initializes sk and 175 * pk with dummy values. */ 176 static int haskellsecp256k1_v0_1_0_keypair_load(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_scalar *sk, haskellsecp256k1_v0_1_0_ge *pk, const haskellsecp256k1_v0_1_0_keypair *keypair) { 177 int ret; 178 const haskellsecp256k1_v0_1_0_pubkey *pubkey = (const haskellsecp256k1_v0_1_0_pubkey *)&keypair->data[32]; 179 180 /* Need to declassify the pubkey because pubkey_load ARG_CHECKs if it's 181 * invalid. */ 182 haskellsecp256k1_v0_1_0_declassify(ctx, pubkey, sizeof(*pubkey)); 183 ret = haskellsecp256k1_v0_1_0_pubkey_load(ctx, pk, pubkey); 184 if (sk != NULL) { 185 ret = ret && haskellsecp256k1_v0_1_0_keypair_seckey_load(ctx, sk, keypair); 186 } 187 if (!ret) { 188 *pk = haskellsecp256k1_v0_1_0_ge_const_g; 189 if (sk != NULL) { 190 *sk = haskellsecp256k1_v0_1_0_scalar_one; 191 } 192 } 193 return ret; 194 } 195 196 int haskellsecp256k1_v0_1_0_keypair_create(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_keypair *keypair, const unsigned char *seckey32) { 197 haskellsecp256k1_v0_1_0_scalar sk; 198 haskellsecp256k1_v0_1_0_ge pk; 199 int ret = 0; 200 VERIFY_CHECK(ctx != NULL); 201 ARG_CHECK(keypair != NULL); 202 memset(keypair, 0, sizeof(*keypair)); 203 ARG_CHECK(haskellsecp256k1_v0_1_0_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); 204 ARG_CHECK(seckey32 != NULL); 205 206 ret = haskellsecp256k1_v0_1_0_ec_pubkey_create_helper(&ctx->ecmult_gen_ctx, &sk, &pk, seckey32); 207 haskellsecp256k1_v0_1_0_keypair_save(keypair, &sk, &pk); 208 haskellsecp256k1_v0_1_0_memczero(keypair, sizeof(*keypair), !ret); 209 210 haskellsecp256k1_v0_1_0_scalar_clear(&sk); 211 return ret; 212 } 213 214 int haskellsecp256k1_v0_1_0_keypair_sec(const haskellsecp256k1_v0_1_0_context* ctx, unsigned char *seckey, const haskellsecp256k1_v0_1_0_keypair *keypair) { 215 VERIFY_CHECK(ctx != NULL); 216 ARG_CHECK(seckey != NULL); 217 memset(seckey, 0, 32); 218 ARG_CHECK(keypair != NULL); 219 220 memcpy(seckey, &keypair->data[0], 32); 221 return 1; 222 } 223 224 int haskellsecp256k1_v0_1_0_keypair_pub(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_pubkey *pubkey, const haskellsecp256k1_v0_1_0_keypair *keypair) { 225 VERIFY_CHECK(ctx != NULL); 226 ARG_CHECK(pubkey != NULL); 227 memset(pubkey, 0, sizeof(*pubkey)); 228 ARG_CHECK(keypair != NULL); 229 230 memcpy(pubkey->data, &keypair->data[32], sizeof(*pubkey)); 231 return 1; 232 } 233 234 int haskellsecp256k1_v0_1_0_keypair_xonly_pub(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_xonly_pubkey *pubkey, int *pk_parity, const haskellsecp256k1_v0_1_0_keypair *keypair) { 235 haskellsecp256k1_v0_1_0_ge pk; 236 int tmp; 237 238 VERIFY_CHECK(ctx != NULL); 239 ARG_CHECK(pubkey != NULL); 240 memset(pubkey, 0, sizeof(*pubkey)); 241 ARG_CHECK(keypair != NULL); 242 243 if (!haskellsecp256k1_v0_1_0_keypair_load(ctx, NULL, &pk, keypair)) { 244 return 0; 245 } 246 tmp = haskellsecp256k1_v0_1_0_extrakeys_ge_even_y(&pk); 247 if (pk_parity != NULL) { 248 *pk_parity = tmp; 249 } 250 haskellsecp256k1_v0_1_0_xonly_pubkey_save(pubkey, &pk); 251 252 return 1; 253 } 254 255 int haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_keypair *keypair, const unsigned char *tweak32) { 256 haskellsecp256k1_v0_1_0_ge pk; 257 haskellsecp256k1_v0_1_0_scalar sk; 258 int y_parity; 259 int ret; 260 261 VERIFY_CHECK(ctx != NULL); 262 ARG_CHECK(keypair != NULL); 263 ARG_CHECK(tweak32 != NULL); 264 265 ret = haskellsecp256k1_v0_1_0_keypair_load(ctx, &sk, &pk, keypair); 266 memset(keypair, 0, sizeof(*keypair)); 267 268 y_parity = haskellsecp256k1_v0_1_0_extrakeys_ge_even_y(&pk); 269 if (y_parity == 1) { 270 haskellsecp256k1_v0_1_0_scalar_negate(&sk, &sk); 271 } 272 273 ret &= haskellsecp256k1_v0_1_0_ec_seckey_tweak_add_helper(&sk, tweak32); 274 ret &= haskellsecp256k1_v0_1_0_ec_pubkey_tweak_add_helper(&pk, tweak32); 275 276 haskellsecp256k1_v0_1_0_declassify(ctx, &ret, sizeof(ret)); 277 if (ret) { 278 haskellsecp256k1_v0_1_0_keypair_save(keypair, &sk, &pk); 279 } 280 281 haskellsecp256k1_v0_1_0_scalar_clear(&sk); 282 return ret; 283 } 284 285 #endif