mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
Move DER encoding into bitcoin/signature.c
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
20624c049f
commit
fbe63124f6
111
bitcoin/script.c
111
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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user