1 /**********************************************************************
2 * Copyright (c) 2013, 2014 Pieter Wuille *
3 * Distributed under the MIT software license, see the accompanying *
4 * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
5 **********************************************************************/
7 #ifndef SECP256K1_ECKEY_IMPL_H
8 #define SECP256K1_ECKEY_IMPL_H
15 #include "ecmult_gen.h"
17 static int secp256k1_eckey_pubkey_parse(secp256k1_ge
*elem
, const unsigned char *pub
, size_t size
) {
18 if (size
== 33 && (pub
[0] == SECP256K1_TAG_PUBKEY_EVEN
|| pub
[0] == SECP256K1_TAG_PUBKEY_ODD
)) {
20 return secp256k1_fe_set_b32(&x
, pub
+1) && secp256k1_ge_set_xo_var(elem
, &x
, pub
[0] == SECP256K1_TAG_PUBKEY_ODD
);
21 } else if (size
== 65 && (pub
[0] == 0x04 || pub
[0] == 0x06 || pub
[0] == 0x07)) {
23 if (!secp256k1_fe_set_b32(&x
, pub
+1) || !secp256k1_fe_set_b32(&y
, pub
+33)) {
26 secp256k1_ge_set_xy(elem
, &x
, &y
);
27 if ((pub
[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN
|| pub
[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD
) &&
28 secp256k1_fe_is_odd(&y
) != (pub
[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD
)) {
31 return secp256k1_ge_is_valid_var(elem
);
37 static int secp256k1_eckey_pubkey_serialize(secp256k1_ge
*elem
, unsigned char *pub
, size_t *size
, int compressed
) {
38 if (secp256k1_ge_is_infinity(elem
)) {
41 secp256k1_fe_normalize_var(&elem
->x
);
42 secp256k1_fe_normalize_var(&elem
->y
);
43 secp256k1_fe_get_b32(&pub
[1], &elem
->x
);
46 pub
[0] = secp256k1_fe_is_odd(&elem
->y
) ? SECP256K1_TAG_PUBKEY_ODD
: SECP256K1_TAG_PUBKEY_EVEN
;
49 pub
[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED
;
50 secp256k1_fe_get_b32(&pub
[33], &elem
->y
);
55 static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar
*key
, const secp256k1_scalar
*tweak
) {
56 secp256k1_scalar_add(key
, key
, tweak
);
57 if (secp256k1_scalar_is_zero(key
)) {
63 static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context
*ctx
, secp256k1_ge
*key
, const secp256k1_scalar
*tweak
) {
66 secp256k1_gej_set_ge(&pt
, key
);
67 secp256k1_scalar_set_int(&one
, 1);
68 secp256k1_ecmult(ctx
, &pt
, &pt
, &one
, tweak
);
70 if (secp256k1_gej_is_infinity(&pt
)) {
73 secp256k1_ge_set_gej(key
, &pt
);
77 static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar
*key
, const secp256k1_scalar
*tweak
) {
78 if (secp256k1_scalar_is_zero(tweak
)) {
82 secp256k1_scalar_mul(key
, key
, tweak
);
86 static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context
*ctx
, secp256k1_ge
*key
, const secp256k1_scalar
*tweak
) {
87 secp256k1_scalar zero
;
89 if (secp256k1_scalar_is_zero(tweak
)) {
93 secp256k1_scalar_set_int(&zero
, 0);
94 secp256k1_gej_set_ge(&pt
, key
);
95 secp256k1_ecmult(ctx
, &pt
, &pt
, tweak
, &zero
);
96 secp256k1_ge_set_gej(key
, &pt
);
100 #endif /* SECP256K1_ECKEY_IMPL_H */