1use alloc::string::{String, ToString};
4use core::borrow::{Borrow, BorrowMut};
5use core::{fmt, str};
6
7use encoding::CompactSizeEncoder;
8use hashes::{hash_newtype, sha256, sha256d, sha512};
9use io::Write;
10use primitives::{script::Script, Amount, ScriptPubKey, Sequence, Transaction};
11
12#[rustfmt::skip]
13const UINT256_ONE: [u8; 32] = [
14 1, 0, 0, 0, 0, 0, 0, 0,
15 0, 0, 0, 0, 0, 0, 0, 0,
16 0, 0, 0, 0, 0, 0, 0, 0,
17 0, 0, 0, 0, 0, 0, 0, 0
18];
19
20#[rustfmt::skip]
21const UINT512_ONE: [u8; 64] = [
22 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
26];
27
28hash_newtype! {
29 #[hash_newtype(forward)]
31 pub struct LegacySighash(sha256d::Hash);
32
33 #[hash_newtype(forward)]
35 pub struct SegwitV0Sighash(sha256d::Hash);
36
37 #[hash_newtype(forward)]
39 pub struct Sighash512(sha512::Hash);
40}
41
42#[cfg(feature = "hex")]
43hashes::impl_hex_for_newtype!(LegacySighash, SegwitV0Sighash, Sighash512);
44#[cfg(feature = "serde")]
45hashes::impl_serde_for_newtype!(LegacySighash, SegwitV0Sighash, Sighash512);
46#[cfg(not(feature = "hex"))]
47hashes::impl_debug_only_for_newtype!(LegacySighash, SegwitV0Sighash, Sighash512);
48
49impl LegacySighash {
50 fn engine() -> sha256d::HashEngine {
51 sha256d::Hash::engine()
52 }
53
54 fn from_engine(e: sha256d::HashEngine) -> Self {
55 Self(sha256d::Hash::from_engine(e))
56 }
57}
58
59impl SegwitV0Sighash {
60 fn engine() -> sha256d::HashEngine {
61 sha256d::Hash::engine()
62 }
63
64 fn from_engine(e: sha256d::HashEngine) -> Self {
65 Self(sha256d::Hash::from_engine(e))
66 }
67}
68
69impl Sighash512 {
70 fn engine() -> sha512::HashEngine {
71 sha512::Hash::engine()
72 }
73
74 fn from_engine(e: sha512::HashEngine) -> Self {
75 Self(sha512::Hash::from_engine(e))
76 }
77}
78
79#[derive(PartialEq, Eq, Debug, Copy, Clone, Hash)]
81pub enum TxSighashType {
82 All = 0x01,
84 None = 0x02,
86 Single = 0x03,
88 AllPlusAnyoneCanPay = 0x81,
90 NonePlusAnyoneCanPay = 0x82,
92 SinglePlusAnyoneCanPay = 0x83,
94}
95
96impl TxSighashType {
97 fn split_anyonecanpay_flag(self) -> (Self, bool) {
98 match self {
99 Self::All => (Self::All, false),
100 Self::None => (Self::None, false),
101 Self::Single => (Self::Single, false),
102 Self::AllPlusAnyoneCanPay => (Self::All, true),
103 Self::NonePlusAnyoneCanPay => (Self::None, true),
104 Self::SinglePlusAnyoneCanPay => (Self::Single, true),
105 }
106 }
107
108 pub fn is_single(&self) -> bool {
110 matches!(self, Self::Single | Self::SinglePlusAnyoneCanPay)
111 }
112
113 pub fn from_consensus(n: u32) -> Self {
115 let mask = 0x1f | 0x80;
116 match n & mask {
117 0x01 => Self::All,
118 0x02 => Self::None,
119 0x03 => Self::Single,
120 0x81 => Self::AllPlusAnyoneCanPay,
121 0x82 => Self::NonePlusAnyoneCanPay,
122 0x83 => Self::SinglePlusAnyoneCanPay,
123 x if x & 0x80 == 0x80 => Self::AllPlusAnyoneCanPay,
124 _ => Self::All,
125 }
126 }
127
128 pub fn from_standard(n: u32) -> Result<Self, NonStandardSighashTypeError> {
134 match n {
135 0x01 => Ok(Self::All),
136 0x02 => Ok(Self::None),
137 0x03 => Ok(Self::Single),
138 0x81 => Ok(Self::AllPlusAnyoneCanPay),
139 0x82 => Ok(Self::NonePlusAnyoneCanPay),
140 0x83 => Ok(Self::SinglePlusAnyoneCanPay),
141 non_standard => Err(NonStandardSighashTypeError(non_standard)),
142 }
143 }
144
145 pub fn to_u32(self) -> u32 {
147 self as u32
148 }
149}
150
151impl fmt::Display for TxSighashType {
152 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153 let s = match self {
154 Self::All => "SIGHASH_ALL",
155 Self::None => "SIGHASH_NONE",
156 Self::Single => "SIGHASH_SINGLE",
157 Self::AllPlusAnyoneCanPay => "SIGHASH_ALL|SIGHASH_ANYONECANPAY",
158 Self::NonePlusAnyoneCanPay => "SIGHASH_NONE|SIGHASH_ANYONECANPAY",
159 Self::SinglePlusAnyoneCanPay => "SIGHASH_SINGLE|SIGHASH_ANYONECANPAY",
160 };
161 f.write_str(s)
162 }
163}
164
165impl str::FromStr for TxSighashType {
166 type Err = SighashTypeParseError;
167
168 fn from_str(s: &str) -> Result<Self, Self::Err> {
169 match s {
170 "SIGHASH_ALL" => Ok(Self::All),
171 "SIGHASH_NONE" => Ok(Self::None),
172 "SIGHASH_SINGLE" => Ok(Self::Single),
173 "SIGHASH_ALL|SIGHASH_ANYONECANPAY" => Ok(Self::AllPlusAnyoneCanPay),
174 "SIGHASH_NONE|SIGHASH_ANYONECANPAY" => Ok(Self::NonePlusAnyoneCanPay),
175 "SIGHASH_SINGLE|SIGHASH_ANYONECANPAY" => Ok(Self::SinglePlusAnyoneCanPay),
176 _ => Err(SighashTypeParseError { unrecognized: s.to_string() }),
177 }
178 }
179}
180
181#[cfg(feature = "serde")]
182internals::serde_string_impl!(TxSighashType, "a TxSighashType data");
183
184#[derive(Debug, Clone, PartialEq, Eq)]
186pub struct NonStandardSighashTypeError(pub u32);
187
188impl fmt::Display for NonStandardSighashTypeError {
189 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190 write!(f, "non-standard sighash type {}", self.0)
191 }
192}
193
194#[cfg(feature = "std")]
195impl std::error::Error for NonStandardSighashTypeError {}
196
197#[derive(Debug, Clone, PartialEq, Eq)]
199#[non_exhaustive]
200pub struct SighashTypeParseError {
201 pub unrecognized: String,
203}
204
205impl fmt::Display for SighashTypeParseError {
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 write!(f, "unrecognized SIGHASH string '{}'", self.unrecognized)
208 }
209}
210
211#[cfg(feature = "std")]
212impl std::error::Error for SighashTypeParseError {}
213
214#[derive(Debug, Clone, PartialEq, Eq)]
216pub struct InputsIndexError {
217 pub index: usize,
219 pub length: usize,
221}
222
223impl fmt::Display for InputsIndexError {
224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225 write!(f, "input index {} out of bounds for length {}", self.index, self.length)
226 }
227}
228
229#[cfg(feature = "std")]
230impl std::error::Error for InputsIndexError {}
231
232#[derive(Debug)]
234pub struct SighashCache<T: Borrow<Transaction>> {
235 tx: T,
236 common_cache: Option<CommonCache>,
237 segwit_cache: Option<SegwitCache>,
238 segwit_cache_512: Option<SegwitV1512Cache>,
239}
240
241#[derive(Debug)]
242struct CommonCache {
243 prevouts: sha256::Hash,
244 sequences: sha256::Hash,
245 outputs: sha256::Hash,
246}
247
248#[derive(Debug)]
249struct SegwitCache {
250 prevouts: sha256d::Hash,
251 sequences: sha256d::Hash,
252 outputs: sha256d::Hash,
253}
254
255#[derive(Debug)]
256struct SegwitV1512Cache {
257 prevouts: sha512::Hash,
258 sequences: sha512::Hash,
259 outputs: sha512::Hash,
260}
261
262impl<R: Borrow<Transaction>> SighashCache<R> {
263 pub fn new(tx: R) -> Self {
265 Self { tx, common_cache: None, segwit_cache: None, segwit_cache_512: None }
266 }
267
268 pub fn transaction(&self) -> &Transaction {
270 self.tx.borrow()
271 }
272
273 pub fn into_transaction(self) -> R {
275 self.tx
276 }
277
278 fn input(&self, input_index: usize) -> Result<&primitives::TxIn, InputsIndexError> {
279 self.tx
280 .borrow()
281 .inputs
282 .get(input_index)
283 .ok_or(InputsIndexError { index: input_index, length: self.tx.borrow().inputs.len() })
284 }
285
286 pub fn legacy_signature_hash(
288 &self,
289 input_index: usize,
290 script_bytes: &[u8],
291 sighash_type: u32,
292 ) -> Result<LegacySighash, InputsIndexError> {
293 self.input(input_index)?;
294
295 if is_invalid_use_of_sighash_single(
296 sighash_type,
297 input_index,
298 self.tx.borrow().outputs.len(),
299 ) {
300 return Ok(LegacySighash::from_byte_array(UINT256_ONE));
301 }
302
303 let tx = self.tx.borrow();
304 let (sighash, anyone_can_pay) =
305 TxSighashType::from_consensus(sighash_type).split_anyonecanpay_flag();
306
307 let mut engine = LegacySighash::engine();
308 io::encode_to_writer(&tx.version, &mut engine).expect("hash engine does not fail");
309
310 encode_compact_size(if anyone_can_pay { 1 } else { tx.inputs.len() }, &mut engine)
311 .expect("hash engine does not fail");
312 if anyone_can_pay {
313 let input = &tx.inputs[input_index];
314 io::encode_to_writer(&input.previous_output, &mut engine)
315 .expect("hash engine does not fail");
316 encode_script_bytes(script_bytes, &mut engine).expect("hash engine does not fail");
317 io::encode_to_writer(&input.sequence, &mut engine).expect("hash engine does not fail");
318 } else {
319 for (n, input) in tx.inputs.iter().enumerate() {
320 io::encode_to_writer(&input.previous_output, &mut engine)
321 .expect("hash engine does not fail");
322 if n == input_index {
323 encode_script_bytes(script_bytes, &mut engine)
324 .expect("hash engine does not fail");
325 } else {
326 io::encode_to_writer(ScriptPubKey::new(), &mut engine)
327 .expect("hash engine does not fail");
328 }
329 if n != input_index
330 && (sighash == TxSighashType::Single || sighash == TxSighashType::None)
331 {
332 io::encode_to_writer(&Sequence::ZERO, &mut engine)
333 .expect("hash engine does not fail");
334 } else {
335 io::encode_to_writer(&input.sequence, &mut engine)
336 .expect("hash engine does not fail");
337 }
338 }
339 }
340
341 match sighash {
342 TxSighashType::All => {
343 encode_compact_size(tx.outputs.len(), &mut engine)
344 .expect("hash engine does not fail");
345 for output in &tx.outputs {
346 io::encode_to_writer(output, &mut engine).expect("hash engine does not fail");
347 }
348 }
349 TxSighashType::Single => {
350 let count = input_index.min(tx.outputs.len() - 1);
351 encode_compact_size(count + 1, &mut engine).expect("hash engine does not fail");
352 for _ in 0..count {
353 engine
354 .write_all(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00])
355 .expect("hash engine does not fail");
356 }
357 io::encode_to_writer(&tx.outputs[count], &mut engine)
358 .expect("hash engine does not fail");
359 }
360 TxSighashType::None => {
361 encode_compact_size(0, &mut engine).expect("hash engine does not fail");
362 }
363 _ => unreachable!(),
364 }
365
366 io::encode_to_writer(&tx.lock_time, &mut engine).expect("hash engine does not fail");
367 engine.write_all(&sighash_type.to_le_bytes()).expect("hash engine does not fail");
368 Ok(LegacySighash::from_engine(engine))
369 }
370
371 pub fn p2wsh_signature_hash(
373 &mut self,
374 input_index: usize,
375 witness_script_bytes: &[u8],
376 amount: Amount,
377 sighash_type: TxSighashType,
378 ) -> Result<SegwitV0Sighash, InputsIndexError> {
379 let zero_hash = [0; 32];
380 let mut engine = SegwitV0Sighash::engine();
381 let (sighash, anyone_can_pay) = sighash_type.split_anyonecanpay_flag();
382 let prevouts =
383 if !anyone_can_pay { Some(self.segwit_cache().prevouts.to_byte_array()) } else { None };
384 let sequences = if !anyone_can_pay
385 && sighash != TxSighashType::Single
386 && sighash != TxSighashType::None
387 {
388 Some(self.segwit_cache().sequences.to_byte_array())
389 } else {
390 None
391 };
392 let outputs = if sighash != TxSighashType::Single && sighash != TxSighashType::None {
393 Some(self.segwit_cache().outputs.to_byte_array())
394 } else {
395 None
396 };
397 let tx = self.tx.borrow();
398
399 io::encode_to_writer(&tx.version, &mut engine).expect("hash engine does not fail");
400 if let Some(prevouts) = prevouts {
401 engine.write_all(&prevouts).expect("hash engine does not fail");
402 } else {
403 engine.write_all(&zero_hash).expect("hash engine does not fail");
404 }
405
406 if let Some(sequences) = sequences {
407 engine.write_all(&sequences).expect("hash engine does not fail");
408 } else {
409 engine.write_all(&zero_hash).expect("hash engine does not fail");
410 }
411
412 let txin = self.input(input_index)?;
413 io::encode_to_writer(&txin.previous_output, &mut engine)
414 .expect("hash engine does not fail");
415 encode_script_bytes(witness_script_bytes, &mut engine).expect("hash engine does not fail");
416 io::encode_to_writer(&amount, &mut engine).expect("hash engine does not fail");
417 io::encode_to_writer(&txin.sequence, &mut engine).expect("hash engine does not fail");
418
419 if let Some(outputs) = outputs {
420 engine.write_all(&outputs).expect("hash engine does not fail");
421 } else if sighash == TxSighashType::Single && input_index < tx.outputs.len() {
422 let mut single_enc = LegacySighash::engine();
423 single_enc = hashes::encode_to_engine(&tx.outputs[input_index], single_enc);
424 let hash = LegacySighash::from_engine(single_enc);
425 engine.write_all(hash.as_byte_array()).expect("hash engine does not fail");
426 } else {
427 engine.write_all(&zero_hash).expect("hash engine does not fail");
428 }
429
430 io::encode_to_writer(&tx.lock_time, &mut engine).expect("hash engine does not fail");
431 engine.write_all(&sighash_type.to_u32().to_le_bytes()).expect("hash engine does not fail");
432 Ok(SegwitV0Sighash::from_engine(engine))
433 }
434
435 pub fn p2wsh512_signature_hash(
437 &mut self,
438 input_index: usize,
439 witness_script_bytes: &[u8],
440 amount: Amount,
441 sighash_type: TxSighashType,
442 ) -> Result<Sighash512, InputsIndexError> {
443 const TAG: &[u8] = b"TidecoinSighashV1_512";
444 let zero_hash = [0; 64];
445 let outputs_len = self.tx.borrow().outputs.len();
446
447 if sighash_type.is_single() && input_index >= outputs_len {
448 return Ok(Sighash512::from_byte_array(UINT512_ONE));
449 }
450
451 let tag_hash = sha512::Hash::hash(TAG);
452 let mut engine = Sighash512::engine();
453 engine.write_all(tag_hash.as_byte_array()).expect("hash engine does not fail");
454 engine.write_all(tag_hash.as_byte_array()).expect("hash engine does not fail");
455
456 let (sighash, anyone_can_pay) = sighash_type.split_anyonecanpay_flag();
457 let prevouts = if !anyone_can_pay {
458 Some(*self.segwit_cache_512().prevouts.as_byte_array())
459 } else {
460 None
461 };
462 let sequences = if !anyone_can_pay
463 && sighash != TxSighashType::Single
464 && sighash != TxSighashType::None
465 {
466 Some(*self.segwit_cache_512().sequences.as_byte_array())
467 } else {
468 None
469 };
470 let outputs = if sighash != TxSighashType::Single && sighash != TxSighashType::None {
471 Some(*self.segwit_cache_512().outputs.as_byte_array())
472 } else {
473 None
474 };
475 let tx = self.tx.borrow();
476 io::encode_to_writer(&tx.version, &mut engine).expect("hash engine does not fail");
477
478 if let Some(prevouts) = prevouts {
479 engine.write_all(&prevouts).expect("hash engine does not fail");
480 } else {
481 engine.write_all(&zero_hash).expect("hash engine does not fail");
482 }
483
484 if let Some(sequences) = sequences {
485 engine.write_all(&sequences).expect("hash engine does not fail");
486 } else {
487 engine.write_all(&zero_hash).expect("hash engine does not fail");
488 }
489
490 let txin = self.input(input_index)?;
491 io::encode_to_writer(&txin.previous_output, &mut engine)
492 .expect("hash engine does not fail");
493 encode_script_bytes(witness_script_bytes, &mut engine).expect("hash engine does not fail");
494 io::encode_to_writer(&amount, &mut engine).expect("hash engine does not fail");
495 io::encode_to_writer(&txin.sequence, &mut engine).expect("hash engine does not fail");
496
497 if let Some(outputs) = outputs {
498 engine.write_all(&outputs).expect("hash engine does not fail");
499 } else if sighash == TxSighashType::Single {
500 let mut single_enc = sha512::Hash::engine();
501 io::encode_to_writer(&tx.outputs[input_index], &mut single_enc)
502 .expect("hash engine does not fail");
503 let hash = sha512::Hash::from_engine(single_enc);
504 engine.write_all(hash.as_byte_array()).expect("hash engine does not fail");
505 } else {
506 engine.write_all(&zero_hash).expect("hash engine does not fail");
507 }
508
509 io::encode_to_writer(&tx.lock_time, &mut engine).expect("hash engine does not fail");
510 engine.write_all(&sighash_type.to_u32().to_le_bytes()).expect("hash engine does not fail");
511 Ok(Sighash512::from_engine(engine))
512 }
513
514 fn common_cache_minimal_borrow<'a>(
515 common_cache: &'a mut Option<CommonCache>,
516 tx: &Transaction,
517 ) -> &'a CommonCache {
518 common_cache.get_or_insert_with(|| {
519 let mut enc_prevouts = sha256::Hash::engine();
520 let mut enc_sequences = sha256::Hash::engine();
521 for txin in &tx.inputs {
522 enc_prevouts = hashes::encode_to_engine(&txin.previous_output, enc_prevouts);
523 enc_sequences = hashes::encode_to_engine(&txin.sequence, enc_sequences);
524 }
525 CommonCache {
526 prevouts: sha256::Hash::from_engine(enc_prevouts),
527 sequences: sha256::Hash::from_engine(enc_sequences),
528 outputs: {
529 let mut enc = sha256::Hash::engine();
530 for txout in &tx.outputs {
531 io::encode_to_writer(txout, &mut enc).expect("hash engine does not fail");
532 }
533 sha256::Hash::from_engine(enc)
534 },
535 }
536 })
537 }
538
539 fn segwit_cache(&mut self) -> &SegwitCache {
540 let common_cache = &mut self.common_cache;
541 let tx = self.tx.borrow();
542 self.segwit_cache.get_or_insert_with(|| {
543 let common_cache = Self::common_cache_minimal_borrow(common_cache, tx);
544 SegwitCache {
545 prevouts: common_cache.prevouts.hash_again(),
546 sequences: common_cache.sequences.hash_again(),
547 outputs: common_cache.outputs.hash_again(),
548 }
549 })
550 }
551
552 fn segwit_cache_512(&mut self) -> &SegwitV1512Cache {
553 let tx = self.tx.borrow();
554 self.segwit_cache_512.get_or_insert_with(|| {
555 let mut enc_prevouts = sha512::Hash::engine();
556 let mut enc_sequences = sha512::Hash::engine();
557 for txin in &tx.inputs {
558 enc_prevouts = hashes::encode_to_engine(&txin.previous_output, enc_prevouts);
559 enc_sequences = hashes::encode_to_engine(&txin.sequence, enc_sequences);
560 }
561 SegwitV1512Cache {
562 prevouts: sha512::Hash::from_engine(enc_prevouts),
563 sequences: sha512::Hash::from_engine(enc_sequences),
564 outputs: {
565 let mut enc = sha512::Hash::engine();
566 for txout in &tx.outputs {
567 io::encode_to_writer(txout, &mut enc).expect("hash engine does not fail");
568 }
569 sha512::Hash::from_engine(enc)
570 },
571 }
572 })
573 }
574}
575
576impl<R: BorrowMut<Transaction>> SighashCache<R> {
577 pub fn transaction_mut(&mut self) -> &mut Transaction {
581 self.tx.borrow_mut()
582 }
583}
584
585fn is_invalid_use_of_sighash_single(sighash: u32, input_index: usize, outputs_len: usize) -> bool {
586 TxSighashType::from_consensus(sighash).is_single() && input_index >= outputs_len
587}
588
589fn encode_compact_size<W: Write>(len: usize, writer: &mut W) -> Result<(), io::Error> {
590 let mut encoder = CompactSizeEncoder::new(len);
591 io::flush_to_writer(&mut encoder, writer)
592}
593
594fn encode_script_bytes<W: Write>(bytes: &[u8], writer: &mut W) -> Result<(), io::Error> {
595 io::encode_to_writer(Script::<()>::from_bytes(bytes), writer)
596}