]>
Commit | Line | Data |
---|---|---|
71712b27 GM |
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 | **********************************************************************/ | |
e2f71f1e | 6 | |
abe2d3e8 DR |
7 | #ifndef SECP256K1_ECKEY_IMPL_H |
8 | #define SECP256K1_ECKEY_IMPL_H | |
e2f71f1e PW |
9 | |
10 | #include "eckey.h" | |
11 | ||
f24041d6 | 12 | #include "scalar.h" |
e2f71f1e PW |
13 | #include "field.h" |
14 | #include "group.h" | |
15 | #include "ecmult_gen.h" | |
16 | ||
dd891e0e | 17 | static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) { |
bc61b91a | 18 | if (size == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) { |
dd891e0e | 19 | secp256k1_fe x; |
bc61b91a | 20 | return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD); |
e2f71f1e | 21 | } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) { |
dd891e0e | 22 | secp256k1_fe x, y; |
d907ebc0 PW |
23 | if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { |
24 | return 0; | |
25 | } | |
e2f71f1e | 26 | secp256k1_ge_set_xy(elem, &x, &y); |
bc61b91a AP |
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)) { | |
e2f71f1e | 29 | return 0; |
26320197 | 30 | } |
39bd94d8 | 31 | return secp256k1_ge_is_valid_var(elem); |
e2f71f1e PW |
32 | } else { |
33 | return 0; | |
34 | } | |
35 | } | |
36 | ||
9234391e | 37 | static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) { |
bbe67d8b PW |
38 | if (secp256k1_ge_is_infinity(elem)) { |
39 | return 0; | |
40 | } | |
39bd94d8 PW |
41 | secp256k1_fe_normalize_var(&elem->x); |
42 | secp256k1_fe_normalize_var(&elem->y); | |
e2f71f1e | 43 | secp256k1_fe_get_b32(&pub[1], &elem->x); |
9234391e | 44 | if (compressed) { |
e2f71f1e | 45 | *size = 33; |
bc61b91a | 46 | pub[0] = secp256k1_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN; |
e2f71f1e PW |
47 | } else { |
48 | *size = 65; | |
bc61b91a | 49 | pub[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED; |
e2f71f1e PW |
50 | secp256k1_fe_get_b32(&pub[33], &elem->y); |
51 | } | |
bbe67d8b | 52 | return 1; |
e2f71f1e PW |
53 | } |
54 | ||
dd891e0e | 55 | static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) { |
a9f5c8b8 | 56 | secp256k1_scalar_add(key, key, tweak); |
26320197 | 57 | if (secp256k1_scalar_is_zero(key)) { |
eb74c36b | 58 | return 0; |
26320197 | 59 | } |
eb74c36b PW |
60 | return 1; |
61 | } | |
62 | ||
dd891e0e PW |
63 | static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { |
64 | secp256k1_gej pt; | |
65 | secp256k1_scalar one; | |
792bcdb0 | 66 | secp256k1_gej_set_ge(&pt, key); |
f24041d6 | 67 | secp256k1_scalar_set_int(&one, 1); |
a9b6595e | 68 | secp256k1_ecmult(ctx, &pt, &pt, &one, tweak); |
eb74c36b | 69 | |
26320197 | 70 | if (secp256k1_gej_is_infinity(&pt)) { |
eb74c36b | 71 | return 0; |
26320197 | 72 | } |
eb74c36b PW |
73 | secp256k1_ge_set_gej(key, &pt); |
74 | return 1; | |
75 | } | |
76 | ||
dd891e0e | 77 | static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak) { |
26320197 | 78 | if (secp256k1_scalar_is_zero(tweak)) { |
eb74c36b | 79 | return 0; |
26320197 | 80 | } |
eb74c36b | 81 | |
a9f5c8b8 | 82 | secp256k1_scalar_mul(key, key, tweak); |
eb74c36b PW |
83 | return 1; |
84 | } | |
85 | ||
dd891e0e PW |
86 | static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { |
87 | secp256k1_scalar zero; | |
88 | secp256k1_gej pt; | |
26320197 | 89 | if (secp256k1_scalar_is_zero(tweak)) { |
eb74c36b | 90 | return 0; |
26320197 | 91 | } |
eb74c36b | 92 | |
f24041d6 | 93 | secp256k1_scalar_set_int(&zero, 0); |
eb74c36b | 94 | secp256k1_gej_set_ge(&pt, key); |
a9b6595e | 95 | secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero); |
eb74c36b PW |
96 | secp256k1_ge_set_gej(key, &pt); |
97 | return 1; | |
98 | } | |
99 | ||
abe2d3e8 | 100 | #endif /* SECP256K1_ECKEY_IMPL_H */ |