verifies that the element at the top of the stack is less than the modulo and valid (limbs are in range) doesn't consume the element, instead sends it to the altstack
()
| 530 | // verifies that the element at the top of the stack is less than the modulo and valid (limbs are in range) |
| 531 | // doesn't consume the element, instead sends it to the altstack |
| 532 | fn check_validity() -> Script { |
| 533 | let limbs_of_c = U254::biguint_to_limbs(Self::modulus_as_bigint().to_biguint().unwrap()); |
| 534 | script! { |
| 535 | // (Assuming limbs are numbered big endian) |
| 536 | // Number A is greater than number B <=> there exists a limb i, s.t. (A_i > B_i OR (A_i >= B_i and i is the first limb)) and there's no limb j > i satisfying A_i < B_i |
| 537 | // Script below maintains if such state exists for each i behind the foremost limb, combining the results and negating them if there is such j |
| 538 | for i in 0..(Self::N_LIMBS as usize) { |
| 539 | OP_DUP OP_DUP OP_TOALTSTACK |
| 540 | { 0 } { 1 << U254::LIMB_SIZE } OP_WITHIN OP_VERIFY |
| 541 | if i == 0 { |
| 542 | { limbs_of_c[i] } |
| 543 | OP_GREATERTHANOREQUAL |
| 544 | } else { |
| 545 | { limbs_of_c[i] } OP_2DUP |
| 546 | OP_GREATERTHAN OP_TOALTSTACK |
| 547 | OP_GREATERTHANOREQUAL |
| 548 | OP_BOOLAND |
| 549 | OP_FROMALTSTACK OP_BOOLOR |
| 550 | } |
| 551 | if i == (Self::N_LIMBS as usize) - 1 { |
| 552 | OP_NOT OP_VERIFY //This OP_NOT can be negated, but it probably isn't necessary |
| 553 | } else { |
| 554 | OP_SWAP |
| 555 | } |
| 556 | } |
| 557 | } |
| 558 | } |
| 559 | |
| 560 | fn check_validity_and_keep_element() -> Script { |
| 561 | script! { |