1use messages::Tx;
2use secp256k1::{Message, PublicKey, Secp256k1, Signature};
3use transaction::sighash::{sighash, SigHashCache, SIGHASH_FORKID};
4use util::{Amount, Error, Result};
5
6const LOCKTIME_THRESHOLD: i32 = 500000000;
8
9const SEQUENCE_LOCKTIME_DISABLE_FLAG: u32 = 1 << 31;
11const SEQUENCE_LOCKTIME_TYPE_FLAG: u32 = 1 << 22;
13
14pub trait Checker {
16 fn check_sig(&mut self, sig: &[u8], pubkey: &[u8], script: &[u8]) -> Result<bool>;
20
21 fn check_locktime(&self, locktime: i32) -> Result<bool>;
23
24 fn check_sequence(&self, sequence: i32) -> Result<bool>;
26}
27
28pub struct TransactionlessChecker {}
30
31impl Checker for TransactionlessChecker {
32 fn check_sig(&mut self, _sig: &[u8], _pubkey: &[u8], _script: &[u8]) -> Result<bool> {
33 Err(Error::IllegalState("Illegal transaction check".to_string()))
34 }
35
36 fn check_locktime(&self, _locktime: i32) -> Result<bool> {
37 Err(Error::IllegalState("Illegal transaction check".to_string()))
38 }
39
40 fn check_sequence(&self, _sequence: i32) -> Result<bool> {
41 Err(Error::IllegalState("Illegal transaction check".to_string()))
42 }
43}
44
45pub struct TransactionChecker<'a> {
47 pub tx: &'a Tx,
49 pub sig_hash_cache: &'a mut SigHashCache,
51 pub input: usize,
53 pub amount: Amount,
55 pub require_sighash_forkid: bool,
57}
58
59impl<'a> Checker for TransactionChecker<'a> {
60 fn check_sig(&mut self, sig: &[u8], pubkey: &[u8], script: &[u8]) -> Result<bool> {
61 if sig.len() < 1 {
62 return Err(Error::ScriptError("Signature too short".to_string()));
63 }
64 let sighash_type = sig[sig.len() - 1];
65 if self.require_sighash_forkid && sighash_type & SIGHASH_FORKID == 0 {
66 return Err(Error::ScriptError("SIGHASH_FORKID not present".to_string()));
67 }
68 let sig_hash = sighash(
69 self.tx,
70 self.input,
71 script,
72 self.amount,
73 sighash_type,
74 self.sig_hash_cache,
75 )?;
76 let der_sig = &sig[0..sig.len() - 1];
77 let secp = Secp256k1::verification_only();
78 let mut signature = Signature::from_der(der_sig)?;
79 signature.normalize_s();
81 let message = Message::from_slice(&sig_hash.0)?;
82 let public_key = PublicKey::from_slice(&pubkey)?;
83 Ok(secp.verify(&message, &signature, &public_key).is_ok())
84 }
85
86 fn check_locktime(&self, locktime: i32) -> Result<bool> {
87 if locktime < 0 {
88 return Err(Error::ScriptError("locktime negative".to_string()));
89 }
90 if (locktime >= LOCKTIME_THRESHOLD && (self.tx.lock_time as i32) < LOCKTIME_THRESHOLD)
91 || (locktime < LOCKTIME_THRESHOLD && (self.tx.lock_time as i32) >= LOCKTIME_THRESHOLD)
92 {
93 return Err(Error::ScriptError("locktime types different".to_string()));
94 }
95 if locktime > self.tx.lock_time as i32 {
96 return Err(Error::ScriptError("locktime greater than tx".to_string()));
97 }
98 if self.tx.inputs[self.input].sequence == 0xffffffff {
99 return Err(Error::ScriptError("sequence is 0xffffffff".to_string()));
100 }
101 Ok(true)
102 }
103
104 fn check_sequence(&self, sequence: i32) -> Result<bool> {
105 if sequence < 0 {
106 return Err(Error::ScriptError("sequence negative".to_string()));
107 }
108 let sequence = sequence as u32;
109 if sequence & SEQUENCE_LOCKTIME_DISABLE_FLAG != 0 {
110 return Ok(true);
111 }
112 if self.tx.version < 2 {
113 return Err(Error::ScriptError("tx version less than 2".to_string()));
114 }
115 if self.tx.inputs[self.input].sequence & SEQUENCE_LOCKTIME_DISABLE_FLAG != 0 {
116 let msg = "tx sequence disable flag set".to_string();
117 return Err(Error::ScriptError(msg));
118 }
119 let sequence_masked = sequence & 0x0000ffff;
120 let tx_sequence_masked = self.tx.inputs[self.input].sequence & 0x0000ffff;
121 if (sequence_masked < SEQUENCE_LOCKTIME_TYPE_FLAG
122 && tx_sequence_masked >= SEQUENCE_LOCKTIME_TYPE_FLAG)
123 || (sequence_masked >= SEQUENCE_LOCKTIME_TYPE_FLAG
124 && sequence_masked < SEQUENCE_LOCKTIME_TYPE_FLAG)
125 {
126 let msg = "sequence types different".to_string();
127 return Err(Error::ScriptError(msg));
128 }
129 if sequence_masked > tx_sequence_masked {
130 let msg = "sequence greater than tx".to_string();
131 return Err(Error::ScriptError(msg));
132 }
133 Ok(true)
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140 use messages::{OutPoint, TxIn, TxOut};
141 use script::op_codes::*;
142 use script::Script;
143 use secp256k1::{PublicKey, Secp256k1, SecretKey};
144 use transaction::generate_signature;
145 use transaction::sighash::{
146 SIGHASH_ALL, SIGHASH_ANYONECANPAY, SIGHASH_FORKID, SIGHASH_NONE, SIGHASH_SINGLE,
147 };
148 use util::{hash160, Hash256};
149
150 #[test]
151 fn standard_p2pkh() {
152 standard_p2pkh_test(SIGHASH_ALL);
153 standard_p2pkh_test(SIGHASH_ALL | SIGHASH_FORKID);
154 }
155
156 fn standard_p2pkh_test(sighash_type: u8) {
157 let secp = Secp256k1::new();
158 let private_key = [1; 32];
159 let secret_key = SecretKey::from_slice(&private_key).unwrap();
160 let pk = PublicKey::from_secret_key(&secp, &secret_key).serialize();
161 let pkh = hash160(&pk);
162
163 let mut pk_script = Script::new();
164 pk_script.append(OP_DUP);
165 pk_script.append(OP_HASH160);
166 pk_script.append_data(&pkh.0);
167 pk_script.append(OP_EQUALVERIFY);
168 pk_script.append(OP_CHECKSIG);
169
170 let tx_1 = Tx {
171 version: 1,
172 inputs: vec![],
173 outputs: vec![TxOut {
174 amount: Amount(10),
175 pk_script,
176 }],
177 lock_time: 0,
178 };
179
180 let mut tx_2 = Tx {
181 version: 1,
182 inputs: vec![TxIn {
183 prev_output: OutPoint {
184 hash: tx_1.hash(),
185 index: 0,
186 },
187 sig_script: Script(vec![]),
188 sequence: 0xffffffff,
189 }],
190 outputs: vec![],
191 lock_time: 0,
192 };
193
194 let mut cache = SigHashCache::new();
195 let pk_script = &tx_1.outputs[0].pk_script.0;
196 let sig_hash = sighash(&tx_2, 0, pk_script, Amount(10), sighash_type, &mut cache).unwrap();
197 let sig = generate_signature(&private_key, &sig_hash, sighash_type).unwrap();
198
199 let mut sig_script = Script::new();
200 sig_script.append_data(&sig);
201 sig_script.append_data(&pk);
202 tx_2.inputs[0].sig_script = sig_script;
203
204 let mut cache = SigHashCache::new();
205 let mut c = TransactionChecker {
206 tx: &tx_2,
207 sig_hash_cache: &mut cache,
208 input: 0,
209 amount: Amount(10),
210 require_sighash_forkid: false,
211 };
212
213 let mut script = Script::new();
214 script.append_slice(&tx_2.inputs[0].sig_script.0);
215 script.append(OP_CODESEPARATOR);
216 script.append_slice(&tx_1.outputs[0].pk_script.0);
217 assert!(script.eval(&mut c).is_ok());
218 }
219
220 #[test]
221 fn multisig() {
222 multisig_test(SIGHASH_ALL);
223 multisig_test(SIGHASH_ALL | SIGHASH_FORKID);
224 }
225
226 fn multisig_test(sighash_type: u8) {
227 let secp = Secp256k1::new();
228 let private_key1 = [1; 32];
229 let private_key2 = [2; 32];
230 let private_key3 = [3; 32];
231 let secret_key1 = SecretKey::from_slice(&private_key1).unwrap();
232 let secret_key2 = SecretKey::from_slice(&private_key2).unwrap();
233 let secret_key3 = SecretKey::from_slice(&private_key3).unwrap();
234 let pk1 = PublicKey::from_secret_key(&secp, &secret_key1).serialize();
235 let pk2 = PublicKey::from_secret_key(&secp, &secret_key2).serialize();
236 let pk3 = PublicKey::from_secret_key(&secp, &secret_key3).serialize();
237
238 let mut pk_script = Script::new();
239 pk_script.append(OP_2);
240 pk_script.append_data(&pk1);
241 pk_script.append_data(&pk2);
242 pk_script.append_data(&pk3);
243 pk_script.append(OP_3);
244 pk_script.append(OP_CHECKMULTISIG);
245
246 let tx_1 = Tx {
247 version: 1,
248 inputs: vec![],
249 outputs: vec![TxOut {
250 amount: Amount(10),
251 pk_script,
252 }],
253 lock_time: 0,
254 };
255
256 let mut tx_2 = Tx {
257 version: 1,
258 inputs: vec![TxIn {
259 prev_output: OutPoint {
260 hash: tx_1.hash(),
261 index: 0,
262 },
263 sig_script: Script(vec![]),
264 sequence: 0xffffffff,
265 }],
266 outputs: vec![],
267 lock_time: 0,
268 };
269
270 let mut cache = SigHashCache::new();
271 let pk_script = &tx_1.outputs[0].pk_script.0;
272 let sig_hash = sighash(&tx_2, 0, pk_script, Amount(10), sighash_type, &mut cache).unwrap();
273 let sig1 = generate_signature(&private_key1, &sig_hash, sighash_type).unwrap();
274 let sig3 = generate_signature(&private_key3, &sig_hash, sighash_type).unwrap();
275
276 let mut sig_script = Script::new();
277 sig_script.append(OP_0);
278 sig_script.append_data(&sig1);
279 sig_script.append_data(&sig3);
280 tx_2.inputs[0].sig_script = sig_script;
281
282 let mut cache = SigHashCache::new();
283 let mut c = TransactionChecker {
284 tx: &tx_2,
285 sig_hash_cache: &mut cache,
286 input: 0,
287 amount: Amount(10),
288 require_sighash_forkid: false,
289 };
290
291 let mut script = Script::new();
292 script.append_slice(&tx_2.inputs[0].sig_script.0);
293 script.append(OP_CODESEPARATOR);
294 script.append_slice(&tx_1.outputs[0].pk_script.0);
295 assert!(script.eval(&mut c).is_ok());
296 }
297
298 #[test]
299 fn blank_check() {
300 blank_check_test(SIGHASH_NONE | SIGHASH_ANYONECANPAY);
301 blank_check_test(SIGHASH_NONE | SIGHASH_ANYONECANPAY | SIGHASH_FORKID);
302 }
303
304 fn blank_check_test(sighash_type: u8) {
305 let secp = Secp256k1::new();
306
307 let private_key1 = [1; 32];
308 let secret_key1 = SecretKey::from_slice(&private_key1).unwrap();
309 let pk1 = PublicKey::from_secret_key(&secp, &secret_key1).serialize();
310 let pkh1 = hash160(&pk1);
311
312 let private_key2 = [2; 32];
313 let secret_key2 = SecretKey::from_slice(&private_key2).unwrap();
314 let pk2 = PublicKey::from_secret_key(&secp, &secret_key2).serialize();
315 let pkh2 = hash160(&pk2);
316
317 let mut pk_script1 = Script::new();
318 pk_script1.append(OP_DUP);
319 pk_script1.append(OP_HASH160);
320 pk_script1.append_data(&pkh1.0);
321 pk_script1.append(OP_EQUALVERIFY);
322 pk_script1.append(OP_CHECKSIG);
323
324 let mut pk_script2 = Script::new();
325 pk_script2.append(OP_DUP);
326 pk_script2.append(OP_HASH160);
327 pk_script2.append_data(&pkh2.0);
328 pk_script2.append(OP_EQUALVERIFY);
329 pk_script2.append(OP_CHECKSIG);
330
331 let tx_1 = Tx {
332 version: 1,
333 inputs: vec![],
334 outputs: vec![
335 TxOut {
336 amount: Amount(10),
337 pk_script: pk_script1,
338 },
339 TxOut {
340 amount: Amount(20),
341 pk_script: pk_script2,
342 },
343 ],
344 lock_time: 0,
345 };
346
347 let mut tx_2 = Tx {
348 version: 1,
349 inputs: vec![TxIn {
350 prev_output: OutPoint {
351 hash: tx_1.hash(),
352 index: 0,
353 },
354 sig_script: Script(vec![]),
355 sequence: 0xffffffff,
356 }],
357 outputs: vec![],
358 lock_time: 0,
359 };
360
361 let mut cache = SigHashCache::new();
364 let pk_script = &tx_1.outputs[0].pk_script.0;
365 let sig_hash1 = sighash(&tx_2, 0, pk_script, Amount(10), sighash_type, &mut cache).unwrap();
366 let sig1 = generate_signature(&private_key1, &sig_hash1, sighash_type).unwrap();
367
368 let mut sig_script1 = Script::new();
369 sig_script1.append_data(&sig1);
370 sig_script1.append_data(&pk1);
371 tx_2.inputs[0].sig_script = sig_script1;
372
373 tx_2.inputs.push(TxIn {
376 prev_output: OutPoint {
377 hash: tx_1.hash(),
378 index: 1,
379 },
380 sig_script: Script(vec![]),
381 sequence: 0xffffffff,
382 });
383
384 let mut cache = SigHashCache::new();
385 let pk_script = &tx_1.outputs[1].pk_script.0;
386
387 let sig_hash2 = sighash(&tx_2, 1, pk_script, Amount(20), sighash_type, &mut cache).unwrap();
388 let sig2 = generate_signature(&private_key2, &sig_hash2, sighash_type).unwrap();
389
390 let mut sig_script2 = Script::new();
391 sig_script2.append_data(&sig2);
392 sig_script2.append_data(&pk2);
393 tx_2.inputs[1].sig_script = sig_script2;
394
395 let mut cache = SigHashCache::new();
396 let mut c1 = TransactionChecker {
397 tx: &tx_2,
398 sig_hash_cache: &mut cache,
399 input: 0,
400 amount: Amount(10),
401 require_sighash_forkid: false,
402 };
403
404 let mut script1 = Script::new();
405 script1.append_slice(&tx_2.inputs[0].sig_script.0);
406 script1.append(OP_CODESEPARATOR);
407 script1.append_slice(&tx_1.outputs[0].pk_script.0);
408 assert!(script1.eval(&mut c1).is_ok());
409
410 let mut cache = SigHashCache::new();
411 let mut c2 = TransactionChecker {
412 tx: &tx_2,
413 sig_hash_cache: &mut cache,
414 input: 1,
415 amount: Amount(20),
416 require_sighash_forkid: false,
417 };
418
419 let mut script2 = Script::new();
420 script2.append_slice(&tx_2.inputs[1].sig_script.0);
421 script2.append(OP_CODESEPARATOR);
422 script2.append_slice(&tx_1.outputs[1].pk_script.0);
423 assert!(script2.eval(&mut c2).is_ok());
424 }
425
426 #[test]
427 fn batch() {
428 batch_test(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY);
429 batch_test(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY | SIGHASH_FORKID);
430 }
431
432 fn batch_test(sighash_type: u8) {
433 let secp = Secp256k1::new();
434
435 let private_key1 = [1; 32];
436 let secret_key1 = SecretKey::from_slice(&private_key1).unwrap();
437 let pk1 = PublicKey::from_secret_key(&secp, &secret_key1).serialize();
438 let pkh1 = hash160(&pk1);
439
440 let private_key2 = [2; 32];
441 let secret_key2 = SecretKey::from_slice(&private_key2).unwrap();
442 let pk2 = PublicKey::from_secret_key(&secp, &secret_key2).serialize();
443 let pkh2 = hash160(&pk2);
444
445 let mut pk_script1 = Script::new();
446 pk_script1.append(OP_DUP);
447 pk_script1.append(OP_HASH160);
448 pk_script1.append_data(&pkh1.0);
449 pk_script1.append(OP_EQUALVERIFY);
450 pk_script1.append(OP_CHECKSIG);
451
452 let mut pk_script2 = Script::new();
453 pk_script2.append(OP_DUP);
454 pk_script2.append(OP_HASH160);
455 pk_script2.append_data(&pkh2.0);
456 pk_script2.append(OP_EQUALVERIFY);
457 pk_script2.append(OP_CHECKSIG);
458
459 let tx_1 = Tx {
460 version: 1,
461 inputs: vec![],
462 outputs: vec![
463 TxOut {
464 amount: Amount(10),
465 pk_script: pk_script1.clone(),
466 },
467 TxOut {
468 amount: Amount(20),
469 pk_script: pk_script2.clone(),
470 },
471 ],
472 lock_time: 0,
473 };
474
475 let mut tx_2 = Tx {
476 version: 1,
477 inputs: vec![TxIn {
478 prev_output: OutPoint {
479 hash: tx_1.hash(),
480 index: 0,
481 },
482 sig_script: Script(vec![]),
483 sequence: 0xffffffff,
484 }],
485 outputs: vec![TxOut {
486 amount: Amount(10),
487 pk_script: pk_script1.clone(),
488 }],
489 lock_time: 0,
490 };
491
492 let mut cache = SigHashCache::new();
495 let pk_script = &tx_1.outputs[0].pk_script.0;
496 let sig_hash1 = sighash(&tx_2, 0, pk_script, Amount(10), sighash_type, &mut cache).unwrap();
497 let sig1 = generate_signature(&private_key1, &sig_hash1, sighash_type).unwrap();
498
499 let mut sig_script1 = Script::new();
500 sig_script1.append_data(&sig1);
501 sig_script1.append_data(&pk1);
502 tx_2.inputs[0].sig_script = sig_script1;
503
504 tx_2.inputs.push(TxIn {
507 prev_output: OutPoint {
508 hash: tx_1.hash(),
509 index: 1,
510 },
511 sig_script: Script(vec![]),
512 sequence: 0xffffffff,
513 });
514 tx_2.outputs.push(TxOut {
515 amount: Amount(20),
516 pk_script: pk_script2.clone(),
517 });
518
519 let mut cache = SigHashCache::new();
520 let sig_hash2 = sighash(
521 &tx_2,
522 1,
523 &tx_1.outputs[1].pk_script.0,
524 Amount(20),
525 sighash_type,
526 &mut cache,
527 )
528 .unwrap();
529 let sig2 = generate_signature(&private_key2, &sig_hash2, sighash_type).unwrap();
530
531 let mut sig_script2 = Script::new();
532 sig_script2.append_data(&sig2);
533 sig_script2.append_data(&pk2);
534 tx_2.inputs[1].sig_script = sig_script2;
535
536 let mut cache = SigHashCache::new();
537 let mut c1 = TransactionChecker {
538 tx: &tx_2,
539 sig_hash_cache: &mut cache,
540 input: 0,
541 amount: Amount(10),
542 require_sighash_forkid: false,
543 };
544
545 let mut script1 = Script::new();
546 script1.append_slice(&tx_2.inputs[0].sig_script.0);
547 script1.append(OP_CODESEPARATOR);
548 script1.append_slice(&tx_1.outputs[0].pk_script.0);
549 assert!(script1.eval(&mut c1).is_ok());
550
551 let mut cache = SigHashCache::new();
552 let mut c2 = TransactionChecker {
553 tx: &tx_2,
554 sig_hash_cache: &mut cache,
555 input: 1,
556 amount: Amount(20),
557 require_sighash_forkid: false,
558 };
559
560 let mut script2 = Script::new();
561 script2.append_slice(&tx_2.inputs[1].sig_script.0);
562 script2.append(OP_CODESEPARATOR);
563 script2.append_slice(&tx_1.outputs[1].pk_script.0);
564 assert!(script2.eval(&mut c2).is_ok());
565 }
566
567 #[test]
568 fn check_locktime() {
569 let mut pk_script = Script::new();
570 pk_script.append_num(500).unwrap();
571 pk_script.append(OP_CHECKLOCKTIMEVERIFY);
572 pk_script.append(OP_1);
573 let mut tx = Tx {
574 version: 1,
575 inputs: vec![TxIn {
576 prev_output: OutPoint {
577 hash: Hash256([0; 32]),
578 index: 0,
579 },
580 sig_script: Script(vec![]),
581 sequence: 0,
582 }],
583 outputs: vec![],
584 lock_time: 499,
585 };
586 {
587 let mut cache = SigHashCache::new();
588 let mut c = TransactionChecker {
589 tx: &tx,
590 sig_hash_cache: &mut cache,
591 input: 0,
592 amount: Amount(0),
593 require_sighash_forkid: false,
594 };
595 assert!(pk_script.eval(&mut c).is_err());
596 }
597 {
598 tx.lock_time = 500;
599 let mut cache = SigHashCache::new();
600 let mut c = TransactionChecker {
601 tx: &tx,
602 sig_hash_cache: &mut cache,
603 input: 0,
604 amount: Amount(0),
605 require_sighash_forkid: false,
606 };
607 assert!(pk_script.eval(&mut c).is_ok());
608 }
609 }
610
611 #[test]
612 fn check_sequence() {
613 let mut pk_script = Script::new();
614 pk_script
615 .append_num(500 | SEQUENCE_LOCKTIME_TYPE_FLAG as i32)
616 .unwrap();
617 pk_script.append(OP_CHECKSEQUENCEVERIFY);
618 pk_script.append(OP_1);
619 let mut tx = Tx {
620 version: 2,
621 inputs: vec![TxIn {
622 prev_output: OutPoint {
623 hash: Hash256([0; 32]),
624 index: 0,
625 },
626 sig_script: Script(vec![]),
627 sequence: 499 | SEQUENCE_LOCKTIME_TYPE_FLAG,
628 }],
629 outputs: vec![],
630 lock_time: 0,
631 };
632 {
633 let mut cache = SigHashCache::new();
634 let mut c = TransactionChecker {
635 tx: &tx,
636 sig_hash_cache: &mut cache,
637 input: 0,
638 amount: Amount(0),
639 require_sighash_forkid: false,
640 };
641 assert!(pk_script.eval(&mut c).is_err());
642 }
643 {
644 tx.inputs[0].sequence = 500 | SEQUENCE_LOCKTIME_TYPE_FLAG;
645 let mut cache = SigHashCache::new();
646 let mut c = TransactionChecker {
647 tx: &tx,
648 sig_hash_cache: &mut cache,
649 input: 0,
650 amount: Amount(0),
651 require_sighash_forkid: false,
652 };
653 assert!(pk_script.eval(&mut c).is_ok());
654 }
655 }
656}