Skip to content

Commit

Permalink
🗜️ add bigint compress functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
ZamDimon committed Oct 25, 2024
1 parent de2c1b1 commit 7913099
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 4 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/bigint/cmpeq/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ where
{
T::OP_EXTEND::<Q>()
}
fn OP_COMPRESS<Q>() -> Script
where
Q: NonNativeLimbInteger,
{
T::OP_COMPRESS::<Q>()
}
}

#[allow(non_snake_case)]
Expand Down
6 changes: 6 additions & 0 deletions src/bigint/implementation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,10 @@ impl<const N_BITS: usize, const LIMB_SIZE: usize> NonNativeInteger
{
Self::handle_OP_EXTEND::<T>()
}
fn OP_COMPRESS<T>() -> Script
where
T: NonNativeLimbInteger,
{
Self::handle_OP_COMPRESS::<T>()
}
}
2 changes: 1 addition & 1 deletion src/bigint/naf/implementation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ pub fn binary_to_be_naf(num_bits: usize) -> Script {
OP_2DUP OP_BITAND OP_IF
// In case they are both 1, we need to change them to -1 and 0, while the carry must be one
OP_3DROP
1 -1 0
1 (-1) 0
OP_ENDIF

OP_ROT
Expand Down
31 changes: 31 additions & 0 deletions src/bigint/stack/implementation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ impl<const N_BITS: usize, const LIMB_SIZE: usize> NonNativeBigIntImpl<N_BITS, LI
"The integers to be extended must have the same number of bits in limb"
);

// Calculating the number of limbs to add
let n_limbs_self = (Self::N_BITS + Self::LIMB_SIZE - 1) / Self::LIMB_SIZE;
let n_limbs_extension = (T::N_BITS + T::LIMB_SIZE - 1) / T::LIMB_SIZE;
let n_limbs_add = n_limbs_extension - n_limbs_self;
Expand All @@ -236,6 +237,36 @@ impl<const N_BITS: usize, const LIMB_SIZE: usize> NonNativeBigIntImpl<N_BITS, LI
}
}
}

/// Extends the big integer to the specified type.
pub(in super::super) fn handle_OP_COMPRESS<T>() -> Script
where
T: NonNativeLimbInteger,
{
assert!(
T::N_BITS < Self::N_BITS,
"The integer to be compressed to must have less bits than the current integer"
);
assert!(
T::LIMB_SIZE == Self::LIMB_SIZE,
"The integers to be compressed to must have the same number of bits in limb"
);

// Calculating the number of limbs to remove
let n_limbs_self = (Self::N_BITS + Self::LIMB_SIZE - 1) / Self::LIMB_SIZE;
let n_limbs_compress = (T::N_BITS + T::LIMB_SIZE - 1) / T::LIMB_SIZE;
let n_limbs_to_remove = n_limbs_self - n_limbs_compress;

if n_limbs_to_remove == 0 {
return script! {};
}

script! {
for i in 0..n_limbs_to_remove {
{ Self::N_LIMBS - i - 1 } OP_ROLL OP_DROP
}
}
}
}

impl<const N_BITS: usize, const LIMB_SIZE: usize> NonNativeBigIntImpl<N_BITS, LIMB_SIZE> {
Expand Down
23 changes: 23 additions & 0 deletions src/bigint/stack/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,3 +488,26 @@ fn test_254_bit_widening() {
assert!(exec_result.success);
}
}

#[test]
/// Tests the extension of 254-bit number to 508-bit number and then
/// compressing it back to 254-bit number.
fn test_254_bit_compress() {
print_script_size("254-bit compression", U508::OP_COMPRESS::<U254>());

let mut prng = ChaCha20Rng::seed_from_u64(0);
for _ in 0..100 {
let a: BigUint = prng.sample(RandomBits::new(254));
let script = script! {
{ U254::OP_PUSH_U32LESLICE(&a.to_u32_digits()) }
{ U254::OP_EXTEND::<U508>() }
{ U508::OP_COMPRESS::<U254>() }
{ U254::OP_PUSH_U32LESLICE(&a.to_u32_digits()) }
{ U254::OP_EQUALVERIFY(1, 0) }
OP_TRUE
};

let exec_result = execute_script(script);
assert!(exec_result.success);
}
}
6 changes: 6 additions & 0 deletions src/bigint/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,12 @@ where
{
T::OP_EXTEND::<Q>()
}
fn OP_COMPRESS<Q>() -> Script
where
Q: NonNativeLimbInteger,
{
T::OP_COMPRESS::<Q>()
}
}

#[allow(non_snake_case)]
Expand Down
2 changes: 1 addition & 1 deletion src/bigint/window/precompute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::marker::PhantomData;
use crate::traits::integer::NonNativeLimbInteger;
use crate::treepp::*;

pub(in super::super) struct WindowedPrecomputeTable<T, const WIDTH: usize, const NOOVERFLOW: bool>
pub struct WindowedPrecomputeTable<T, const WIDTH: usize, const NOOVERFLOW: bool>
where
T: NonNativeLimbInteger,
{
Expand Down
5 changes: 5 additions & 0 deletions src/traits/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ pub trait NonNativeInteger: Comparable + Arithmeticable + Bitable {
where
T: NonNativeLimbInteger;

/// Compresses the given [`NonNativeInteger`] back to the specified type.
fn OP_COMPRESS<T>() -> Script
where
T: NonNativeLimbInteger;

// --- Stack operations ---

/// Zips two [`NonNativeInteger`]s at specified depths.
Expand Down

0 comments on commit 7913099

Please sign in to comment.