]>
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 PW |
6 | |
7 | #ifndef _SECP256K1_ECKEY_IMPL_H_ | |
8 | #define _SECP256K1_ECKEY_IMPL_H_ | |
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) { |
e2f71f1e | 18 | if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) { |
dd891e0e | 19 | secp256k1_fe x; |
39bd94d8 | 20 | return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == 0x03); |
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); |
26320197 | 27 | if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07)) { |
e2f71f1e | 28 | return 0; |
26320197 | 29 | } |
39bd94d8 | 30 | return secp256k1_ge_is_valid_var(elem); |
e2f71f1e PW |
31 | } else { |
32 | return 0; | |
33 | } | |
34 | } | |
35 | ||
9234391e | 36 | static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) { |
bbe67d8b PW |
37 | if (secp256k1_ge_is_infinity(elem)) { |
38 | return 0; | |
39 | } | |
39bd94d8 PW |
40 | secp256k1_fe_normalize_var(&elem->x); |
41 | secp256k1_fe_normalize_var(&elem->y); | |
e2f71f1e | 42 | secp256k1_fe_get_b32(&pub[1], &elem->x); |
9234391e | 43 | if (compressed) { |
e2f71f1e PW |
44 | *size = 33; |
45 | pub[0] = 0x02 | (secp256k1_fe_is_odd(&elem->y) ? 0x01 : 0x00); | |
46 | } else { | |
47 | *size = 65; | |
48 | pub[0] = 0x04; | |
49 | secp256k1_fe_get_b32(&pub[33], &elem->y); | |
50 | } | |
bbe67d8b | 51 | return 1; |
e2f71f1e PW |
52 | } |
53 | ||
dd891e0e | 54 | static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) { |
a9f5c8b8 | 55 | secp256k1_scalar_add(key, key, tweak); |
26320197 | 56 | if (secp256k1_scalar_is_zero(key)) { |
eb74c36b | 57 | return 0; |
26320197 | 58 | } |
eb74c36b PW |
59 | return 1; |
60 | } | |
61 | ||
dd891e0e PW |
62 | static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { |
63 | secp256k1_gej pt; | |
64 | secp256k1_scalar one; | |
792bcdb0 | 65 | secp256k1_gej_set_ge(&pt, key); |
f24041d6 | 66 | secp256k1_scalar_set_int(&one, 1); |
a9b6595e | 67 | secp256k1_ecmult(ctx, &pt, &pt, &one, tweak); |
eb74c36b | 68 | |
26320197 | 69 | if (secp256k1_gej_is_infinity(&pt)) { |
eb74c36b | 70 | return 0; |
26320197 | 71 | } |
eb74c36b PW |
72 | secp256k1_ge_set_gej(key, &pt); |
73 | return 1; | |
74 | } | |
75 | ||
dd891e0e | 76 | static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak) { |
26320197 | 77 | if (secp256k1_scalar_is_zero(tweak)) { |
eb74c36b | 78 | return 0; |
26320197 | 79 | } |
eb74c36b | 80 | |
a9f5c8b8 | 81 | secp256k1_scalar_mul(key, key, tweak); |
eb74c36b PW |
82 | return 1; |
83 | } | |
84 | ||
dd891e0e PW |
85 | static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { |
86 | secp256k1_scalar zero; | |
87 | secp256k1_gej pt; | |
26320197 | 88 | if (secp256k1_scalar_is_zero(tweak)) { |
eb74c36b | 89 | return 0; |
26320197 | 90 | } |
eb74c36b | 91 | |
f24041d6 | 92 | secp256k1_scalar_set_int(&zero, 0); |
eb74c36b | 93 | secp256k1_gej_set_ge(&pt, key); |
a9b6595e | 94 | secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero); |
eb74c36b PW |
95 | secp256k1_ge_set_gej(key, &pt); |
96 | return 1; | |
97 | } | |
98 | ||
e2f71f1e | 99 | #endif |