Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🗜️ Add BigInt Compress Functionality #1

Merged
merged 2 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
33 changes: 32 additions & 1 deletion src/bigint/stack/implementation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ impl<const N_BITS: usize, const LIMB_SIZE: usize> NonNativeBigIntImpl<N_BITS, LI
}
}

/// Extends the big integer to the specified type.
/// Extends the big integer to the specified [`NonNativeLimbInteger`].
pub(in super::super) fn handle_OP_EXTEND<T>() -> Script
where
T: NonNativeLimbInteger,
Expand All @@ -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
}
}
}

/// Compresses the big integer to the specified [`NonNativeLimbInteger`].
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