mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-11 12:22:39 -03:00
Privkey import/export
This commit is contained in:
parent
50eb498ece
commit
da3038c757
4 changed files with 123 additions and 0 deletions
|
@ -90,6 +90,13 @@ int secp256k1_ecdsa_pubkey_create(unsigned char *pubkey, int *pubkeylen, const u
|
|||
|
||||
int secp256k1_ecdsa_pubkey_decompress(unsigned char *pubkey, int *pubkeylen);
|
||||
|
||||
int secp256k1_ecdsa_privkey_export(const unsigned char *seckey,
|
||||
unsigned char *privkey, int *privkeylen,
|
||||
int compressed);
|
||||
|
||||
int secp256k1_ecdsa_privkey_import(unsigned char *seckey,
|
||||
const unsigned char *privkey, int privkeylen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -18,5 +18,7 @@ int static secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const se
|
|||
int static secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *seckey, const secp256k1_num_t *message, const secp256k1_num_t *nonce, int *recid);
|
||||
int static secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_num_t *message, int recid);
|
||||
void static secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *r, const secp256k1_num_t *s);
|
||||
int static secp256k1_ecdsa_privkey_parse(secp256k1_num_t *key, const unsigned char *privkey, int privkeylen);
|
||||
int static secp256k1_ecdsa_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_num_t *key, int compressed);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -210,4 +210,99 @@ void static secp256k1_ecdsa_pubkey_serialize(secp256k1_ge_t *elem, unsigned char
|
|||
}
|
||||
}
|
||||
|
||||
int static secp256k1_ecdsa_privkey_parse(secp256k1_num_t *key, const unsigned char *privkey, int privkeylen) {
|
||||
const unsigned char *end = privkey + privkeylen;
|
||||
// sequence header
|
||||
if (end < privkey+1 || *privkey != 0x30)
|
||||
return 0;
|
||||
privkey++;
|
||||
// sequence length constructor
|
||||
int lenb = 0;
|
||||
if (end < privkey+1 || !(*privkey & 0x80))
|
||||
return 0;
|
||||
lenb = *privkey & ~0x80; privkey++;
|
||||
if (lenb < 1 || lenb > 2)
|
||||
return 0;
|
||||
if (end < privkey+lenb)
|
||||
return 0;
|
||||
// sequence length
|
||||
int len = 0;
|
||||
len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0);
|
||||
privkey += lenb;
|
||||
if (end < privkey+len)
|
||||
return 0;
|
||||
// sequence element 0: version number (=1)
|
||||
if (end < privkey+3 || privkey[0] != 0x02 || privkey[1] != 0x01 || privkey[2] != 0x01)
|
||||
return 0;
|
||||
privkey += 3;
|
||||
// sequence element 1: octet string, 32 bytes
|
||||
if (end < privkey+34 || privkey[0] != 0x04 || privkey[1] != 0x20)
|
||||
return 0;
|
||||
secp256k1_num_set_bin(key, privkey+2, 32);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int static secp256k1_ecdsa_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_num_t *key, int compressed) {
|
||||
secp256k1_gej_t rp;
|
||||
secp256k1_ecmult_gen(&rp, key);
|
||||
secp256k1_ge_t r;
|
||||
secp256k1_ge_set_gej(&r, &rp);
|
||||
if (compressed) {
|
||||
static const unsigned char begin[] = {
|
||||
0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20
|
||||
};
|
||||
static const unsigned char middle[] = {
|
||||
0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
|
||||
0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
|
||||
0x21
|
||||
};
|
||||
static const unsigned char end[] = {
|
||||
0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,0x8C,0xD0,
|
||||
0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00,0x03,0x18,0x39,0x05,0xAE,
|
||||
0x25,0xE8,0x15,0x63,0x4C,0xE7,0xF5,0xD9,0xBE,0xDB,0xAA,0x2C,0x39,0x03,0x2A,0xB9,
|
||||
0x8C,0x75,0xB5,0xE8,0x8F,0xE4,0x3F,0x8D,0xD8,0x24,0x6F,0x3C
|
||||
};
|
||||
unsigned char *ptr = privkey;
|
||||
memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
|
||||
secp256k1_num_get_bin(ptr, 32, key); ptr += 32;
|
||||
memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
|
||||
int pubkeylen = 0;
|
||||
secp256k1_ecdsa_pubkey_serialize(&r, ptr, &pubkeylen, 1); ptr += pubkeylen;
|
||||
memcpy(ptr, end, sizeof(end)); ptr += sizeof(end);
|
||||
*privkeylen = ptr - privkey;
|
||||
} else {
|
||||
static const unsigned char begin[] = {
|
||||
0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20
|
||||
};
|
||||
static const unsigned char middle[] = {
|
||||
0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
|
||||
0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
|
||||
0x41
|
||||
};
|
||||
static const unsigned char end[] = {
|
||||
0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,0x8C,0xD0,
|
||||
0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00,0x04,0x18,0x39,0x05,0xAE,
|
||||
0x25,0xE8,0x15,0x63,0x4C,0xE7,0xF5,0xD9,0xBE,0xDB,0xAA,0x2C,0x39,0x03,0x2A,0xB9,
|
||||
0x8C,0x75,0xB5,0xE8,0x8F,0xE4,0x3F,0x8D,0xD8,0x24,0x6F,0x3C,0x54,0x73,0xCC,0xD4,
|
||||
0xAB,0x47,0x5E,0x6A,0x9E,0x66,0x20,0xB5,0x2F,0x5C,0xE2,0xFD,0x15,0xA2,0xDE,0x32,
|
||||
0xCB,0xE9,0x05,0x15,0x4B,0x3A,0x05,0x84,0x4A,0xF7,0x07,0x85
|
||||
};
|
||||
unsigned char *ptr = privkey;
|
||||
memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
|
||||
secp256k1_num_get_bin(ptr, 32, key); ptr += 32;
|
||||
memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
|
||||
int pubkeylen = 0;
|
||||
secp256k1_ecdsa_pubkey_serialize(&r, ptr, &pubkeylen, 0); ptr += pubkeylen;
|
||||
memcpy(ptr, end, sizeof(end)); ptr += sizeof(end);
|
||||
*privkeylen = ptr - privkey;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -141,3 +141,22 @@ int secp256k1_ecdsa_pubkey_decompress(unsigned char *pubkey, int *pubkeylen) {
|
|||
secp256k1_ecdsa_pubkey_serialize(&p, pubkey, pubkeylen, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int secp256k1_ecdsa_privkey_export(const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) {
|
||||
secp256k1_num_t key;
|
||||
secp256k1_num_init(&key);
|
||||
secp256k1_num_set_bin(&key, seckey, 32);
|
||||
int ret = secp256k1_ecdsa_privkey_serialize(privkey, privkeylen, &key, compressed);
|
||||
secp256k1_num_free(&key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ecdsa_privkey_import(unsigned char *seckey, const unsigned char *privkey, int privkeylen) {
|
||||
secp256k1_num_t key;
|
||||
secp256k1_num_init(&key);
|
||||
int ret = secp256k1_ecdsa_privkey_parse(&key, privkey, privkeylen);
|
||||
if (ret)
|
||||
secp256k1_num_get_bin(seckey, 32, &key);
|
||||
secp256k1_num_free(&key);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue