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.val.to_i64().unwrap_or(if is_negative {
100 i64::MIN
101 } else {
102 i64::MAX
103 });
104 if v > i32::MAX as i64 {
105 BigInt::from(i32::MAX)
106 } else if v < i32::MIN as i64 {
107 BigInt::from(i32::MIN).abs()
108 } else {
109 abs_val.clone()
110 }
111 } else {
112 abs_val.clone()
113 };
114
115 let _ = working_val; let mut result: Vec<u8> = Vec::new();
119 let mut cpy = abs_val;
120 while cpy > BigInt::zero() {
121 result.push((&cpy & BigInt::from(0xff_u8))
122 .to_u8()
123 .unwrap_or(0));
124 cpy >>= 8;
125 }
126
127 if result.is_empty() {
128 return vec![];
129 }
130
131 if result[result.len() - 1] & 0x80 != 0 {
133 result.push(if is_negative { 0x80 } else { 0x00 });
135 } else if is_negative {
136 let last = result.len() - 1;
137 result[last] |= 0x80;
138 }
139
140 result
141 }
142
143 pub fn add(&mut self, other: &ScriptNumber) -> &mut Self {
147 self.val = &self.val + &other.val;
148 self
149 }
150
151 pub fn sub(&mut self, other: &ScriptNumber) -> &mut Self {
153 self.val = &self.val - &other.val;
154 self
155 }
156
157 pub fn mul(&mut self, other: &ScriptNumber) -> &mut Self {
159 self.val = &self.val * &other.val;
160 self
161 }
162
163 pub fn div(&mut self, other: &ScriptNumber) -> &mut Self {
165 use num_integer::Integer;
167 let (q, r) = self.val.div_rem(&other.val);
168 let _ = r;
171 self.val = q;
172 self
173 }
174
175 pub fn modulo(&mut self, other: &ScriptNumber) -> &mut Self {
177 use num_integer::Integer;
179 let (_, r) = self.val.div_rem(&other.val);
180 self.val = r;
181 self
182 }
183
184 pub fn incr(&mut self) -> &mut Self {
186 self.val = &self.val + BigInt::one();
187 self
188 }
189
190 pub fn decr(&mut self) -> &mut Self {
192 self.val = &self.val - BigInt::one();
193 self
194 }
195
196 pub fn neg(&mut self) -> &mut Self {
198 self.val = -self.val.clone();
199 self
200 }
201
202 pub fn abs(&mut self) -> &mut Self {
204 if self.val.is_negative() {
205 self.val = -self.val.clone();
206 }
207 self
208 }
209
210 pub fn set(&mut self, i: i64) -> &mut Self {
212 self.val = BigInt::from(i);
213 self
214 }
215
216 pub fn is_zero(&self) -> bool {
220 self.val.is_zero()
221 }
222
223 pub fn less_than(&self, other: &ScriptNumber) -> bool {
225 self.val < other.val
226 }
227
228 pub fn less_than_int(&self, i: i64) -> bool {
230 self.val < BigInt::from(i)
231 }
232
233 pub fn less_than_or_equal(&self, other: &ScriptNumber) -> bool {
235 self.val <= other.val
236 }
237
238 pub fn greater_than(&self, other: &ScriptNumber) -> bool {
240 self.val > other.val
241 }
242
243 pub fn greater_than_int(&self, i: i64) -> bool {
245 self.val > BigInt::from(i)
246 }
247
248 pub fn greater_than_or_equal(&self, other: &ScriptNumber) -> bool {
250 self.val >= other.val
251 }
252
253 pub fn equal(&self, other: &ScriptNumber) -> bool {
255 self.val == other.val
256 }
257
258 pub fn equal_int(&self, i: i64) -> bool {
260 self.val == BigInt::from(i)
261 }
262
263 pub fn to_i32(&self) -> i32 {
267 match self.val.to_i64() {
268 Some(v) => {
269 if v > i32::MAX as i64 {
270 i32::MAX
271 } else if v < i32::MIN as i64 {
272 i32::MIN
273 } else {
274 v as i32
275 }
276 }
277 None => {
278 if self.val.is_positive() {
279 i32::MAX
280 } else {
281 i32::MIN
282 }
283 }
284 }
285 }
286
287 pub fn to_i64(&self) -> i64 {
289 if self.greater_than_int(i64::MAX) {
290 return i64::MAX;
291 }
292 if self.less_than_int(i64::MIN) {
293 return i64::MIN;
294 }
295 self.val.to_i64().unwrap_or(0)
296 }
297
298 pub fn to_int(&self) -> i64 {
300 self.val.to_i64().unwrap_or(0)
301 }
302}
303
304pub fn minimally_encode(data: &[u8]) -> Vec<u8> {
306 if data.is_empty() {
307 return vec![];
308 }
309
310 let mut data = data.to_vec();
311 let last = data[data.len() - 1];
312
313 if last & 0x7f != 0 {
314 return data;
315 }
316
317 if data.len() == 1 {
318 return vec![];
319 }
320
321 if data[data.len() - 2] & 0x80 != 0 {
322 return data;
323 }
324
325 let mut i = data.len() - 1;
326 while i > 0 {
327 if data[i - 1] != 0 {
328 if data[i - 1] & 0x80 != 0 {
329 data[i] = last;
330 return data[..=i].to_vec();
331 } else {
332 data[i - 1] |= last;
333 return data[..i].to_vec();
334 }
335 }
336 i -= 1;
337 }
338
339 vec![]
340}
341
342pub fn check_minimal_data_encoding(v: &[u8]) -> Result<(), InterpreterError> {
344 if v.is_empty() {
345 return Ok(());
346 }
347
348 if v[v.len() - 1] & 0x7f == 0 {
349 if v.len() == 1 || v[v.len() - 2] & 0x80 == 0 {
350 return Err(InterpreterError::new(
351 InterpreterErrorCode::MinimalData,
352 format!(
353 "numeric value encoded as {:02x?} is not minimally encoded",
354 v
355 ),
356 ));
357 }
358 }
359
360 Ok(())
361}
362
363#[cfg(test)]
364mod tests {
365 use super::*;
366
367 fn hex_to_bytes(s: &str) -> Vec<u8> {
368 hex::decode(s).unwrap()
369 }
370
371 #[test]
372 fn test_script_num_bytes() {
373 let tests: Vec<(i64, Vec<u8>)> = vec![
374 (0, vec![]),
375 (1, hex_to_bytes("01")),
376 (-1, hex_to_bytes("81")),
377 (127, hex_to_bytes("7f")),
378 (-127, hex_to_bytes("ff")),
379 (128, hex_to_bytes("8000")),
380 (-128, hex_to_bytes("8080")),
381 (129, hex_to_bytes("8100")),
382 (-129, hex_to_bytes("8180")),
383 (256, hex_to_bytes("0001")),
384 (-256, hex_to_bytes("0081")),
385 (32767, hex_to_bytes("ff7f")),
386 (-32767, hex_to_bytes("ffff")),
387 (32768, hex_to_bytes("008000")),
388 (-32768, hex_to_bytes("008080")),
389 (65535, hex_to_bytes("ffff00")),
390 (-65535, hex_to_bytes("ffff80")),
391 (524288, hex_to_bytes("000008")),
392 (-524288, hex_to_bytes("000088")),
393 (7340032, hex_to_bytes("000070")),
394 (-7340032, hex_to_bytes("0000f0")),
395 (8388608, hex_to_bytes("00008000")),
396 (-8388608, hex_to_bytes("00008080")),
397 (2147483647, hex_to_bytes("ffffff7f")),
398 (-2147483647, hex_to_bytes("ffffffff")),
399 (2147483648, hex_to_bytes("0000008000")),
401 (-2147483648, hex_to_bytes("0000008080")),
402 (2415919104, hex_to_bytes("0000009000")),
403 (-2415919104, hex_to_bytes("0000009080")),
404 (4294967295, hex_to_bytes("ffffffff00")),
405 (-4294967295, hex_to_bytes("ffffffff80")),
406 (4294967296, hex_to_bytes("0000000001")),
407 (-4294967296, hex_to_bytes("0000000081")),
408 (281474976710655, hex_to_bytes("ffffffffffff00")),
409 (-281474976710655, hex_to_bytes("ffffffffffff80")),
410 (72057594037927935, hex_to_bytes("ffffffffffffff00")),
411 (-72057594037927935, hex_to_bytes("ffffffffffffff80")),
412 (9223372036854775807, hex_to_bytes("ffffffffffffff7f")),
413 (-9223372036854775807, hex_to_bytes("ffffffffffffffff")),
414 ];
415
416 for (num, expected) in &tests {
417 let sn = ScriptNumber {
418 val: BigInt::from(*num),
419 after_genesis: true, };
421 let got = sn.to_bytes();
422 assert_eq!(
423 &got, expected,
424 "Bytes: num={}, got={:02x?}, want={:02x?}",
425 num, got, expected
426 );
427 }
428 }
429
430 #[test]
431 fn test_make_script_num() {
432 struct Test {
433 serialized: Vec<u8>,
434 num: i64,
435 num_len: usize,
436 minimal_encoding: bool,
437 expect_err: bool,
438 }
439
440 let tests = vec![
441 Test { serialized: hex_to_bytes("80"), num: 0, num_len: 4, minimal_encoding: true, expect_err: true },
443 Test { serialized: vec![], num: 0, num_len: 4, minimal_encoding: true, expect_err: false },
445 Test { serialized: hex_to_bytes("01"), num: 1, num_len: 4, minimal_encoding: true, expect_err: false },
446 Test { serialized: hex_to_bytes("81"), num: -1, num_len: 4, minimal_encoding: true, expect_err: false },
447 Test { serialized: hex_to_bytes("7f"), num: 127, num_len: 4, minimal_encoding: true, expect_err: false },
448 Test { serialized: hex_to_bytes("ff"), num: -127, num_len: 4, minimal_encoding: true, expect_err: false },
449 Test { serialized: hex_to_bytes("8000"), num: 128, num_len: 4, minimal_encoding: true, expect_err: false },
450 Test { serialized: hex_to_bytes("8080"), num: -128, num_len: 4, minimal_encoding: true, expect_err: false },
451 Test { serialized: hex_to_bytes("8100"), num: 129, num_len: 4, minimal_encoding: true, expect_err: false },
452 Test { serialized: hex_to_bytes("8180"), num: -129, num_len: 4, minimal_encoding: true, expect_err: false },
453 Test { serialized: hex_to_bytes("0001"), num: 256, num_len: 4, minimal_encoding: true, expect_err: false },
454 Test { serialized: hex_to_bytes("0081"), num: -256, num_len: 4, minimal_encoding: true, expect_err: false },
455 Test { serialized: hex_to_bytes("ff7f"), num: 32767, num_len: 4, minimal_encoding: true, expect_err: false },
456 Test { serialized: hex_to_bytes("ffff"), num: -32767, num_len: 4, minimal_encoding: true, expect_err: false },
457 Test { serialized: hex_to_bytes("008000"), num: 32768, num_len: 4, minimal_encoding: true, expect_err: false },
458 Test { serialized: hex_to_bytes("008080"), num: -32768, num_len: 4, minimal_encoding: true, expect_err: false },
459 Test { serialized: hex_to_bytes("ffffff7f"), num: 2147483647, num_len: 4, minimal_encoding: true, expect_err: false },
460 Test { serialized: hex_to_bytes("ffffffff"), num: -2147483647, num_len: 4, minimal_encoding: true, expect_err: false },
461 Test { serialized: hex_to_bytes("ffffffff7f"), num: 549755813887, num_len: 5, minimal_encoding: true, expect_err: false },
463 Test { serialized: hex_to_bytes("ffffffffff"), num: -549755813887, num_len: 5, minimal_encoding: true, expect_err: false },
464 Test { serialized: hex_to_bytes("0000008000"), num: 0, num_len: 4, minimal_encoding: true, expect_err: true },
466 Test { serialized: hex_to_bytes("00"), num: 0, num_len: 4, minimal_encoding: true, expect_err: true },
468 Test { serialized: hex_to_bytes("0100"), num: 0, num_len: 4, minimal_encoding: true, expect_err: true },
469 Test { serialized: hex_to_bytes("00"), num: 0, num_len: 4, minimal_encoding: false, expect_err: false },
471 Test { serialized: hex_to_bytes("0100"), num: 1, num_len: 4, minimal_encoding: false, expect_err: false },
472 ];
473
474 for test in &tests {
475 let result = ScriptNumber::from_bytes(
476 &test.serialized,
477 test.num_len,
478 test.minimal_encoding,
479 true,
480 );
481 match result {
482 Ok(sn) => {
483 assert!(
484 !test.expect_err,
485 "from_bytes({:02x?}): expected error",
486 test.serialized
487 );
488 assert_eq!(
489 sn.to_int(),
490 test.num,
491 "from_bytes({:02x?}): got {}, want {}",
492 test.serialized,
493 sn.to_int(),
494 test.num
495 );
496 }
497 Err(_) => {
498 assert!(
499 test.expect_err,
500 "from_bytes({:02x?}): unexpected error",
501 test.serialized
502 );
503 }
504 }
505 }
506 }
507
508 #[test]
509 fn test_script_num_int32() {
510 let tests: Vec<(i64, i32)> = vec![
511 (0, 0),
512 (1, 1),
513 (-1, -1),
514 (2147483647, 2147483647),
515 (-2147483647, -2147483647),
516 (-2147483648, -2147483648),
517 (2147483648, 2147483647),
519 (-2147483649, -2147483648),
520 (9223372036854775807, 2147483647),
521 (-9223372036854775808, -2147483648),
522 ];
523
524 for (input, want) in &tests {
525 let sn = ScriptNumber {
526 val: BigInt::from(*input),
527 after_genesis: false,
528 };
529 assert_eq!(
530 sn.to_i32(),
531 *want,
532 "Int32({}): got {}, want {}",
533 input,
534 sn.to_i32(),
535 want
536 );
537 }
538 }
539
540 #[test]
541 fn test_minimally_encode() {
542 assert_eq!(minimally_encode(&[]), Vec::<u8>::new());
544 assert_eq!(minimally_encode(&[0x7f]), vec![0x7f]);
546 assert_eq!(minimally_encode(&[0x00]), Vec::<u8>::new());
548 assert_eq!(minimally_encode(&[0x80]), Vec::<u8>::new());
550 }
551}