diff --git a/src/script/error.rs b/src/script/error.rs index cb00b206..2d8cc7ac 100644 --- a/src/script/error.rs +++ b/src/script/error.rs @@ -14,6 +14,7 @@ pub enum Error { // BIP62 SignatureHashtype, SignatureDer, + Minimaldata, SignatureHighS, PubkeyType, } @@ -32,6 +33,7 @@ impl fmt::Display for Error { // BIP62 Error::SignatureHashtype => "Invalid Signature Hashtype".fmt(f), Error::SignatureDer => "Invalid Signature".fmt(f), + Error::Minimaldata => "Check minimaldata failed".fmt(f), Error::SignatureHighS => "Invalid High S in Signature".fmt(f), Error::PubkeyType => "Invalid Pubkey".fmt(f), } diff --git a/src/script/interpreter.rs b/src/script/interpreter.rs index 52f16803..9675e708 100644 --- a/src/script/interpreter.rs +++ b/src/script/interpreter.rs @@ -206,9 +206,9 @@ fn check_minimal_push(data: &[u8], opcode: Opcode) -> bool { } pub fn eval_script( - _stack: &mut Vec>, + stack: &mut Vec>, script: &Script, - _flags: &VerificationFlags, + flags: &VerificationFlags, _checker: &SignatureChecker, _version: SignatureVersion ) -> Result { @@ -218,9 +218,15 @@ pub fn eval_script( for i in script.into_iter() { match try!(i) { - Instruction::PushValue(_opcode, _num) => { + Instruction::PushValue(_opcode, num) => { + stack.push(num.to_vec()); }, - Instruction::PushBytes(_opcode, _bytes) => { + Instruction::PushBytes(opcode, bytes) => { + // TODO: if fExec + if flags.verify_minimaldata && !check_minimal_push(bytes, opcode) { + return Err(Error::Minimaldata); + } + stack.push(bytes.to_vec()); }, Instruction::Normal(_opcode) => { }, diff --git a/src/script/num.rs b/src/script/num.rs index 81f13718..7826101a 100644 --- a/src/script/num.rs +++ b/src/script/num.rs @@ -26,3 +26,45 @@ impl From for Num { } } } + +impl Num { + pub fn to_vec(&self) -> Vec { + if self.value == 0 { + return vec![]; + } + + let mut result = vec![]; + let negative = self.value < 0; + let mut absvalue = match negative { + true => (-self.value) as u64, + false => self.value as u64, + }; + + while absvalue > 0 { + result.push(absvalue as u8 & 0xff); + absvalue >>= 8; + } + + // - If the most significant byte is >= 0x80 and the value is positive, push a + // new zero-byte to make the significant byte < 0x80 again. + + // - If the most significant byte is >= 0x80 and the value is negative, push a + // new 0x80 byte that will be popped off when converting to an integral. + + // - If the most significant byte is < 0x80 and the value is negative, add + // 0x80 to it, since it will be subtracted and interpreted as a negative when + // converting to an integral. + + if result[result.len() - 1] & 0x80 != 0 { + match negative { + true => result.push(0x80), + false => result.push(0), + } + } else if negative { + let rlen = result.len(); + result[rlen - 1] |= 0x80; + } + + result + } +}