mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-21 16:14:23 +01:00
Move bitcoin stuff into bitcoin subdir.
It's not very interesting if you're looking for LN code. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
6
bitcoin/README
Normal file
6
bitcoin/README
Normal file
@@ -0,0 +1,6 @@
|
||||
These are standard bitcoin manipulation routines which should be
|
||||
provided by any normal bitcoin library in whatever language you choose.
|
||||
|
||||
The ones here are standalone ones taken from bitcoin core and soe I
|
||||
wrote, many taken from bitcoin-iterate and pasted in here.
|
||||
|
||||
11
bitcoin/address.c
Normal file
11
bitcoin/address.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "address.h"
|
||||
#include "pubkey.h"
|
||||
#include <ccan/crypto/sha256/sha256.h>
|
||||
|
||||
void bitcoin_address(const struct pubkey *key, struct bitcoin_address *addr)
|
||||
{
|
||||
struct sha256 h;
|
||||
|
||||
sha256(&h, key->key, pubkey_len(key));
|
||||
RIPEMD160(h.u.u8, sizeof(h), addr->addr);
|
||||
}
|
||||
15
bitcoin/address.h
Normal file
15
bitcoin/address.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef LIGHTNING_BITCOIN_ADDRESS_H
|
||||
#define LIGHTNING_BITCOIN_ADDRESS_H
|
||||
#include <openssl/ripemd.h>
|
||||
#include <ccan/short_types/short_types.h>
|
||||
|
||||
struct pubkey;
|
||||
|
||||
/* An address is the RIPEMD160 of the SHA of the public key. */
|
||||
struct bitcoin_address {
|
||||
u8 addr[RIPEMD160_DIGEST_LENGTH]; /* 20 */
|
||||
};
|
||||
|
||||
void bitcoin_address(const struct pubkey *key,
|
||||
struct bitcoin_address *addr);
|
||||
#endif /* LIGHTNING_BITCOIN_ADDRESS_H */
|
||||
364
bitcoin/base58.c
Normal file
364
bitcoin/base58.c
Normal file
@@ -0,0 +1,364 @@
|
||||
/* Converted to C by Rusty Russell, based on bitcoin source: */
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2012 The Bitcoin Developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#include "base58.h"
|
||||
#include "shadouble.h"
|
||||
#include "address.h"
|
||||
#include "pubkey.h"
|
||||
#include <assert.h>
|
||||
#include <ccan/build_assert/build_assert.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char enc_16[] = "0123456789abcdef";
|
||||
static const char enc_58[] =
|
||||
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
static char encode_char(unsigned long val, const char *enc)
|
||||
{
|
||||
assert(val < strlen(enc));
|
||||
return enc[val];
|
||||
}
|
||||
|
||||
static int decode_char(char c, const char *enc)
|
||||
{
|
||||
const char *pos = strchr(enc, c);
|
||||
if (!pos)
|
||||
return -1;
|
||||
return pos - enc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode a byte sequence as a base58-encoded string. This is a bit
|
||||
* weird: returns pointer into buf (or NULL if wouldn't fit).
|
||||
*/
|
||||
static char *encode_base58(char *buf, size_t buflen,
|
||||
const u8 *data, size_t data_len)
|
||||
{
|
||||
char *p;
|
||||
BIGNUM bn;
|
||||
|
||||
/* Convert to a bignum. */
|
||||
BN_init(&bn);
|
||||
BN_bin2bn(data, data_len, &bn);
|
||||
|
||||
/* Add NUL terminator */
|
||||
if (!buflen) {
|
||||
p = NULL;
|
||||
goto out;
|
||||
}
|
||||
p = buf + buflen;
|
||||
*(--p) = '\0';
|
||||
|
||||
/* Fill from the back, using a series of divides. */
|
||||
while (!BN_is_zero(&bn)) {
|
||||
int rem = BN_div_word(&bn, 58);
|
||||
if (--p < buf) {
|
||||
p = NULL;
|
||||
goto out;
|
||||
}
|
||||
*p = encode_char(rem, enc_58);
|
||||
}
|
||||
|
||||
/* Now, this is really weird. We pad with zeroes, but not at
|
||||
* base 58, but in terms of zero bytes. This means that some
|
||||
* encodings are shorter than others! */
|
||||
while (data_len && *data == '\0') {
|
||||
if (--p < buf) {
|
||||
p = NULL;
|
||||
goto out;
|
||||
}
|
||||
*p = encode_char(0, enc_58);
|
||||
data_len--;
|
||||
data++;
|
||||
}
|
||||
|
||||
out:
|
||||
BN_free(&bn);
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a base_n-encoded string into a byte sequence.
|
||||
*/
|
||||
bool raw_decode_base_n(BIGNUM *bn, const char *src, size_t len, int base)
|
||||
{
|
||||
const char *enc;
|
||||
|
||||
BN_zero(bn);
|
||||
|
||||
assert(base == 16 || base == 58);
|
||||
switch (base) {
|
||||
case 16:
|
||||
enc = enc_16;
|
||||
break;
|
||||
case 58:
|
||||
enc = enc_58;
|
||||
break;
|
||||
}
|
||||
|
||||
while (len) {
|
||||
char current = *src;
|
||||
|
||||
if (base == 16)
|
||||
current = tolower(current); /* TODO: Not in ccan. */
|
||||
int val = decode_char(current, enc);
|
||||
if (val < 0) {
|
||||
BN_free(bn);
|
||||
return false;
|
||||
}
|
||||
BN_mul_word(bn, base);
|
||||
BN_add_word(bn, val);
|
||||
src++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a base58-encoded string into a byte sequence.
|
||||
*/
|
||||
bool raw_decode_base58(BIGNUM *bn, const char *src, size_t len)
|
||||
{
|
||||
return raw_decode_base_n(bn, src, len, 58);
|
||||
}
|
||||
|
||||
void base58_get_checksum(u8 csum[4], const u8 buf[], size_t buflen)
|
||||
{
|
||||
struct sha256_double sha_result;
|
||||
|
||||
/* Form checksum, using double SHA2 (as per bitcoin standard) */
|
||||
sha256_double(&sha_result, buf, buflen);
|
||||
|
||||
/* Use first four bytes of that as the checksum. */
|
||||
memcpy(csum, sha_result.sha.u.u8, 4);
|
||||
}
|
||||
|
||||
char *bitcoin_to_base58(const tal_t *ctx, bool test_net,
|
||||
const struct bitcoin_address *addr)
|
||||
{
|
||||
u8 buf[1 + RIPEMD160_DIGEST_LENGTH + 4];
|
||||
char out[BASE58_ADDR_MAX_LEN + 2], *p;
|
||||
|
||||
buf[0] = test_net ? 111 : 0;
|
||||
|
||||
BUILD_ASSERT(sizeof(*addr) == RIPEMD160_DIGEST_LENGTH);
|
||||
memcpy(buf+1, addr, RIPEMD160_DIGEST_LENGTH);
|
||||
|
||||
/* Append checksum */
|
||||
base58_get_checksum(buf + 1 + RIPEMD160_DIGEST_LENGTH,
|
||||
buf, 1 + RIPEMD160_DIGEST_LENGTH);
|
||||
|
||||
p = encode_base58(out, BASE58_ADDR_MAX_LEN, buf, sizeof(buf));
|
||||
return tal_strdup(ctx, p);
|
||||
}
|
||||
|
||||
bool bitcoin_from_base58(bool *test_net,
|
||||
struct bitcoin_address *addr,
|
||||
const char *base58, size_t base58_len)
|
||||
{
|
||||
u8 buf[1 + RIPEMD160_DIGEST_LENGTH + 4];
|
||||
BIGNUM bn;
|
||||
size_t len;
|
||||
u8 csum[4];
|
||||
|
||||
BN_init(&bn);
|
||||
if (!raw_decode_base58(&bn, base58, base58_len))
|
||||
return false;
|
||||
|
||||
len = BN_num_bytes(&bn);
|
||||
if (len > sizeof(buf))
|
||||
return false;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
BN_bn2bin(&bn, buf + sizeof(buf) - len);
|
||||
BN_free(&bn);
|
||||
|
||||
if (buf[0] == 111)
|
||||
*test_net = true;
|
||||
else if (buf[0] == 0)
|
||||
*test_net = false;
|
||||
else
|
||||
return false;
|
||||
|
||||
base58_get_checksum(csum, buf, 1 + RIPEMD160_DIGEST_LENGTH);
|
||||
if (memcmp(csum, buf + 1 + RIPEMD160_DIGEST_LENGTH, sizeof(csum)) != 0)
|
||||
return false;
|
||||
|
||||
BUILD_ASSERT(sizeof(*addr) == RIPEMD160_DIGEST_LENGTH);
|
||||
memcpy(addr, buf+1, sizeof(*addr));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* buf already contains version and ripemd160. Append checksum and encode */
|
||||
char *base58_with_check(char dest[BASE58_ADDR_MAX_LEN],
|
||||
u8 buf[1 + RIPEMD160_DIGEST_LENGTH + 4])
|
||||
{
|
||||
/* Append checksum */
|
||||
base58_get_checksum(buf + 1 + RIPEMD160_DIGEST_LENGTH,
|
||||
buf, 1 + RIPEMD160_DIGEST_LENGTH);
|
||||
|
||||
/* Now encode. */
|
||||
return encode_base58(dest, BASE58_ADDR_MAX_LEN, buf,
|
||||
1 + RIPEMD160_DIGEST_LENGTH + 4);
|
||||
}
|
||||
|
||||
bool ripemd_from_base58(u8 *version, u8 ripemd160[RIPEMD160_DIGEST_LENGTH],
|
||||
const char *base58)
|
||||
{
|
||||
u8 buf[1 + RIPEMD160_DIGEST_LENGTH + 4];
|
||||
u8 csum[4];
|
||||
BIGNUM bn;
|
||||
size_t len;
|
||||
|
||||
/* Too long? Check here before doing arithmetic. */
|
||||
if (strlen(base58) > BASE58_ADDR_MAX_LEN - 1)
|
||||
return false;
|
||||
|
||||
BN_init(&bn);
|
||||
/* Fails if it contains invalid characters. */
|
||||
if (!raw_decode_base58(&bn, base58, strlen(base58)))
|
||||
return false;
|
||||
|
||||
/* Too big? */
|
||||
len = BN_num_bytes(&bn);
|
||||
if (len > sizeof(buf)) {
|
||||
BN_free(&bn);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Fill start with zeroes. */
|
||||
memset(buf, 0, sizeof(buf) - len);
|
||||
BN_bn2bin(&bn, buf + sizeof(buf) - len);
|
||||
BN_free(&bn);
|
||||
|
||||
/* Check checksum is correct. */
|
||||
base58_get_checksum(csum, buf, sizeof(buf));
|
||||
if (memcmp(csum, buf + 1 + RIPEMD160_DIGEST_LENGTH, 4) != 0)
|
||||
return false;
|
||||
|
||||
*version = buf[0];
|
||||
memcpy(ripemd160, buf + 1, RIPEMD160_DIGEST_LENGTH);
|
||||
return true;
|
||||
}
|
||||
|
||||
char *key_to_base58(const tal_t *ctx, bool test_net, EC_KEY *key)
|
||||
{
|
||||
u8 buf[1 + 32 + 1 + 4];
|
||||
char out[BASE58_KEY_MAX_LEN + 2], *p;
|
||||
const BIGNUM *bn = EC_KEY_get0_private_key(key);
|
||||
int len;
|
||||
|
||||
buf[0] = test_net ? 239 : 128;
|
||||
|
||||
/* Make sure any zeroes are at the front of number (MSB) */
|
||||
len = BN_num_bytes(bn);
|
||||
assert(len <= 32);
|
||||
memset(buf + 1, 0, 32 - len);
|
||||
BN_bn2bin(bn, buf + 1 + 32 - len);
|
||||
|
||||
/* Mark this as a compressed key. */
|
||||
buf[1 + 32] = 1;
|
||||
|
||||
/* Append checksum */
|
||||
base58_get_checksum(buf + 1 + 32 + 1, buf, 1 + 32 + 1);
|
||||
|
||||
p = encode_base58(out, BASE58_KEY_MAX_LEN, buf, sizeof(buf));
|
||||
return tal_strdup(ctx, p);
|
||||
}
|
||||
|
||||
// Thus function based on bitcoin's key.cpp:
|
||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
static bool EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
|
||||
{
|
||||
BN_CTX *ctx = NULL;
|
||||
EC_POINT *pub_key = NULL;
|
||||
const EC_GROUP *group = EC_KEY_get0_group(eckey);
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
return false;
|
||||
|
||||
pub_key = EC_POINT_new(group);
|
||||
if (pub_key == NULL)
|
||||
return false;
|
||||
|
||||
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
|
||||
return false;
|
||||
|
||||
EC_KEY_set_private_key(eckey, priv_key);
|
||||
EC_KEY_set_public_key(eckey, pub_key);
|
||||
|
||||
BN_CTX_free(ctx);
|
||||
EC_POINT_free(pub_key);
|
||||
return true;
|
||||
}
|
||||
|
||||
EC_KEY *key_from_base58(const char *base58, size_t base58_len,
|
||||
bool *test_net, struct pubkey *key)
|
||||
{
|
||||
size_t keylen;
|
||||
u8 keybuf[1 + 32 + 1 + 4], *kptr;
|
||||
u8 csum[4];
|
||||
EC_KEY *priv;
|
||||
BIGNUM bn;
|
||||
point_conversion_form_t cform;
|
||||
|
||||
BN_init(&bn);
|
||||
if (!raw_decode_base58(&bn, base58, base58_len))
|
||||
return NULL;
|
||||
|
||||
keylen = BN_num_bytes(&bn);
|
||||
if (keylen == 1 + 32 + 4)
|
||||
cform = POINT_CONVERSION_UNCOMPRESSED;
|
||||
else if (keylen == 1 + 32 + 1 + 4)
|
||||
cform = POINT_CONVERSION_COMPRESSED;
|
||||
else
|
||||
goto fail_free_bn;
|
||||
BN_bn2bin(&bn, keybuf);
|
||||
|
||||
base58_get_checksum(csum, keybuf, keylen - sizeof(csum));
|
||||
if (memcmp(csum, keybuf + keylen - sizeof(csum), sizeof(csum)) != 0)
|
||||
goto fail_free_bn;
|
||||
|
||||
/* Byte after key should be 1 to represent a compressed key. */
|
||||
if (cform == POINT_CONVERSION_COMPRESSED && keybuf[1 + 32] != 1)
|
||||
goto fail_free_bn;
|
||||
|
||||
if (keybuf[0] == 128)
|
||||
*test_net = false;
|
||||
else if (keybuf[0] == 239)
|
||||
*test_net = true;
|
||||
else
|
||||
goto fail_free_bn;
|
||||
|
||||
priv = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
EC_KEY_set_conv_form(priv, cform);
|
||||
|
||||
BN_free(&bn);
|
||||
BN_init(&bn);
|
||||
if (!BN_bin2bn(keybuf + 1, 32, &bn))
|
||||
goto fail_free_priv;
|
||||
if (!EC_KEY_regenerate_key(priv, &bn))
|
||||
goto fail_free_priv;
|
||||
|
||||
/* Save public key */
|
||||
kptr = key->key;
|
||||
keylen = i2o_ECPublicKey(priv, &kptr);
|
||||
assert(keylen == pubkey_len(key));
|
||||
|
||||
BN_free(&bn);
|
||||
return priv;
|
||||
|
||||
fail_free_priv:
|
||||
EC_KEY_free(priv);
|
||||
fail_free_bn:
|
||||
BN_free(&bn);
|
||||
return NULL;
|
||||
}
|
||||
47
bitcoin/base58.h
Normal file
47
bitcoin/base58.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef LIGHTNING_BITCOIN_BASE58_H
|
||||
#define LIGHTNING_BITCOIN_BASE58_H
|
||||
/* FIXME: Use libsecpk1 */
|
||||
#include <ccan/tal/tal.h>
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ripemd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct pubkey;
|
||||
struct bitcoin_address;
|
||||
|
||||
/* Encoding is version byte + ripemd160 + 4-byte checksum == 200 bits => 2^200.
|
||||
*
|
||||
* Now, 58^34 < 2^200, but 58^35 > 2^200. So 35 digits is sufficient,
|
||||
* plus 1 terminator.
|
||||
*/
|
||||
#define BASE58_ADDR_MAX_LEN 36
|
||||
|
||||
/* For encoding private keys, it's 302 bits.
|
||||
* 58^51 < 2^302, but 58^52 > 2^302. So 52 digits, plus one terminator. */
|
||||
#define BASE58_KEY_MAX_LEN 53
|
||||
|
||||
/* Bitcoin address encoded in base58, with version and checksum */
|
||||
char *bitcoin_to_base58(const tal_t *ctx, bool test_net,
|
||||
const struct bitcoin_address *addr);
|
||||
bool bitcoin_from_base58(bool *test_net,
|
||||
struct bitcoin_address *addr,
|
||||
const char *base58, size_t len);
|
||||
|
||||
bool ripemd_from_base58(u8 *version, u8 ripemd160[RIPEMD160_DIGEST_LENGTH],
|
||||
const char *base58);
|
||||
|
||||
char *base58_with_check(char dest[BASE58_ADDR_MAX_LEN],
|
||||
u8 buf[1 + RIPEMD160_DIGEST_LENGTH + 4]);
|
||||
|
||||
char *key_to_base58(const tal_t *ctx, bool test_net, EC_KEY *key);
|
||||
EC_KEY *key_from_base58(const char *base58, size_t base58_len,
|
||||
bool *test_net, struct pubkey *key);
|
||||
|
||||
bool raw_decode_base_n(BIGNUM *bn, const char *src, size_t len, int base);
|
||||
bool raw_decode_base58(BIGNUM *bn, const char *src, size_t len);
|
||||
void base58_get_checksum(u8 csum[4], const u8 buf[], size_t buflen);
|
||||
|
||||
#endif /* PETTYCOIN_BITCOIN_BASE58_H */
|
||||
67
bitcoin/pubkey.c
Normal file
67
bitcoin/pubkey.c
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "pubkey.h"
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <ccan/str/hex/hex.h>
|
||||
|
||||
/* Must agree on key validity with bitcoin! Stolen from bitcoin/src/pubkey.h's
|
||||
* GetLen:
|
||||
* // Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
* // Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
* // Distributed under the MIT software license, see the accompanying
|
||||
* // file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
*/
|
||||
static unsigned int GetLen(unsigned char chHeader)
|
||||
{
|
||||
if (chHeader == 2 || chHeader == 3)
|
||||
return 33;
|
||||
if (chHeader == 4 || chHeader == 6 || chHeader == 7)
|
||||
return 65;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool valid_pubkey(const BitcoinPubkey *key)
|
||||
{
|
||||
if (key->key.len < 1)
|
||||
return false;
|
||||
return (key->key.len == GetLen(key->key.data[0]));
|
||||
}
|
||||
|
||||
size_t pubkey_len(const struct pubkey *key)
|
||||
{
|
||||
size_t len = GetLen(key->key[0]);
|
||||
|
||||
assert(len);
|
||||
return len;
|
||||
}
|
||||
|
||||
BitcoinPubkey *pubkey_to_proto(const tal_t *ctx, const struct pubkey *key)
|
||||
{
|
||||
BitcoinPubkey *p = tal(ctx, BitcoinPubkey);
|
||||
|
||||
bitcoin_pubkey__init(p);
|
||||
p->key.len = pubkey_len(key);
|
||||
p->key.data = tal_dup_arr(p, u8, key->key, p->key.len, 0);
|
||||
|
||||
assert(valid_pubkey(p));
|
||||
return p;
|
||||
}
|
||||
|
||||
bool proto_to_pubkey(const BitcoinPubkey *pb, struct pubkey *key)
|
||||
{
|
||||
if (!valid_pubkey(pb))
|
||||
return false;
|
||||
|
||||
memcpy(key->key, pb->key.data, pb->key.len);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pubkey_from_hexstr(const char *str, struct pubkey *key)
|
||||
{
|
||||
size_t slen = strlen(str), dlen;
|
||||
dlen = hex_data_size(slen);
|
||||
|
||||
if (dlen != 33 && dlen != 65)
|
||||
return false;
|
||||
if (!hex_decode(str, slen, key->key, dlen))
|
||||
return false;
|
||||
return GetLen(key->key[0]) == dlen;
|
||||
}
|
||||
21
bitcoin/pubkey.h
Normal file
21
bitcoin/pubkey.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef LIGHTNING_BITCOIN_PUBKEY_H
|
||||
#define LIGHTNING_BITCOIN_PUBKEY_H
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include "../lightning.pb-c.h"
|
||||
|
||||
struct pubkey {
|
||||
u8 key[65];
|
||||
};
|
||||
|
||||
/* Convert to-from protobuf to internal representation. */
|
||||
BitcoinPubkey *pubkey_to_proto(const tal_t *ctx, const struct pubkey *key);
|
||||
bool proto_to_pubkey(const BitcoinPubkey *pb, struct pubkey *key);
|
||||
|
||||
/* 33 or 65 bytes? */
|
||||
size_t pubkey_len(const struct pubkey *key);
|
||||
|
||||
/* Convert from hex string (scriptPubKey from validateaddress) */
|
||||
bool pubkey_from_hexstr(const char *str, struct pubkey *key);
|
||||
|
||||
#endif /* LIGHTNING_PUBKEY_H */
|
||||
419
bitcoin/script.c
Normal file
419
bitcoin/script.c
Normal file
@@ -0,0 +1,419 @@
|
||||
#include "script.h"
|
||||
#include "address.h"
|
||||
#include "signature.h"
|
||||
#include "pubkey.h"
|
||||
#include <openssl/ripemd.h>
|
||||
#include <ccan/endian/endian.h>
|
||||
#include <ccan/crypto/sha256/sha256.h>
|
||||
|
||||
/* Some standard ops */
|
||||
#define OP_PUSHBYTES(val) (val)
|
||||
#define OP_PUSHDATA1 0x4C
|
||||
#define OP_PUSHDATA2 0x4D
|
||||
#define OP_PUSHDATA4 0x4E
|
||||
#define OP_NOP 0x61
|
||||
#define OP_IF 0x63
|
||||
#define OP_ELSE 0x67
|
||||
#define OP_ENDIF 0x68
|
||||
#define OP_DEPTH 0x74
|
||||
#define OP_DROP 0x75
|
||||
#define OP_DUP 0x76
|
||||
#define OP_EQUAL 0x87
|
||||
#define OP_EQUALVERIFY 0x88
|
||||
#define OP_SIZE 0x82
|
||||
#define OP_1SUB 0x8C
|
||||
#define OP_CHECKSIG 0xAC
|
||||
#define OP_CHECKMULTISIG 0xAE
|
||||
#define OP_HASH160 0xA9
|
||||
|
||||
#ifdef HAS_CSV
|
||||
#define OP_CHECKSEQUENCEVERIFY 0xB2
|
||||
#else
|
||||
/* OP_NOP, otherwise bitcoind complains */
|
||||
#define OP_CHECKSEQUENCEVERIFY 0x61
|
||||
#endif
|
||||
static void add(u8 **scriptp, const void *mem, size_t len)
|
||||
{
|
||||
size_t oldlen = tal_count(*scriptp);
|
||||
tal_resize(scriptp, oldlen + len);
|
||||
memcpy(*scriptp + oldlen, mem, len);
|
||||
}
|
||||
|
||||
static void add_op(u8 **scriptp, u8 op)
|
||||
{
|
||||
add(scriptp, &op, 1);
|
||||
}
|
||||
|
||||
static void add_push_bytes(u8 **scriptp, const void *mem, size_t len)
|
||||
{
|
||||
if (len < 76)
|
||||
add_op(scriptp, OP_PUSHBYTES(len));
|
||||
else if (len < 256) {
|
||||
char c = len;
|
||||
add_op(scriptp, OP_PUSHDATA1);
|
||||
add(scriptp, &c, 1);
|
||||
} else if (len < 65536) {
|
||||
le16 v = cpu_to_le16(len);
|
||||
add_op(scriptp, OP_PUSHDATA2);
|
||||
add(scriptp, &v, 2);
|
||||
} else {
|
||||
le32 v = cpu_to_le32(len);
|
||||
add_op(scriptp, OP_PUSHDATA4);
|
||||
add(scriptp, &v, 4);
|
||||
}
|
||||
|
||||
add(scriptp, mem, len);
|
||||
}
|
||||
|
||||
static void add_number(u8 **script, u32 num)
|
||||
{
|
||||
if (num == 0)
|
||||
add_op(script, 0);
|
||||
else if (num <= 16)
|
||||
add_op(script, 0x50 + num);
|
||||
else {
|
||||
u8 n = num;
|
||||
/* We could handle others, but currently unnecessary. */
|
||||
assert(num < 256);
|
||||
add_push_bytes(script, &n, sizeof(n));
|
||||
}
|
||||
}
|
||||
|
||||
static void add_push_key(u8 **scriptp, const struct pubkey *key)
|
||||
{
|
||||
add_push_bytes(scriptp, key->key, pubkey_len(key));
|
||||
}
|
||||
|
||||
/* Stolen direct from bitcoin/src/script/sign.cpp:
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
*/
|
||||
static bool IsValidSignatureEncoding(const unsigned char sig[], size_t len)
|
||||
{
|
||||
// Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash]
|
||||
// * total-length: 1-byte length descriptor of everything that follows,
|
||||
// excluding the sighash byte.
|
||||
// * R-length: 1-byte length descriptor of the R value that follows.
|
||||
// * R: arbitrary-length big-endian encoded R value. It must use the shortest
|
||||
// possible encoding for a positive integers (which means no null bytes at
|
||||
// the start, except a single one when the next byte has its highest bit set).
|
||||
// * S-length: 1-byte length descriptor of the S value that follows.
|
||||
// * S: arbitrary-length big-endian encoded S value. The same rules apply.
|
||||
// * sighash: 1-byte value indicating what data is hashed (not part of the DER
|
||||
// signature)
|
||||
|
||||
// Minimum and maximum size constraints.
|
||||
if (len < 9) return false;
|
||||
if (len > 73) return false;
|
||||
|
||||
// A signature is of type 0x30 (compound).
|
||||
if (sig[0] != 0x30) return false;
|
||||
|
||||
// Make sure the length covers the entire signature.
|
||||
if (sig[1] != len - 3) return false;
|
||||
|
||||
// Extract the length of the R element.
|
||||
unsigned int lenR = sig[3];
|
||||
|
||||
// Make sure the length of the S element is still inside the signature.
|
||||
if (5 + lenR >= len) return false;
|
||||
|
||||
// Extract the length of the S element.
|
||||
unsigned int lenS = sig[5 + lenR];
|
||||
|
||||
// Verify that the length of the signature matches the sum of the length
|
||||
// of the elements.
|
||||
if ((size_t)(lenR + lenS + 7) != len) return false;
|
||||
|
||||
// Check whether the R element is an integer.
|
||||
if (sig[2] != 0x02) return false;
|
||||
|
||||
// Zero-length integers are not allowed for R.
|
||||
if (lenR == 0) return false;
|
||||
|
||||
// Negative numbers are not allowed for R.
|
||||
if (sig[4] & 0x80) return false;
|
||||
|
||||
// Null bytes at the start of R are not allowed, unless R would
|
||||
// otherwise be interpreted as a negative number.
|
||||
if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false;
|
||||
|
||||
// Check whether the S element is an integer.
|
||||
if (sig[lenR + 4] != 0x02) return false;
|
||||
|
||||
// Zero-length integers are not allowed for S.
|
||||
if (lenS == 0) return false;
|
||||
|
||||
// Negative numbers are not allowed for S.
|
||||
if (sig[lenR + 6] & 0x80) return false;
|
||||
|
||||
// Null bytes at the start of S are not allowed, unless S would otherwise be
|
||||
// interpreted as a negative number.
|
||||
if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* DER encode a value, return length used. */
|
||||
static size_t der_encode_val(const u8 *val, u8 *der)
|
||||
{
|
||||
size_t len = 0, val_len = 32;
|
||||
|
||||
der[len++] = 0x2; /* value type. */
|
||||
|
||||
/* Strip leading zeroes. */
|
||||
while (val_len && val[0] == 0) {
|
||||
val++;
|
||||
val_len--;
|
||||
}
|
||||
|
||||
/* Add zero byte if it would otherwise be signed. */
|
||||
if (val[0] & 0x80) {
|
||||
der[len++] = 1 + val_len; /* value length */
|
||||
der[len++] = 0;
|
||||
} else
|
||||
der[len++] = val_len; /* value length */
|
||||
|
||||
memcpy(der + len, val, val_len);
|
||||
return len + val_len;
|
||||
}
|
||||
|
||||
/* Bitcoin wants DER encoding. */
|
||||
static void add_push_sig(u8 **scriptp, const struct bitcoin_signature *sig)
|
||||
{
|
||||
u8 der[2 + 2 + 1 + sizeof(sig->sig.r) + 2 + 1 + sizeof(sig->sig.s) + 1];
|
||||
size_t len = 0;
|
||||
|
||||
der[len++] = 0x30; /* Type */
|
||||
der[len++] = 0; /* Total length after this: fill it at end. */
|
||||
|
||||
len += der_encode_val(sig->sig.r, der + len);
|
||||
len += der_encode_val(sig->sig.s, der + len);
|
||||
|
||||
/* Fix up total length */
|
||||
der[1] = len - 2;
|
||||
|
||||
/* Append sighash type */
|
||||
der[len++] = sig->stype;
|
||||
|
||||
assert(IsValidSignatureEncoding(der, len));
|
||||
add_push_bytes(scriptp, der, len);
|
||||
}
|
||||
|
||||
/* FIXME: permute? */
|
||||
/* Is a < b? (If equal we don't care) */
|
||||
static bool key_less(const struct pubkey *a, const struct pubkey *b)
|
||||
{
|
||||
/* Shorter one wins. */
|
||||
if (pubkey_len(a) != pubkey_len(b))
|
||||
return pubkey_len(a) < pubkey_len(b);
|
||||
|
||||
return memcmp(a->key, b->key, pubkey_len(a)) < 0;
|
||||
}
|
||||
|
||||
/* tal_count() gives the length of the script. */
|
||||
u8 *bitcoin_redeem_2of2(const tal_t *ctx,
|
||||
const struct pubkey *key1,
|
||||
const struct pubkey *key2)
|
||||
{
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
add_number(&script, 2);
|
||||
if (key_less(key1, key2)) {
|
||||
add_push_key(&script, key1);
|
||||
add_push_key(&script, key2);
|
||||
} else {
|
||||
add_push_key(&script, key2);
|
||||
add_push_key(&script, key1);
|
||||
}
|
||||
add_number(&script, 2);
|
||||
add_op(&script, OP_CHECKMULTISIG);
|
||||
return script;
|
||||
}
|
||||
|
||||
/* tal_count() gives the length of the script. */
|
||||
u8 *bitcoin_redeem_single(const tal_t *ctx, const struct pubkey *key)
|
||||
{
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
add_push_key(&script, key);
|
||||
add_op(&script, OP_CHECKSIG);
|
||||
return script;
|
||||
}
|
||||
|
||||
/* Create p2sh for this redeem script. */
|
||||
u8 *scriptpubkey_p2sh(const tal_t *ctx, const u8 *redeemscript)
|
||||
{
|
||||
struct sha256 h;
|
||||
u8 redeemhash[RIPEMD160_DIGEST_LENGTH];
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
|
||||
add_op(&script, OP_HASH160);
|
||||
sha256(&h, redeemscript, tal_count(redeemscript));
|
||||
RIPEMD160(h.u.u8, sizeof(h), redeemhash);
|
||||
add_push_bytes(&script, redeemhash, sizeof(redeemhash));
|
||||
add_op(&script, OP_EQUAL);
|
||||
return script;
|
||||
}
|
||||
|
||||
u8 *scriptsig_pay_to_pubkeyhash(const tal_t *ctx,
|
||||
const struct pubkey *key,
|
||||
const struct bitcoin_signature *sig)
|
||||
{
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
|
||||
add_push_sig(&script, sig);
|
||||
add_push_key(&script, key);
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
/* Assumes redeemscript contains CHECKSIG, not CHECKMULTISIG */
|
||||
u8 *scriptsig_p2sh_single_sig(const tal_t *ctx,
|
||||
const u8 *redeem_script,
|
||||
size_t redeem_len,
|
||||
const struct bitcoin_signature *sig)
|
||||
{
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
|
||||
add_push_sig(&script, sig);
|
||||
add_push_bytes(&script, redeem_script, redeem_len);
|
||||
return script;
|
||||
}
|
||||
|
||||
u8 *scriptsig_p2sh_2of2(const tal_t *ctx,
|
||||
const struct bitcoin_signature *sig1,
|
||||
const struct bitcoin_signature *sig2,
|
||||
const struct pubkey *key1,
|
||||
const struct pubkey *key2)
|
||||
{
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
u8 *redeemscript;
|
||||
|
||||
/* OP_CHECKMULTISIG has an out-by-one bug, which MBZ */
|
||||
add_number(&script, 0);
|
||||
/* sig order should match key order. */
|
||||
if (key_less(key1, key2)) {
|
||||
add_push_sig(&script, sig1);
|
||||
add_push_sig(&script, sig2);
|
||||
} else {
|
||||
add_push_sig(&script, sig2);
|
||||
add_push_sig(&script, sig1);
|
||||
}
|
||||
redeemscript = bitcoin_redeem_2of2(script, key1, key2);
|
||||
add_push_bytes(&script, redeemscript, tal_count(redeemscript));
|
||||
return script;
|
||||
}
|
||||
|
||||
/* Is this a normal pay to pubkey hash? */
|
||||
bool is_pay_to_pubkey_hash(const u8 *script, size_t script_len)
|
||||
{
|
||||
if (script_len != 25)
|
||||
return false;
|
||||
if (script[0] != OP_DUP)
|
||||
return false;
|
||||
if (script[1] != OP_HASH160)
|
||||
return false;
|
||||
if (script[2] != OP_PUSHBYTES(20))
|
||||
return false;
|
||||
if (script[23] != OP_EQUALVERIFY)
|
||||
return false;
|
||||
if (script[24] != OP_CHECKSIG)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_p2sh(const u8 *script, size_t script_len)
|
||||
{
|
||||
if (script_len != 23)
|
||||
return false;
|
||||
if (script[0] != OP_HASH160)
|
||||
return false;
|
||||
if (script[1] != OP_PUSHBYTES(20))
|
||||
return false;
|
||||
if (script[22] != OP_EQUAL)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* One of:
|
||||
* mysig and theirsig, OR
|
||||
* mysig and relative locktime passed, OR
|
||||
* theirsig and hash preimage. */
|
||||
u8 *bitcoin_redeem_revocable(const tal_t *ctx,
|
||||
const struct pubkey *mykey,
|
||||
u32 locktime,
|
||||
const struct pubkey *theirkey,
|
||||
const struct sha256 *rhash)
|
||||
{
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
u8 rhash_ripemd[RIPEMD160_DIGEST_LENGTH];
|
||||
le32 locktime_le = cpu_to_le32(locktime);
|
||||
|
||||
/* If there are two args: */
|
||||
add_op(&script, OP_DEPTH);
|
||||
add_op(&script, OP_1SUB);
|
||||
add_op(&script, OP_IF);
|
||||
|
||||
/* If the top arg is a hashpreimage. */
|
||||
add_op(&script, OP_SIZE);
|
||||
add_number(&script, 32);
|
||||
add_op(&script, OP_EQUAL);
|
||||
add_op(&script, OP_IF);
|
||||
|
||||
/* Must hash to revocation_hash, and be signed by them. */
|
||||
RIPEMD160(rhash->u.u8, sizeof(rhash->u), rhash_ripemd);
|
||||
add_op(&script, OP_HASH160);
|
||||
add_push_bytes(&script, rhash_ripemd, sizeof(rhash_ripemd));
|
||||
add_op(&script, OP_EQUALVERIFY);
|
||||
add_push_key(&script, theirkey);
|
||||
add_op(&script, OP_CHECKSIG);
|
||||
|
||||
/* Otherwise, it should be both our sigs. */
|
||||
|
||||
/* FIXME: Perhaps this is a bad idea? We don't need it to
|
||||
* close, and without this we force the blockchain to commit
|
||||
* to the timeout: that may make a flood of transactions due
|
||||
* to hub collapse less likely (as some optimists hope hub
|
||||
* will return). */
|
||||
add_op(&script, OP_ELSE);
|
||||
|
||||
add_number(&script, 2);
|
||||
/* This obscures whose key is whose. Probably unnecessary? */
|
||||
if (key_less(mykey, theirkey)) {
|
||||
add_push_key(&script, mykey);
|
||||
add_push_key(&script, theirkey);
|
||||
} else {
|
||||
add_push_key(&script, theirkey);
|
||||
add_push_key(&script, mykey);
|
||||
}
|
||||
add_number(&script, 2);
|
||||
add_op(&script, OP_CHECKMULTISIG);
|
||||
add_op(&script, OP_ENDIF);
|
||||
|
||||
/* Not two args? Must be us using timeout. */
|
||||
add_op(&script, OP_ELSE);
|
||||
add_push_bytes(&script, &locktime_le, sizeof(locktime_le));
|
||||
add_op(&script, OP_CHECKSEQUENCEVERIFY);
|
||||
add_op(&script, OP_DROP);
|
||||
add_push_key(&script, mykey);
|
||||
add_op(&script, OP_CHECKSIG);
|
||||
add_op(&script, OP_ENDIF);
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
u8 *scriptsig_p2sh_revoke(const tal_t *ctx,
|
||||
const struct sha256 *preimage,
|
||||
const struct bitcoin_signature *sig,
|
||||
const u8 *revocable_redeem,
|
||||
size_t redeem_len)
|
||||
{
|
||||
u8 *script = tal_arr(ctx, u8, 0);
|
||||
|
||||
add_push_sig(&script, sig);
|
||||
add_push_bytes(&script, preimage, sizeof(*preimage));
|
||||
add_push_bytes(&script, revocable_redeem, redeem_len);
|
||||
|
||||
return script;
|
||||
}
|
||||
69
bitcoin/script.h
Normal file
69
bitcoin/script.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifndef LIGHTNING_BITCOIN_SCRIPT_H
|
||||
#define LIGHTNING_BITCOIN_SCRIPT_H
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include "signature.h"
|
||||
|
||||
struct bitcoin_address;
|
||||
struct pubkey;
|
||||
struct sha256;
|
||||
|
||||
/* A bitcoin signature includes one byte for the type. */
|
||||
struct bitcoin_signature {
|
||||
struct signature sig;
|
||||
enum sighash_type stype;
|
||||
};
|
||||
|
||||
/* tal_count() gives the length of the script. */
|
||||
u8 *bitcoin_redeem_2of2(const tal_t *ctx,
|
||||
const struct pubkey *key1,
|
||||
const struct pubkey *key2);
|
||||
|
||||
/* tal_count() gives the length of the script. */
|
||||
u8 *bitcoin_redeem_single(const tal_t *ctx, const struct pubkey *key);
|
||||
|
||||
/* One of:
|
||||
* mysig and theirsig, OR
|
||||
* mysig and relative locktime passed, OR
|
||||
* theirsig and hash preimage. */
|
||||
u8 *bitcoin_redeem_revocable(const tal_t *ctx,
|
||||
const struct pubkey *mykey,
|
||||
u32 locktime,
|
||||
const struct pubkey *theirkey,
|
||||
const struct sha256 *revocation_hash);
|
||||
|
||||
/* Create an output script using p2sh for this redeem script. */
|
||||
u8 *scriptpubkey_p2sh(const tal_t *ctx, const u8 *redeemscript);
|
||||
|
||||
/* Create an input script to accept pay to pubkey */
|
||||
u8 *scriptsig_pay_to_pubkeyhash(const tal_t *ctx,
|
||||
const struct pubkey *key,
|
||||
const struct bitcoin_signature *sig);
|
||||
|
||||
/* Create an input script to accept pay to pubkey */
|
||||
u8 *scriptsig_p2sh_2of2(const tal_t *ctx,
|
||||
const struct bitcoin_signature *sig1,
|
||||
const struct bitcoin_signature *sig2,
|
||||
const struct pubkey *key1,
|
||||
const struct pubkey *key2);
|
||||
|
||||
/* Create an input script to solve by revokehash */
|
||||
u8 *scriptsig_p2sh_revoke(const tal_t *ctx,
|
||||
const struct sha256 *preimage,
|
||||
const struct bitcoin_signature *sig,
|
||||
const u8 *revocable_redeem,
|
||||
size_t redeem_len);
|
||||
|
||||
/* Create an input script which pushes sigs then redeem script. */
|
||||
u8 *scriptsig_p2sh_single_sig(const tal_t *ctx,
|
||||
const u8 *redeem_script,
|
||||
size_t redeem_len,
|
||||
const struct bitcoin_signature *sig);
|
||||
|
||||
/* Is this a normal pay to pubkey hash? */
|
||||
bool is_pay_to_pubkey_hash(const u8 *script, size_t script_len);
|
||||
|
||||
/* Is this a pay to script hash? */
|
||||
bool is_p2sh(const u8 *script, size_t script_len);
|
||||
|
||||
#endif /* LIGHTNING_BITCOIN_SCRIPT_H */
|
||||
13
bitcoin/shadouble.c
Normal file
13
bitcoin/shadouble.c
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "shadouble.h"
|
||||
|
||||
void sha256_double(struct sha256_double *shadouble, const void *p, size_t len)
|
||||
{
|
||||
sha256(&shadouble->sha, p, len);
|
||||
sha256(&shadouble->sha, &shadouble->sha, sizeof(shadouble->sha));
|
||||
}
|
||||
|
||||
void sha256_double_done(struct sha256_ctx *shactx, struct sha256_double *res)
|
||||
{
|
||||
sha256_done(shactx, &res->sha);
|
||||
sha256(&res->sha, &res->sha, sizeof(res->sha));
|
||||
}
|
||||
14
bitcoin/shadouble.h
Normal file
14
bitcoin/shadouble.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef LIGHTNING_BITCOIN_SHADOUBLE_H
|
||||
#define LIGHTNING_BITCOIN_SHADOUBLE_H
|
||||
#include "config.h"
|
||||
#include <ccan/crypto/sha256/sha256.h>
|
||||
|
||||
/* To explicitly distinguish between single sha and bitcoin's standard double */
|
||||
struct sha256_double {
|
||||
struct sha256 sha;
|
||||
};
|
||||
|
||||
void sha256_double(struct sha256_double *shadouble, const void *p, size_t len);
|
||||
|
||||
void sha256_double_done(struct sha256_ctx *sha256, struct sha256_double *res);
|
||||
#endif /* LIGHTNING_BITCOIN_SHADOUBLE_H */
|
||||
276
bitcoin/signature.c
Normal file
276
bitcoin/signature.c
Normal file
@@ -0,0 +1,276 @@
|
||||
#include "signature.h"
|
||||
#include "shadouble.h"
|
||||
#include "tx.h"
|
||||
#include "pubkey.h"
|
||||
#include "script.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <assert.h>
|
||||
#include <ccan/cast/cast.h>
|
||||
|
||||
#undef DEBUG
|
||||
#ifdef DEBUG
|
||||
#include <ccan/err/err.h>
|
||||
#define SHA_FMT \
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x" \
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x" \
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x" \
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x"
|
||||
|
||||
#define SHA_VALS(e) \
|
||||
e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], \
|
||||
e[8], e[9], e[10], e[11], e[12], e[13], e[14], e[15], \
|
||||
e[16], e[17], e[18], e[19], e[20], e[21], e[22], e[23], \
|
||||
e[24], e[25], e[25], e[26], e[28], e[29], e[30], e[31]
|
||||
|
||||
static void dump_tx(const char *msg,
|
||||
const struct bitcoin_tx *tx, size_t inputnum,
|
||||
const u8 *script, size_t script_len,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
size_t i, j;
|
||||
warnx("%s tx version %u locktime %#x:",
|
||||
msg, tx->version, tx->lock_time);
|
||||
for (i = 0; i < tx->input_count; i++) {
|
||||
warnx("input[%zu].txid = "SHA_FMT, i,
|
||||
SHA_VALS(tx->input[i].txid.sha.u.u8));
|
||||
warnx("input[%zu].index = %u", i, tx->input[i].index);
|
||||
}
|
||||
for (i = 0; i < tx->output_count; i++) {
|
||||
warnx("output[%zu].amount = %llu",
|
||||
i, (long long)tx->output[i].amount);
|
||||
warnx("output[%zu].script = %llu",
|
||||
i, (long long)tx->output[i].script_length);
|
||||
for (j = 0; j < tx->output[i].script_length; j++)
|
||||
fprintf(stderr, "%02x", tx->output[i].script[j]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
warnx("input[%zu].script = %zu", inputnum, script_len);
|
||||
for (i = 0; i < script_len; i++)
|
||||
fprintf(stderr, "%02x", script[i]);
|
||||
if (key) {
|
||||
fprintf(stderr, "\nPubkey: ");
|
||||
for (i = 0; i < pubkey_len(key); i++)
|
||||
fprintf(stderr, "%02x", key->key[i]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void dump_tx(const char *msg,
|
||||
const struct bitcoin_tx *tx, size_t inputnum,
|
||||
const u8 *script, size_t script_len,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
bool sign_hash(const tal_t *ctx, EC_KEY *private_key,
|
||||
const struct sha256_double *h,
|
||||
struct signature *s)
|
||||
{
|
||||
ECDSA_SIG *sig;
|
||||
int len;
|
||||
|
||||
sig = ECDSA_do_sign(h->sha.u.u8, sizeof(*h), private_key);
|
||||
if (!sig)
|
||||
return false;
|
||||
|
||||
/* See https://github.com/sipa/bitcoin/commit/a81cd9680.
|
||||
* There can only be one signature with an even S, so make sure we
|
||||
* get that one. */
|
||||
if (BN_is_odd(sig->s)) {
|
||||
const EC_GROUP *group;
|
||||
BIGNUM order;
|
||||
|
||||
BN_init(&order);
|
||||
group = EC_KEY_get0_group(private_key);
|
||||
EC_GROUP_get_order(group, &order, NULL);
|
||||
BN_sub(sig->s, &order, sig->s);
|
||||
BN_free(&order);
|
||||
|
||||
assert(!BN_is_odd(sig->s));
|
||||
}
|
||||
|
||||
/* In case numbers are small. */
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
/* Pack r and s into signature, 32 bytes each. */
|
||||
len = BN_num_bytes(sig->r);
|
||||
assert(len <= sizeof(s->r));
|
||||
BN_bn2bin(sig->r, s->r + sizeof(s->r) - len);
|
||||
len = BN_num_bytes(sig->s);
|
||||
assert(len <= sizeof(s->s));
|
||||
BN_bn2bin(sig->s, s->s + sizeof(s->s) - len);
|
||||
|
||||
ECDSA_SIG_free(sig);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Only does SIGHASH_ALL */
|
||||
static void sha256_tx_one_input(struct bitcoin_tx *tx,
|
||||
size_t input_num,
|
||||
const u8 *script, size_t script_len,
|
||||
struct sha256_double *hash)
|
||||
{
|
||||
struct sha256_ctx ctx = SHA256_INIT;
|
||||
size_t i;
|
||||
|
||||
assert(input_num < tx->input_count);
|
||||
|
||||
/* You must have all inputs zeroed to start. */
|
||||
for (i = 0; i < tx->input_count; i++)
|
||||
assert(tx->input[i].script_length == 0);
|
||||
|
||||
tx->input[input_num].script_length = script_len;
|
||||
tx->input[input_num].script = cast_const(u8 *, script);
|
||||
|
||||
sha256_init(&ctx);
|
||||
sha256_tx(&ctx, tx);
|
||||
sha256_le32(&ctx, SIGHASH_ALL);
|
||||
sha256_double_done(&ctx, hash);
|
||||
|
||||
/* Reset it for next time. */
|
||||
tx->input[input_num].script_length = 0;
|
||||
tx->input[input_num].script = NULL;
|
||||
}
|
||||
|
||||
/* Only does SIGHASH_ALL */
|
||||
bool sign_tx_input(const tal_t *ctx, struct bitcoin_tx *tx,
|
||||
unsigned int in,
|
||||
const u8 *subscript, size_t subscript_len,
|
||||
EC_KEY *privkey, const struct pubkey *key,
|
||||
struct signature *sig)
|
||||
{
|
||||
struct sha256_double hash;
|
||||
|
||||
sha256_tx_one_input(tx, in, subscript, subscript_len, &hash);
|
||||
dump_tx("Signing", tx, in, subscript, subscript_len, key);
|
||||
return sign_hash(ctx, privkey, &hash, sig);
|
||||
}
|
||||
|
||||
static bool check_signed_hash(const struct sha256_double *hash,
|
||||
const struct signature *signature,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
bool ok = false;
|
||||
BIGNUM r, s;
|
||||
ECDSA_SIG sig = { &r, &s };
|
||||
EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
const unsigned char *k = key->key;
|
||||
|
||||
/* S must be even: https://github.com/sipa/bitcoin/commit/a81cd9680 */
|
||||
assert((signature->s[31] & 1) == 0);
|
||||
|
||||
/* Unpack public key. */
|
||||
if (!o2i_ECPublicKey(&eckey, &k, pubkey_len(key)))
|
||||
goto out;
|
||||
|
||||
/* Unpack signature. */
|
||||
BN_init(&r);
|
||||
BN_init(&s);
|
||||
if (!BN_bin2bn(signature->r, sizeof(signature->r), &r)
|
||||
|| !BN_bin2bn(signature->s, sizeof(signature->s), &s))
|
||||
goto free_bns;
|
||||
|
||||
/* Now verify hash with public key and signature. */
|
||||
switch (ECDSA_do_verify(hash->sha.u.u8, sizeof(hash->sha.u), &sig,
|
||||
eckey)) {
|
||||
case 0:
|
||||
/* Invalid signature */
|
||||
goto free_bns;
|
||||
case -1:
|
||||
/* Malformed or other error. */
|
||||
goto free_bns;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
|
||||
free_bns:
|
||||
BN_free(&r);
|
||||
BN_free(&s);
|
||||
|
||||
out:
|
||||
EC_KEY_free(eckey);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool check_tx_sig(struct bitcoin_tx *tx, size_t input_num,
|
||||
const u8 *redeemscript, size_t redeemscript_len,
|
||||
const struct pubkey *key,
|
||||
const struct bitcoin_signature *sig)
|
||||
{
|
||||
struct sha256_double hash;
|
||||
bool ret;
|
||||
|
||||
assert(input_num < tx->input_count);
|
||||
|
||||
sha256_tx_one_input(tx, input_num, redeemscript, redeemscript_len,
|
||||
&hash);
|
||||
|
||||
/* We only use SIGHASH_ALL for the moment. */
|
||||
if (sig->stype != SIGHASH_ALL)
|
||||
return false;
|
||||
|
||||
ret = check_signed_hash(&hash, &sig->sig, key);
|
||||
if (!ret)
|
||||
dump_tx("Sig failed", tx, input_num,
|
||||
redeemscript, redeemscript_len, key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool check_2of2_sig(struct bitcoin_tx *tx, size_t input_num,
|
||||
const u8 *redeemscript, size_t redeemscript_len,
|
||||
const struct pubkey *key1, const struct pubkey *key2,
|
||||
const struct bitcoin_signature *sig1,
|
||||
const struct bitcoin_signature *sig2)
|
||||
{
|
||||
struct sha256_double hash;
|
||||
assert(input_num < tx->input_count);
|
||||
|
||||
sha256_tx_one_input(tx, input_num, redeemscript, redeemscript_len,
|
||||
&hash);
|
||||
|
||||
/* We only use SIGHASH_ALL for the moment. */
|
||||
if (sig1->stype != SIGHASH_ALL || sig2->stype != SIGHASH_ALL)
|
||||
return false;
|
||||
|
||||
return check_signed_hash(&hash, &sig1->sig, key1)
|
||||
&& check_signed_hash(&hash, &sig2->sig, key2);
|
||||
}
|
||||
|
||||
Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig)
|
||||
{
|
||||
Signature *pb = tal(ctx, Signature);
|
||||
signature__init(pb);
|
||||
|
||||
assert((sig->s[31] & 1) == 0);
|
||||
|
||||
/* Kill me now... */
|
||||
memcpy(&pb->r1, sig->r, 8);
|
||||
memcpy(&pb->r2, sig->r + 8, 8);
|
||||
memcpy(&pb->r3, sig->r + 16, 8);
|
||||
memcpy(&pb->r4, sig->r + 24, 8);
|
||||
memcpy(&pb->s1, sig->s, 8);
|
||||
memcpy(&pb->s2, sig->s + 8, 8);
|
||||
memcpy(&pb->s3, sig->s + 16, 8);
|
||||
memcpy(&pb->s4, sig->s + 24, 8);
|
||||
|
||||
return pb;
|
||||
}
|
||||
|
||||
bool proto_to_signature(const Signature *pb, struct signature *sig)
|
||||
{
|
||||
/* Kill me again. */
|
||||
memcpy(sig->r, &pb->r1, 8);
|
||||
memcpy(sig->r + 8, &pb->r2, 8);
|
||||
memcpy(sig->r + 16, &pb->r3, 8);
|
||||
memcpy(sig->r + 24, &pb->r4, 8);
|
||||
memcpy(sig->s, &pb->s1, 8);
|
||||
memcpy(sig->s + 8, &pb->s2, 8);
|
||||
memcpy(sig->s + 16, &pb->s3, 8);
|
||||
memcpy(sig->s + 24, &pb->s4, 8);
|
||||
|
||||
/* S must be even */
|
||||
return (sig->s[31] & 1) == 0;
|
||||
}
|
||||
|
||||
54
bitcoin/signature.h
Normal file
54
bitcoin/signature.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef LIGHTNING_BITCOIN_SIGNATURE_H
|
||||
#define LIGHTNING_BITCOIN_SIGNATURE_H
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include "../lightning.pb-c.h"
|
||||
|
||||
enum sighash_type {
|
||||
SIGHASH_ALL = 1,
|
||||
SIGHASH_NONE = 2,
|
||||
SIGHASH_SINGLE = 3,
|
||||
SIGHASH_ANYONECANPAY = 0x80
|
||||
};
|
||||
|
||||
/* ECDSA of double SHA256. */
|
||||
struct signature {
|
||||
u8 r[32];
|
||||
u8 s[32];
|
||||
};
|
||||
|
||||
struct sha256_double;
|
||||
struct bitcoin_tx;
|
||||
struct pubkey;
|
||||
struct bitcoin_tx_output;
|
||||
struct bitcoin_signature;
|
||||
|
||||
bool sign_hash(const tal_t *ctx, EC_KEY *private_key,
|
||||
const struct sha256_double *h,
|
||||
struct signature *s);
|
||||
|
||||
/* All tx input scripts must be set to 0 len. */
|
||||
bool sign_tx_input(const tal_t *ctx, struct bitcoin_tx *tx,
|
||||
unsigned int in,
|
||||
const u8 *subscript, size_t subscript_len,
|
||||
EC_KEY *privkey, const struct pubkey *pubkey,
|
||||
struct signature *sig);
|
||||
|
||||
/* Does this sig sign the tx with this input for this pubkey. */
|
||||
bool check_tx_sig(struct bitcoin_tx *tx, size_t input_num,
|
||||
const u8 *redeemscript, size_t redeemscript_len,
|
||||
const struct pubkey *key,
|
||||
const struct bitcoin_signature *sig);
|
||||
|
||||
bool check_2of2_sig(struct bitcoin_tx *tx, size_t input_num,
|
||||
const u8 *redeemscript, size_t redeemscript_len,
|
||||
const struct pubkey *key1, const struct pubkey *key2,
|
||||
const struct bitcoin_signature *sig1,
|
||||
const struct bitcoin_signature *sig2);
|
||||
|
||||
/* Convert to-from protobuf to internal representation. */
|
||||
Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig);
|
||||
bool proto_to_signature(const Signature *pb, struct signature *sig);
|
||||
|
||||
#endif /* LIGHTNING_BITCOIN_SIGNATURE_H */
|
||||
315
bitcoin/tx.c
Normal file
315
bitcoin/tx.c
Normal file
@@ -0,0 +1,315 @@
|
||||
#include "tx.h"
|
||||
#include <ccan/crypto/sha256/sha256.h>
|
||||
#include <ccan/err/err.h>
|
||||
#include <ccan/tal/grab_file/grab_file.h>
|
||||
#include <ccan/str/hex/hex.h>
|
||||
#include <ccan/endian/endian.h>
|
||||
#include <assert.h>
|
||||
|
||||
static void add_varint(varint_t v,
|
||||
void (*add)(const void *, size_t, void *), void *addp)
|
||||
{
|
||||
u8 buf[9], *p = buf;
|
||||
|
||||
if (v < 0xfd) {
|
||||
*(p++) = v;
|
||||
} else if (v <= 0xffff) {
|
||||
(*p++) = 0xfd;
|
||||
(*p++) = v;
|
||||
(*p++) = v >> 8;
|
||||
} else if (v <= 0xffffffff) {
|
||||
(*p++) = 0xfe;
|
||||
(*p++) = v;
|
||||
(*p++) = v >> 8;
|
||||
(*p++) = v >> 16;
|
||||
(*p++) = v >> 24;
|
||||
} else {
|
||||
(*p++) = 0xff;
|
||||
(*p++) = v;
|
||||
(*p++) = v >> 8;
|
||||
(*p++) = v >> 16;
|
||||
(*p++) = v >> 24;
|
||||
(*p++) = v >> 32;
|
||||
(*p++) = v >> 40;
|
||||
(*p++) = v >> 48;
|
||||
(*p++) = v >> 56;
|
||||
}
|
||||
add(buf, p - buf, addp);
|
||||
}
|
||||
|
||||
static void add_le32(u32 v,
|
||||
void (*add)(const void *, size_t, void *), void *addp)
|
||||
{
|
||||
le32 l = cpu_to_le32(v);
|
||||
add(&l, sizeof(l), addp);
|
||||
}
|
||||
|
||||
static void add_le64(u64 v,
|
||||
void (*add)(const void *, size_t, void *), void *addp)
|
||||
{
|
||||
le64 l = cpu_to_le64(v);
|
||||
add(&l, sizeof(l), addp);
|
||||
}
|
||||
|
||||
static void add_tx_input(const struct bitcoin_tx_input *input,
|
||||
void (*add)(const void *, size_t, void *), void *addp)
|
||||
{
|
||||
add(&input->txid, sizeof(input->txid), addp);
|
||||
add_le32(input->index, add, addp);
|
||||
add_varint(input->script_length, add, addp);
|
||||
add(input->script, input->script_length, addp);
|
||||
add_le32(input->sequence_number, add, addp);
|
||||
}
|
||||
|
||||
static void add_tx_output(const struct bitcoin_tx_output *output,
|
||||
void (*add)(const void *, size_t, void *), void *addp)
|
||||
{
|
||||
add_le64(output->amount, add, addp);
|
||||
add_varint(output->script_length, add, addp);
|
||||
add(output->script, output->script_length, addp);
|
||||
}
|
||||
|
||||
static void add_tx(const struct bitcoin_tx *tx,
|
||||
void (*add)(const void *, size_t, void *), void *addp)
|
||||
{
|
||||
varint_t i;
|
||||
|
||||
add_le32(tx->version, add, addp);
|
||||
add_varint(tx->input_count, add, addp);
|
||||
for (i = 0; i < tx->input_count; i++)
|
||||
add_tx_input(&tx->input[i], add, addp);
|
||||
add_varint(tx->output_count, add, addp);
|
||||
for (i = 0; i < tx->output_count; i++)
|
||||
add_tx_output(&tx->output[i], add, addp);
|
||||
add_le32(tx->lock_time, add, addp);
|
||||
}
|
||||
|
||||
static void add_sha(const void *data, size_t len, void *shactx_)
|
||||
{
|
||||
struct sha256_ctx *ctx = shactx_;
|
||||
sha256_update(ctx, data, len);
|
||||
}
|
||||
|
||||
void sha256_tx(struct sha256_ctx *ctx, const struct bitcoin_tx *tx)
|
||||
{
|
||||
add_tx(tx, add_sha, ctx);
|
||||
}
|
||||
|
||||
static void add_linearize(const void *data, size_t len, void *pptr_)
|
||||
{
|
||||
u8 **pptr = pptr_;
|
||||
size_t oldsize = tal_count(*pptr);
|
||||
|
||||
tal_resize(pptr, oldsize + len);
|
||||
memcpy(*pptr + oldsize, data, len);
|
||||
}
|
||||
|
||||
u8 *linearize_tx(const tal_t *ctx, const struct bitcoin_tx *tx)
|
||||
{
|
||||
u8 *arr = tal_arr(ctx, u8, 0);
|
||||
add_tx(tx, add_linearize, &arr);
|
||||
return arr;
|
||||
}
|
||||
|
||||
void bitcoin_txid(const struct bitcoin_tx *tx, struct sha256_double *txid)
|
||||
{
|
||||
struct sha256_ctx ctx = SHA256_INIT;
|
||||
|
||||
sha256_tx(&ctx, tx);
|
||||
sha256_double_done(&ctx, txid);
|
||||
}
|
||||
|
||||
struct bitcoin_tx *bitcoin_tx(const tal_t *ctx, varint_t input_count,
|
||||
varint_t output_count)
|
||||
{
|
||||
struct bitcoin_tx *tx = tal(ctx, struct bitcoin_tx);
|
||||
size_t i;
|
||||
|
||||
tx->version = BITCOIN_TX_VERSION;
|
||||
tx->output_count = output_count;
|
||||
tx->output = tal_arrz(tx, struct bitcoin_tx_output, output_count);
|
||||
tx->input_count = input_count;
|
||||
tx->input = tal_arrz(tx, struct bitcoin_tx_input, input_count);
|
||||
for (i = 0; i < tx->input_count; i++) {
|
||||
/* We assume NULL is a zero bitmap */
|
||||
assert(tx->input[i].script == NULL);
|
||||
tx->input[i].sequence_number = 0xFFFFFFFF;
|
||||
}
|
||||
tx->lock_time = 0xFFFFFFFF;
|
||||
|
||||
return tx;
|
||||
}
|
||||
|
||||
/* Sets *cursor to NULL and returns NULL when a pull fails. */
|
||||
static const u8 *pull(const u8 **cursor, size_t *max, void *copy, size_t n)
|
||||
{
|
||||
const u8 *p = *cursor;
|
||||
|
||||
if (*max < n) {
|
||||
*cursor = NULL;
|
||||
*max = 0;
|
||||
/* Just make sure we don't leak uninitialized mem! */
|
||||
if (copy)
|
||||
memset(copy, 0, n);
|
||||
return NULL;
|
||||
}
|
||||
*cursor += n;
|
||||
*max -= n;
|
||||
if (copy)
|
||||
memcpy(copy, p, n);
|
||||
return p;
|
||||
}
|
||||
|
||||
static u64 pull_varint(const u8 **cursor, size_t *max)
|
||||
{
|
||||
u64 ret;
|
||||
const u8 *p;
|
||||
|
||||
p = pull(cursor, max, NULL, 1);
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
if (*p < 0xfd) {
|
||||
ret = *p;
|
||||
} else if (*p == 0xfd) {
|
||||
p = pull(cursor, max, NULL, 2);
|
||||
if (!p)
|
||||
return 0;
|
||||
ret = ((u64)p[1] << 8) + p[0];
|
||||
} else if (*p == 0xfe) {
|
||||
p = pull(cursor, max, NULL, 4);
|
||||
if (!p)
|
||||
return 0;
|
||||
ret = ((u64)p[3] << 24) + ((u64)p[2] << 16)
|
||||
+ ((u64)p[1] << 8) + p[0];
|
||||
} else {
|
||||
p = pull(cursor, max, NULL, 8);
|
||||
if (!p)
|
||||
return 0;
|
||||
ret = ((u64)p[7] << 56) + ((u64)p[6] << 48)
|
||||
+ ((u64)p[5] << 40) + ((u64)p[4] << 32)
|
||||
+ ((u64)p[3] << 24) + ((u64)p[2] << 16)
|
||||
+ ((u64)p[1] << 8) + p[0];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 pull_le32(const u8 **cursor, size_t *max)
|
||||
{
|
||||
le32 ret;
|
||||
|
||||
if (!pull(cursor, max, &ret, sizeof(ret)))
|
||||
return 0;
|
||||
return le32_to_cpu(ret);
|
||||
}
|
||||
|
||||
static u64 pull_le64(const u8 **cursor, size_t *max)
|
||||
{
|
||||
le64 ret;
|
||||
|
||||
if (!pull(cursor, max, &ret, sizeof(ret)))
|
||||
return 0;
|
||||
return le64_to_cpu(ret);
|
||||
}
|
||||
|
||||
static bool pull_sha256_double(const u8 **cursor, size_t *max,
|
||||
struct sha256_double *h)
|
||||
{
|
||||
return pull(cursor, max, h, sizeof(*h));
|
||||
}
|
||||
|
||||
static void pull_input(const tal_t *ctx, const u8 **cursor, size_t *max,
|
||||
struct bitcoin_tx_input *input)
|
||||
{
|
||||
pull_sha256_double(cursor, max, &input->txid);
|
||||
input->index = pull_le32(cursor, max);
|
||||
input->script_length = pull_varint(cursor, max);
|
||||
input->script = tal_arr(ctx, u8, input->script_length);
|
||||
pull(cursor, max, input->script, input->script_length);
|
||||
input->sequence_number = pull_le32(cursor, max);
|
||||
}
|
||||
|
||||
static void pull_output(const tal_t *ctx, const u8 **cursor, size_t *max,
|
||||
struct bitcoin_tx_output *output)
|
||||
{
|
||||
output->amount = pull_le64(cursor, max);
|
||||
output->script_length = pull_varint(cursor, max);
|
||||
output->script = tal_arr(ctx, u8, output->script_length);
|
||||
pull(cursor, max, output->script, output->script_length);
|
||||
}
|
||||
|
||||
static struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx,
|
||||
const u8 **cursor, size_t *max)
|
||||
{
|
||||
struct bitcoin_tx *tx = tal(ctx, struct bitcoin_tx);
|
||||
size_t i;
|
||||
|
||||
tx->version = pull_le32(cursor, max);
|
||||
tx->input_count = pull_varint(cursor, max);
|
||||
tx->input = tal_arr(tx, struct bitcoin_tx_input, tx->input_count);
|
||||
for (i = 0; i < tx->input_count; i++)
|
||||
pull_input(tx, cursor, max, tx->input + i);
|
||||
tx->output_count = pull_varint(cursor, max);
|
||||
tx->output = tal_arr(ctx, struct bitcoin_tx_output, tx->output_count);
|
||||
for (i = 0; i < tx->output_count; i++)
|
||||
pull_output(tx, cursor, max, tx->output + i);
|
||||
tx->lock_time = pull_le32(cursor, max);
|
||||
|
||||
/* If we ran short, or have bytes left over, fail. */
|
||||
if (!*cursor || *max != 0)
|
||||
tx = tal_free(tx);
|
||||
return tx;
|
||||
}
|
||||
|
||||
struct bitcoin_tx *bitcoin_tx_from_file(const tal_t *ctx,
|
||||
const char *filename)
|
||||
{
|
||||
char *hex;
|
||||
u8 *linear_tx;
|
||||
const u8 *p;
|
||||
struct bitcoin_tx *tx;
|
||||
size_t len;
|
||||
|
||||
/* Grabs file, add nul at end. */
|
||||
hex = grab_file(ctx, filename);
|
||||
if (!hex)
|
||||
err(1, "Opening %s", filename);
|
||||
|
||||
if (strends(hex, "\n"))
|
||||
hex[strlen(hex)-1] = '\0';
|
||||
len = hex_data_size(strlen(hex));
|
||||
p = linear_tx = tal_arr(hex, u8, len);
|
||||
if (!hex_decode(hex, strlen(hex), linear_tx, len))
|
||||
errx(1, "Bad hex string in %s", filename);
|
||||
|
||||
tx = pull_bitcoin_tx(ctx, &p, &len);
|
||||
if (!tx)
|
||||
errx(1, "Bad transaction in %s", filename);
|
||||
tal_free(hex);
|
||||
|
||||
return tx;
|
||||
}
|
||||
|
||||
/* <sigh>. Bitcoind represents hashes as little-endian for RPC. This didn't
|
||||
* stick for blockids (everyone else uses big-endian, eg. block explorers),
|
||||
* but it did stick for txids. */
|
||||
static void reverse_bytes(u8 *arr, size_t len)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len / 2; i++) {
|
||||
unsigned char tmp = arr[i];
|
||||
arr[i] = arr[len - 1 - i];
|
||||
arr[len - 1 - i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
bool bitcoin_txid_from_hex(const char *hexstr, size_t hexstr_len,
|
||||
struct sha256_double *txid)
|
||||
{
|
||||
if (!hex_decode(hexstr, hexstr_len, txid, sizeof(*txid)))
|
||||
return false;
|
||||
reverse_bytes(txid->sha.u.u8, sizeof(txid->sha.u.u8));
|
||||
return true;
|
||||
}
|
||||
|
||||
57
bitcoin/tx.h
Normal file
57
bitcoin/tx.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifndef LIGHTNING_BITCOIN_TX_H
|
||||
#define LIGHTNING_BITCOIN_TX_H
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include "shadouble.h"
|
||||
|
||||
#define BITCOIN_TX_VERSION 1
|
||||
|
||||
/* We unpack varints for our in-memory representation */
|
||||
#define varint_t u64
|
||||
|
||||
struct bitcoin_tx {
|
||||
u32 version;
|
||||
varint_t input_count;
|
||||
struct bitcoin_tx_input *input;
|
||||
varint_t output_count;
|
||||
struct bitcoin_tx_output *output;
|
||||
u32 lock_time;
|
||||
};
|
||||
|
||||
struct bitcoin_tx_output {
|
||||
u64 amount;
|
||||
varint_t script_length;
|
||||
u8 *script;
|
||||
};
|
||||
|
||||
struct bitcoin_tx_input {
|
||||
struct sha256_double txid;
|
||||
u32 index; /* output number referred to by above */
|
||||
varint_t script_length;
|
||||
u8 *script;
|
||||
u32 sequence_number;
|
||||
};
|
||||
|
||||
|
||||
/* SHA256^2 the tx: simpler than sha256_tx */
|
||||
void bitcoin_txid(const struct bitcoin_tx *tx, struct sha256_double *txid);
|
||||
|
||||
/* Useful for signature code. */
|
||||
void sha256_tx(struct sha256_ctx *ctx, const struct bitcoin_tx *tx);
|
||||
|
||||
/* Linear bytes of tx. */
|
||||
u8 *linearize_tx(const tal_t *ctx, const struct bitcoin_tx *tx);
|
||||
|
||||
/* Allocate a tx: you just need to fill in inputs and outputs (they're
|
||||
* zeroed with inputs' sequence_number set to FFFFFFFF) */
|
||||
struct bitcoin_tx *bitcoin_tx(const tal_t *ctx, varint_t input_count,
|
||||
varint_t output_count);
|
||||
|
||||
struct bitcoin_tx *bitcoin_tx_from_file(const tal_t *ctx,
|
||||
const char *filename);
|
||||
|
||||
/* Parse hex string to get txid (reversed, a-la bitcoind). */
|
||||
bool bitcoin_txid_from_hex(const char *hexstr, size_t hexstr_len,
|
||||
struct sha256_double *txid);
|
||||
|
||||
#endif /* LIGHTNING_BITCOIN_TX_H */
|
||||
Reference in New Issue
Block a user