Newer
Older
use transaction::{Transaction, SEQUENCE_LOCKTIME_DISABLE_FLAG};
use crypto::{sha1, sha256, dhash160, dhash256, ripemd160};
use script::{script, Script, Num, VerificationFlags, Opcode, Error, read_usize};
#[derive(Debug, PartialEq, Clone, Copy)]
#[repr(u8)]
impl From<SighashBase> for u32 {
fn from(s: SighashBase) -> Self {
s as u32
}
}
/// Documentation
/// https://en.bitcoin.it/wiki/OP_CHECKSIG#Procedure_for_Hashtype_SIGHASH_SINGLE
/// TODO: Possibly handle other integers when deserialing
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Sighash {
pub base: SighashBase,
pub anyone_can_pay: bool,
match s.anyone_can_pay {
true => base | 0x80,
false => base,
}
}
}
impl From<u32> for Sighash {
fn from(u: u32) -> Self {
// use 0x9f istead of 0x1f to catch 0x80
match u & 0x9f {
1 => Sighash::new(SighashBase::All, false),
2 => Sighash::new(SighashBase::None, false),
3 => Sighash::new(SighashBase::Single, false),
0x81 => Sighash::new(SighashBase::All, true),
0x82 => Sighash::new(SighashBase::None, true),
0x83 => Sighash::new(SighashBase::Single, true),
x if x & 0x80 == 0x80 => Sighash::new(SighashBase::All, true),
// 0 is handled like all...
_ => Sighash::new(SighashBase::All, false),
}
}
}
pub fn new(base: SighashBase, anyone_can_pay: bool) -> Self {
Sighash {
base: base,
anyone_can_pay: anyone_can_pay,
}
}
pub fn from_u32(u: u32) -> Option<Self> {
// use 0x9f istead of 0x1f to catch 0x80
let (base, anyone_can_pay) = match u & 0x9f {
1 => (SighashBase::All, false),
2 => (SighashBase::None, false),
3 => (SighashBase::Single, false),
0x81 => (SighashBase::All, true),
0x82 => (SighashBase::None, true),
0x83 => (SighashBase::Single, true),
x if x & 0x80 == 0x80 => (SighashBase::All, true),
Some(Sighash::new(base, anyone_can_pay))
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum SignatureVersion {
fn check_signature(
&self,
script_signature: &[u8],
script: &Script,
version: SignatureVersion
) -> bool;
fn check_lock_time(&self, lock_time: Num) -> bool;
fn check_sequence(&self, sequence: Num) -> bool;
}
pub struct NoopSignatureChecker;
impl SignatureChecker for NoopSignatureChecker {
fn check_signature(&self, _: &[u8], _: &[u8], _: &Script, _: SignatureVersion) -> bool {
false
}
fn check_lock_time(&self, _: Num) -> bool {
false
}
fn check_sequence(&self, _: Num) -> bool {
false
}
}
pub struct TransactionSignatureChecker {
transaction: Transaction,
i: u32,
amount: i64,
}
impl TransactionSignatureChecker {
fn verify_signature(&self, _signature: &[u8], _public: &[u8], _hash: &H256) -> bool {
unimplemented!();
}
}
impl SignatureChecker for TransactionSignatureChecker {
fn check_signature(
&self,
_script: &Script,
_version: SignatureVersion
) -> bool {
let public = match Public::from_slice(public) {
Ok(public) => public,
_ => return false,
};
if script_signature.is_empty() {
return false;
}
let _hash_type = script_signature.last().unwrap();
unimplemented!();
}
fn check_lock_time(&self, _lock_time: Num) -> bool {
unimplemented!();
}
fn check_sequence(&self, _sequence: Num) -> bool {
unimplemented!();
}
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
fn is_public_key(v: &[u8]) -> bool {
match v.len() {
33 if v[0] == 2 || v[0] == 3 => true,
65 if v[0] == 4 => true,
_ => false,
}
}
/// A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
/// Where R and S are not negative (their first byte has its highest bit not set), and not
/// excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
/// in which case a single 0 byte is necessary and even required).
///
/// See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
///
/// This function is consensus-critical since BIP66.
fn is_valid_signature_encoding(sig: &[u8]) -> bool {
// 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 sig.len() < 9 || sig.len() > 73 {
return false;
}
// A signature is of type 0x30 (compound)
if sig[0] != 0x30 {
return false;
}
Loading full blame...