libbtc
bitcoinclibrary
ecc_libsecp256k1.c
Go to the documentation of this file.
1 #include "secp256k1/include/secp256k1.h"
2 
3 #include <assert.h>
4 #include <stdint.h>
5 #include <string.h>
6 
7 #include "btc/btc.h"
8 
9 #include "random.h"
10 
11 static secp256k1_context* secp256k1_ctx = NULL;
12 
13 void ecc_start(void)
14 {
15  secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
16  assert(secp256k1_ctx != NULL);
17 
18  uint8_t seed[32];
19  random_bytes(seed, 32, 0);
20  int ret = secp256k1_context_randomize(secp256k1_ctx, seed);
21  assert(ret);
22 }
23 
24 
25 void ecc_stop(void)
26 {
27  secp256k1_context* ctx = secp256k1_ctx;
28  secp256k1_ctx = NULL;
29 
30  if (ctx) {
31  secp256k1_context_destroy(ctx);
32  }
33 }
34 
35 
36 void ecc_get_pubkey(const uint8_t* private_key, uint8_t* public_key, size_t* in_outlen, btc_bool compressed)
37 {
38  secp256k1_pubkey pubkey;
39  assert(secp256k1_ctx);
40  assert((int)*in_outlen == (compressed ? 33 : 65));
41  memset(public_key, 0, *in_outlen);
42 
43  if (!secp256k1_ec_pubkey_create(secp256k1_ctx, &pubkey, (const unsigned char*)private_key)) {
44  return;
45  }
46 
47  if (!secp256k1_ec_pubkey_serialize(secp256k1_ctx, public_key, in_outlen, &pubkey, compressed)) {
48  return;
49  }
50 
51  return;
52 }
53 
54 btc_bool ecc_private_key_tweak_add(uint8_t* private_key, const uint8_t* tweak)
55 {
56  assert(secp256k1_ctx);
57  return secp256k1_ec_privkey_tweak_add(secp256k1_ctx, (unsigned char*)private_key, (const unsigned char*)tweak);
58 }
59 
60 btc_bool ecc_public_key_tweak_add(uint8_t* public_key_inout, const uint8_t* tweak)
61 {
62  size_t out;
63  secp256k1_pubkey pubkey;
64 
65  assert(secp256k1_ctx);
66  if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey, public_key_inout, 33))
67  return false;
68 
69  if (!secp256k1_ec_pubkey_tweak_add(secp256k1_ctx, &pubkey, (const unsigned char*)tweak))
70  return false;
71 
72  if (!secp256k1_ec_pubkey_serialize(secp256k1_ctx, public_key_inout, &out, &pubkey, SECP256K1_EC_COMPRESSED))
73  return false;
74 
75  return true;
76 }
77 
78 
79 btc_bool ecc_verify_privatekey(const uint8_t* private_key)
80 {
81  assert(secp256k1_ctx);
82  return secp256k1_ec_seckey_verify(secp256k1_ctx, (const unsigned char*)private_key);
83 }
84 
85 btc_bool ecc_verify_pubkey(const uint8_t* public_key, btc_bool compressed)
86 {
87  secp256k1_pubkey pubkey;
88 
89  assert(secp256k1_ctx);
90  if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey, public_key, compressed ? 33 : 65)) {
91  memset(&pubkey, 0, sizeof(pubkey));
92  return false;
93  }
94 
95  memset(&pubkey, 0, sizeof(pubkey));
96  return true;
97 }
98 
99 btc_bool ecc_sign(const uint8_t* private_key, const uint8_t* hash, unsigned char* sigder, size_t* outlen)
100 {
101  assert(secp256k1_ctx);
102 
103  secp256k1_ecdsa_signature sig;
104  if (!secp256k1_ecdsa_sign(secp256k1_ctx, &sig, hash, private_key, secp256k1_nonce_function_rfc6979, NULL))
105  return 0;
106 
107  if (!secp256k1_ecdsa_signature_serialize_der(secp256k1_ctx, sigder, outlen, &sig))
108  return 0;
109 
110  return 1;
111 }
112 
113 btc_bool ecc_verify_sig(const uint8_t* public_key, btc_bool compressed, const uint8_t* hash, unsigned char* sigder, size_t siglen)
114 {
115  assert(secp256k1_ctx);
116 
117  secp256k1_ecdsa_signature sig;
118  secp256k1_pubkey pubkey;
119 
120  if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey, public_key, compressed ? 33 : 65))
121  return false;
122 
123  if (!secp256k1_ecdsa_signature_parse_der(secp256k1_ctx, &sig, sigder, siglen))
124  return false;
125 
126  return secp256k1_ecdsa_verify(secp256k1_ctx, &sig, hash, &pubkey);
127 }
uint8_t btc_bool
Definition: btc.h:34
void ecc_get_pubkey(const uint8_t *private_key, uint8_t *public_key, size_t *in_outlen, btc_bool compressed)
get public key from given private key
void ecc_start(void)
init static ecc context
btc_bool random_bytes(uint8_t *buf, uint32_t len, const uint8_t update_seed)
Definition: random.c:57
static secp256k1_context * secp256k1_ctx
btc_bool ecc_verify_pubkey(const uint8_t *public_key, btc_bool compressed)
verifies a given public key (compressed[33] or uncompressed[65] bytes)
btc_bool ecc_public_key_tweak_add(uint8_t *public_key_inout, const uint8_t *tweak)
ec mul tweak on given public key
btc_bool ecc_private_key_tweak_add(uint8_t *private_key, const uint8_t *tweak)
ec mul tweak on given private key
btc_bool ecc_sign(const uint8_t *private_key, const uint8_t *hash, unsigned char *sigder, size_t *outlen)
btc_bool ecc_verify_privatekey(const uint8_t *private_key)
verifies a given 32byte key
void ecc_stop(void)
destroys the static ecc context
btc_bool ecc_verify_sig(const uint8_t *public_key, btc_bool compressed, const uint8_t *hash, unsigned char *sigder, size_t siglen)