1use num_bigint::BigInt;
10use num_traits::{One, Signed, ToPrimitive, Zero};
11
12use super::error::{InterpreterError, InterpreterErrorCode};
13
14#[derive(Debug, Clone)]
16pub struct ScriptNumber {
17 pub val: BigInt,
19 pub after_genesis: bool,
21}
22
23impl ScriptNumber {
24 pub fn new(val: i64, after_genesis: bool) -> Self {
26 ScriptNumber {
27 val: BigInt::from(val),
28 after_genesis,
29 }
30 }
31
32 pub fn from_bytes(
38 bb: &[u8],
39 script_num_len: usize,
40 require_minimal: bool,
41 after_genesis: bool,
42 ) -> Result<Self, InterpreterError> {
43 if bb.len() > script_num_len {
44 return Err(InterpreterError::new(
45 InterpreterErrorCode::NumberTooBig,
46 format!(
47 "numeric value encoded as {:02x?} is {} bytes which exceeds the max allowed of {}",
48 bb, bb.len(), script_num_len
49 ),
50 ));
51 }
52
53 if require_minimal {
54 check_minimal_data_encoding(bb)?;
55 }
56
57 if bb.is_empty() {
58 return Ok(ScriptNumber {
59 val: BigInt::zero(),
60 after_genesis,
61 });
62 }
63
64 let mut v = BigInt::zero();
66 for (i, &b) in bb.iter().enumerate() {
67 v |= BigInt::from(b) << (8 * i);
68 }
69
70 if bb[bb.len() - 1] & 0x80 != 0 {
72 let mask = !(BigInt::from(0x80_i64) << (8 * (bb.len() - 1)));
74 v &= mask;
75 v = -v;
76 }
77
78 Ok(ScriptNumber {
79 val: v,
80 after_genesis,
81 })
82 }
83
84 pub fn to_bytes(&self) -> Vec<u8> {
86 if self.val.is_zero() {
87 return vec![];
88 }
89
90 let is_negative = self.val.is_negative();
91 let abs_val = if is_negative {
92 -self.val.clone()
93 } else {
94 self.val.clone()
95 };
96
97 let working_val = if !self.after_genesis {
99 let v = self
100 .val
101 .to_i64()
102 .unwrap_or(if is_negative { i64::MIN } else { i64::MAX });
103 if v > i32::MAX as i64 {
104 BigInt::from(i32::MAX)
105 } else if v < i32::MIN as i64 {
106 BigInt::from(i32::MIN).abs()
107 } else {
108 abs_val.clone()
109 }
110 } else {
111 abs_val.clone()
112 };
113
114 let _ = working_val; let mut result: Vec<u8> = Vec::new();
118 let mut cpy = abs_val;
119 while cpy > BigInt::zero() {
120 result.push((&cpy & BigInt::from(0xff_u8)).to_u8().unwrap_or(0));
121 cpy >>= 8;
122 }
123
124 if result.is_empty() {
125 return vec![];
126 }
127
128 if result[result.len() - 1] & 0x80 != 0 {
130 result.push(if is_negative { 0x80 } else { 0x00 });
132 } else if is_negative {
133 let last = result.len() - 1;
134 result[last] |= 0x80;
135 }
136
137 result
138 }
139
140 pub fn add(&mut self, other: &ScriptNumber) -> &mut Self {
144 self.val = &self.val + &other.val;
145 self
146 }
147
148 pub fn sub(&mut self, other: &ScriptNumber) -> &mut Self {
150 self.val = &self.val - &other.val;
151 self
152 }
153
154 pub fn mul(&mut self, other: &ScriptNumber) -> &mut Self {
156 self.val = &self.val * &other.val;
157 self
158 }
159
160 pub fn div(&mut self, other: &ScriptNumber) -> &mut Self {
162 use num_integer::Integer;
164 let (q, r) = self.val.div_rem(&other.val);
165 let _ = r;
168 self.val = q;
169 self
170 }
171
172 pub fn modulo(&mut self, other: &ScriptNumber) -> &mut Self {
174 use num_integer::Integer;
176 let (_, r) = self.val.div_rem(&other.val);
177 self.val = r;
178 self
179 }
180
181 pub fn incr(&mut self) -> &mut Self {
183 self.val = &self.val + BigInt::one();
184 self
185 }
186
187 pub fn decr(&mut self) -> &mut Self {
189 self.val = &self.val - BigInt::one();
190 self
191 }
192
193 pub fn neg(&mut self) -> &mut Self {
195 self.val = -self.val.clone();
196 self
197 }
198
199 pub fn abs(&mut self) -> &mut Self {
201 if self.val.is_negative() {
202 self.val = -self.val.clone();
203 }
204 self
205 }
206
207 pub fn set(&mut self, i: i64) -> &mut Self {
209 self.val = BigInt::from(i);
210 self
211 }
212
213 pub fn is_zero(&self) -> bool {
217 self.val.is_zero()
218 }
219
220 pub fn less_than(&self, other: &ScriptNumber) -> bool {
222 self.val < other.val
223 }
224
225 pub fn less_than_int(&self, i: i64) -> bool {
227 self.val < BigInt::from(i)
228 }
229
230 pub fn less_than_or_equal(&self, other: &ScriptNumber) -> bool {
232 self.val <= other.val
233 }
234
235 pub fn greater_than(&self, other: &ScriptNumber) -> bool {
237 self.val > other.val
238 }
239
240 pub fn greater_than_int(&self, i: i64) -> bool {
242 self.val > BigInt::from(i)
243 }
244
245 pub fn greater_than_or_equal(&self, other: &ScriptNumber) -> bool {
247 self.val >= other.val
248 }
249
250 pub fn equal(&self, other: &ScriptNumber) -> bool {
252 self.val == other.val
253 }
254
255 pub fn equal_int(&self, i: i64) -> bool {
257 self.val == BigInt::from(i)
258 }
259
260 pub fn to_i32(&self) -> i32 {
264 match self.val.to_i64() {
265 Some(v) => {
266 if v > i32::MAX as i64 {
267 i32::MAX
268 } else if v < i32::MIN as i64 {
269 i32::MIN
270 } else {
271 v as i32
272 }
273 }
274 None => {
275 if self.val.is_positive() {
276 i32::MAX
277 } else {
278 i32::MIN
279 }
280 }
281 }
282 }
283
284 pub fn to_i64(&self) -> i64 {
286 if self.greater_than_int(i64::MAX) {
287 return i64::MAX;
288 }
289 if self.less_than_int(i64::MIN) {
290 return i64::MIN;
291 }
292 self.val.to_i64().unwrap_or(0)
293 }
294
295 pub fn to_int(&self) -> i64 {
297 self.val.to_i64().unwrap_or(0)
298 }
299}
300
301pub fn minimally_encode(data: &[u8]) -> Vec<u8> {
303 if data.is_empty() {
304 return vec![];
305 }
306
307 let mut data = data.to_vec();
308 let last = data[data.len() - 1];
309
310 if last & 0x7f != 0 {
311 return data;
312 }
313
314 if data.len() == 1 {
315 return vec![];
316 }
317
318 if data[data.len() - 2] & 0x80 != 0 {
319 return data;
320 }
321
322 let mut i = data.len() - 1;
323 while i > 0 {
324 if data[i - 1] != 0 {
325 if data[i - 1] & 0x80 != 0 {
326 data[i] = last;
327 return data[..=i].to_vec();
328 } else {
329 data[i - 1] |= last;
330 return data[..i].to_vec();
331 }
332 }
333 i -= 1;
334 }
335
336 vec![]
337}
338
339pub fn check_minimal_data_encoding(v: &[u8]) -> Result<(), InterpreterError> {
341 if v.is_empty() {
342 return Ok(());
343 }
344
345 if v[v.len() - 1] & 0x7f == 0 {
346 if v.len() == 1 || v[v.len() - 2] & 0x80 == 0 {
347 return Err(InterpreterError::new(
348 InterpreterErrorCode::MinimalData,
349 format!(
350 "numeric value encoded as {:02x?} is not minimally encoded",
351 v
352 ),
353 ));
354 }
355 }
356
357 Ok(())
358}
359
360#[cfg(test)]
361mod tests {
362 use super::*;
363
364 fn hex_to_bytes(s: &str) -> Vec<u8> {
365 hex::decode(s).unwrap()
366 }
367
368 #[test]
369 fn test_script_num_bytes() {
370 let tests: Vec<(i64, Vec<u8>)> = vec![
371 (0, vec![]),
372 (1, hex_to_bytes("01")),
373 (-1, hex_to_bytes("81")),
374 (127, hex_to_bytes("7f")),
375 (-127, hex_to_bytes("ff")),
376 (128, hex_to_bytes("8000")),
377 (-128, hex_to_bytes("8080")),
378 (129, hex_to_bytes("8100")),
379 (-129, hex_to_bytes("8180")),
380 (256, hex_to_bytes("0001")),
381 (-256, hex_to_bytes("0081")),
382 (32767, hex_to_bytes("ff7f")),
383 (-32767, hex_to_bytes("ffff")),
384 (32768, hex_to_bytes("008000")),
385 (-32768, hex_to_bytes("008080")),
386 (65535, hex_to_bytes("ffff00")),
387 (-65535, hex_to_bytes("ffff80")),
388 (524288, hex_to_bytes("000008")),
389 (-524288, hex_to_bytes("000088")),
390 (7340032, hex_to_bytes("000070")),
391 (-7340032, hex_to_bytes("0000f0")),
392 (8388608, hex_to_bytes("00008000")),
393 (-8388608, hex_to_bytes("00008080")),
394 (2147483647, hex_to_bytes("ffffff7f")),
395 (-2147483647, hex_to_bytes("ffffffff")),
396 (2147483648, hex_to_bytes("0000008000")),
398 (-2147483648, hex_to_bytes("0000008080")),
399 (2415919104, hex_to_bytes("0000009000")),
400 (-2415919104, hex_to_bytes("0000009080")),
401 (4294967295, hex_to_bytes("ffffffff00")),
402 (-4294967295, hex_to_bytes("ffffffff80")),
403 (4294967296, hex_to_bytes("0000000001")),
404 (-4294967296, hex_to_bytes("0000000081")),
405 (281474976710655, hex_to_bytes("ffffffffffff00")),
406 (-281474976710655, hex_to_bytes("ffffffffffff80")),
407 (72057594037927935, hex_to_bytes("ffffffffffffff00")),
408 (-72057594037927935, hex_to_bytes("ffffffffffffff80")),
409 (9223372036854775807, hex_to_bytes("ffffffffffffff7f")),
410 (-9223372036854775807, hex_to_bytes("ffffffffffffffff")),
411 ];
412
413 for (num, expected) in &tests {
414 let sn = ScriptNumber {
415 val: BigInt::from(*num),
416 after_genesis: true, };
418 let got = sn.to_bytes();
419 assert_eq!(
420 &got, expected,
421 "Bytes: num={}, got={:02x?}, want={:02x?}",
422 num, got, expected
423 );
424 }
425 }
426
427 #[test]
428 fn test_make_script_num() {
429 struct Test {
430 serialized: Vec<u8>,
431 num: i64,
432 num_len: usize,
433 minimal_encoding: bool,
434 expect_err: bool,
435 }
436
437 let tests = vec![
438 Test {
440 serialized: hex_to_bytes("80"),
441 num: 0,
442 num_len: 4,
443 minimal_encoding: true,
444 expect_err: true,
445 },
446 Test {
448 serialized: vec![],
449 num: 0,
450 num_len: 4,
451 minimal_encoding: true,
452 expect_err: false,
453 },
454 Test {
455 serialized: hex_to_bytes("01"),
456 num: 1,
457 num_len: 4,
458 minimal_encoding: true,
459 expect_err: false,
460 },
461 Test {
462 serialized: hex_to_bytes("81"),
463 num: -1,
464 num_len: 4,
465 minimal_encoding: true,
466 expect_err: false,
467 },
468 Test {
469 serialized: hex_to_bytes("7f"),
470 num: 127,
471 num_len: 4,
472 minimal_encoding: true,
473 expect_err: false,
474 },
475 Test {
476 serialized: hex_to_bytes("ff"),
477 num: -127,
478 num_len: 4,
479 minimal_encoding: true,
480 expect_err: false,
481 },
482 Test {
483 serialized: hex_to_bytes("8000"),
484 num: 128,
485 num_len: 4,
486 minimal_encoding: true,
487 expect_err: false,
488 },
489 Test {
490 serialized: hex_to_bytes("8080"),
491 num: -128,
492 num_len: 4,
493 minimal_encoding: true,
494 expect_err: false,
495 },
496 Test {
497 serialized: hex_to_bytes("8100"),
498 num: 129,
499 num_len: 4,
500 minimal_encoding: true,
501 expect_err: false,
502 },
503 Test {
504 serialized: hex_to_bytes("8180"),
505 num: -129,
506 num_len: 4,
507 minimal_encoding: true,
508 expect_err: false,
509 },
510 Test {
511 serialized: hex_to_bytes("0001"),
512 num: 256,
513 num_len: 4,
514 minimal_encoding: true,
515 expect_err: false,
516 },
517 Test {
518 serialized: hex_to_bytes("0081"),
519 num: -256,
520 num_len: 4,
521 minimal_encoding: true,
522 expect_err: false,
523 },
524 Test {
525 serialized: hex_to_bytes("ff7f"),
526 num: 32767,
527 num_len: 4,
528 minimal_encoding: true,
529 expect_err: false,
530 },
531 Test {
532 serialized: hex_to_bytes("ffff"),
533 num: -32767,
534 num_len: 4,
535 minimal_encoding: true,
536 expect_err: false,
537 },
538 Test {
539 serialized: hex_to_bytes("008000"),
540 num: 32768,
541 num_len: 4,
542 minimal_encoding: true,
543 expect_err: false,
544 },
545 Test {
546 serialized: hex_to_bytes("008080"),
547 num: -32768,
548 num_len: 4,
549 minimal_encoding: true,
550 expect_err: false,
551 },
552 Test {
553 serialized: hex_to_bytes("ffffff7f"),
554 num: 2147483647,
555 num_len: 4,
556 minimal_encoding: true,
557 expect_err: false,
558 },
559 Test {
560 serialized: hex_to_bytes("ffffffff"),
561 num: -2147483647,
562 num_len: 4,
563 minimal_encoding: true,
564 expect_err: false,
565 },
566 Test {
568 serialized: hex_to_bytes("ffffffff7f"),
569 num: 549755813887,
570 num_len: 5,
571 minimal_encoding: true,
572 expect_err: false,
573 },
574 Test {
575 serialized: hex_to_bytes("ffffffffff"),
576 num: -549755813887,
577 num_len: 5,
578 minimal_encoding: true,
579 expect_err: false,
580 },
581 Test {
583 serialized: hex_to_bytes("0000008000"),
584 num: 0,
585 num_len: 4,
586 minimal_encoding: true,
587 expect_err: true,
588 },
589 Test {
591 serialized: hex_to_bytes("00"),
592 num: 0,
593 num_len: 4,
594 minimal_encoding: true,
595 expect_err: true,
596 },
597 Test {
598 serialized: hex_to_bytes("0100"),
599 num: 0,
600 num_len: 4,
601 minimal_encoding: true,
602 expect_err: true,
603 },
604 Test {
606 serialized: hex_to_bytes("00"),
607 num: 0,
608 num_len: 4,
609 minimal_encoding: false,
610 expect_err: false,
611 },
612 Test {
613 serialized: hex_to_bytes("0100"),
614 num: 1,
615 num_len: 4,
616 minimal_encoding: false,
617 expect_err: false,
618 },
619 ];
620
621 for test in &tests {
622 let result = ScriptNumber::from_bytes(
623 &test.serialized,
624 test.num_len,
625 test.minimal_encoding,
626 true,
627 );
628 match result {
629 Ok(sn) => {
630 assert!(
631 !test.expect_err,
632 "from_bytes({:02x?}): expected error",
633 test.serialized
634 );
635 assert_eq!(
636 sn.to_int(),
637 test.num,
638 "from_bytes({:02x?}): got {}, want {}",
639 test.serialized,
640 sn.to_int(),
641 test.num
642 );
643 }
644 Err(_) => {
645 assert!(
646 test.expect_err,
647 "from_bytes({:02x?}): unexpected error",
648 test.serialized
649 );
650 }
651 }
652 }
653 }
654
655 #[test]
656 fn test_script_num_int32() {
657 let tests: Vec<(i64, i32)> = vec![
658 (0, 0),
659 (1, 1),
660 (-1, -1),
661 (2147483647, 2147483647),
662 (-2147483647, -2147483647),
663 (-2147483648, -2147483648),
664 (2147483648, 2147483647),
666 (-2147483649, -2147483648),
667 (9223372036854775807, 2147483647),
668 (-9223372036854775808, -2147483648),
669 ];
670
671 for (input, want) in &tests {
672 let sn = ScriptNumber {
673 val: BigInt::from(*input),
674 after_genesis: false,
675 };
676 assert_eq!(
677 sn.to_i32(),
678 *want,
679 "Int32({}): got {}, want {}",
680 input,
681 sn.to_i32(),
682 want
683 );
684 }
685 }
686
687 #[test]
688 fn test_minimally_encode() {
689 assert_eq!(minimally_encode(&[]), Vec::<u8>::new());
691 assert_eq!(minimally_encode(&[0x7f]), vec![0x7f]);
693 assert_eq!(minimally_encode(&[0x00]), Vec::<u8>::new());
695 assert_eq!(minimally_encode(&[0x80]), Vec::<u8>::new());
697 }
698}