bitcoin_script_analyzer/util/checksig.rs
1pub const SIGHASH_DEFAULT: u8 = 0;
2pub const SIGHASH_ALL: u8 = 1;
3pub const SIGHASH_NONE: u8 = 2;
4pub const SIGHASH_SINGLE: u8 = 3;
5pub const SIGHASH_ANYONECANPAY: u8 = 128;
6
7/// hash types that can appear at the end of a signature (SIGHASH_DEFAULT can't)
8pub const SIG_HASH_TYPES: [u8; 6] = [
9 SIGHASH_ALL,
10 SIGHASH_NONE,
11 SIGHASH_SINGLE,
12 SIGHASH_ALL | SIGHASH_ANYONECANPAY,
13 SIGHASH_NONE | SIGHASH_ANYONECANPAY,
14 SIGHASH_SINGLE | SIGHASH_ANYONECANPAY,
15];
16
17pub enum PubKeyCheckResult {
18 Invalid,
19 Valid { compressed: bool },
20}
21
22pub fn check_pub_key(pub_key: &[u8]) -> PubKeyCheckResult {
23 if pub_key.len() == 33 && (pub_key[0] == 0x02 || pub_key[0] == 0x03) {
24 PubKeyCheckResult::Valid { compressed: true }
25 } else if pub_key.len() == 65 && pub_key[0] == 0x04 {
26 PubKeyCheckResult::Valid { compressed: false }
27 } else {
28 PubKeyCheckResult::Invalid
29 }
30}
31
32// The following function was copied from the Bitcoin Core source code, src/script/interpreter (lines 97-170) at b92d609fb25637ccda000e182da854d4b762eee9
33// Edited for use in this software
34
35// Orignal Bitcoin Core copyright header:
36// Copyright (c) 2009-2010 Satoshi Nakamoto
37// Copyright (c) 2009-2022 The Bitcoin Core developers
38// Distributed under the MIT software license, see the accompanying
39// file COPYING or http://www.opensource.org/licenses/mit-license.php.
40
41/// A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
42/// Where R and S are not negative (their first byte has its highest bit not set), and not
43/// excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
44/// in which case a single 0 byte is necessary and even required).
45///
46/// See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
47///
48/// This function is consensus-critical since BIP66.
49pub fn is_valid_signature_encoding(sig: &[u8]) -> bool {
50 // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash]
51 // * total-length: 1-byte length descriptor of everything that follows,
52 // excluding the sighash byte.
53 // * R-length: 1-byte length descriptor of the R value that follows.
54 // * R: arbitrary-length big-endian encoded R value. It must use the shortest
55 // possible encoding for a positive integer (which means no null bytes at
56 // the start, except a single one when the next byte has its highest bit set).
57 // * S-length: 1-byte length descriptor of the S value that follows.
58 // * S: arbitrary-length big-endian encoded S value. The same rules apply.
59 // * sighash: 1-byte value indicating what data is hashed (not part of the DER
60 // signature)
61
62 // Minimum and maximum size constraints.
63 if sig.len() < 9 {
64 return false;
65 }
66 if sig.len() > 73 {
67 return false;
68 }
69
70 // A signature is of type 0x30 (compound).
71 if sig[0] != 0x30 {
72 return false;
73 }
74
75 // Make sure the length covers the entire signature.
76 if sig[1] != sig.len() as u8 - 3 {
77 return false;
78 }
79
80 // Extract the length of the R element.
81 let len_r = sig[3] as usize;
82
83 // Make sure the length of the S element is still inside the signature.
84 if 5 + len_r >= sig.len() {
85 return false;
86 }
87
88 // Extract the length of the S element.
89 let len_s = sig[5 + len_r] as usize;
90
91 // Verify that the length of the signature matches the sum of the length
92 // of the elements.
93 if len_r + len_s + 7 != sig.len() {
94 return false;
95 }
96
97 // Check whether the R element is an integer.
98 if sig[2] != 0x02 {
99 return false;
100 }
101
102 // Zero-length integers are not allowed for R.
103 if len_r == 0 {
104 return false;
105 }
106
107 // Negative numbers are not allowed for R.
108 if (sig[4] & 0x80) != 0 {
109 return false;
110 }
111
112 // Null bytes at the start of R are not allowed, unless R would
113 // otherwise be interpreted as a negative number.
114 if len_r > 1 && sig[4] == 0x00 && (sig[5] & 0x80) == 0 {
115 return false;
116 }
117
118 // Check whether the S element is an integer.
119 if sig[len_r + 4] != 0x02 {
120 return false;
121 }
122
123 // Zero-length integers are not allowed for S.
124 if len_s == 0 {
125 return false;
126 }
127
128 // Negative numbers are not allowed for S.
129 if (sig[len_r + 6] & 0x80) != 0 {
130 return false;
131 }
132
133 // Null bytes at the start of S are not allowed, unless S would otherwise be
134 // interpreted as a negative number.
135 if len_s > 1 && sig[len_r + 6] == 0x00 && (sig[len_r + 7] & 0x80) == 0 {
136 return false;
137 }
138
139 true
140}