diff --git a/bitcoin/script.c b/bitcoin/script.c index fca3189f2..37cb1c8f1 100644 --- a/bitcoin/script.c +++ b/bitcoin/script.c @@ -85,121 +85,14 @@ 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; + u8 der[73]; + size_t len = signature_to_der(der, &sig->sig); /* Append sighash type */ der[len++] = sig->stype; - - assert(IsValidSignatureEncoding(der, len)); add_push_bytes(scriptp, der, len); } diff --git a/bitcoin/signature.c b/bitcoin/signature.c index 160be9500..0b5d4476a 100644 --- a/bitcoin/signature.c +++ b/bitcoin/signature.c @@ -238,3 +238,117 @@ bool check_2of2_sig(struct bitcoin_tx *tx, size_t input_num, return check_signed_hash(&hash, &sig1->sig, key1) && check_signed_hash(&hash, &sig2->sig, key2); } + +/* 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; +} + +size_t signature_to_der(u8 der[72], const struct signature *sig) +{ + size_t len = 0; + + der[len++] = 0x30; /* Type */ + der[len++] = 0; /* Total length after this: fill it at end. */ + + len += der_encode_val(sig->r, der + len); + len += der_encode_val(sig->s, der + len); + + /* Fix up total length */ + der[1] = len - 2; + + /* IsValidSignatureEncoding() expect extra byte for sighash */ + assert(IsValidSignatureEncoding(der, len + 1)); + return len; +} diff --git a/bitcoin/signature.h b/bitcoin/signature.h index 8d004f26d..dd52bd2fc 100644 --- a/bitcoin/signature.h +++ b/bitcoin/signature.h @@ -46,4 +46,7 @@ bool check_2of2_sig(struct bitcoin_tx *tx, size_t input_num, const struct bitcoin_signature *sig1, const struct bitcoin_signature *sig2); +/* Give DER encoding of signature: returns length used (<= 72). */ +size_t signature_to_der(u8 der[72], const struct signature *s); + #endif /* LIGHTNING_BITCOIN_SIGNATURE_H */