Skip to content

Commit 6e61c43

Browse files
authored
🔀 Merge pull request #1 from feature/bigint-compress
🗜️ Add BigInt Compress Functionality
2 parents de2c1b1 + 1f97d5d commit 6e61c43

File tree

9 files changed

+82
-5
lines changed

9 files changed

+82
-5
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bigint/cmpeq/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,12 @@ where
168168
{
169169
T::OP_EXTEND::<Q>()
170170
}
171+
fn OP_COMPRESS<Q>() -> Script
172+
where
173+
Q: NonNativeLimbInteger,
174+
{
175+
T::OP_COMPRESS::<Q>()
176+
}
171177
}
172178

173179
#[allow(non_snake_case)]

src/bigint/implementation.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,10 @@ impl<const N_BITS: usize, const LIMB_SIZE: usize> NonNativeInteger
167167
{
168168
Self::handle_OP_EXTEND::<T>()
169169
}
170+
fn OP_COMPRESS<T>() -> Script
171+
where
172+
T: NonNativeLimbInteger,
173+
{
174+
Self::handle_OP_COMPRESS::<T>()
175+
}
170176
}

src/bigint/naf/implementation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub fn binary_to_be_naf(num_bits: usize) -> Script {
8585
OP_2DUP OP_BITAND OP_IF
8686
// In case they are both 1, we need to change them to -1 and 0, while the carry must be one
8787
OP_3DROP
88-
1 -1 0
88+
{ 1 } { -1 } { 0 }
8989
OP_ENDIF
9090

9191
OP_ROT

src/bigint/stack/implementation.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ impl<const N_BITS: usize, const LIMB_SIZE: usize> NonNativeBigIntImpl<N_BITS, LI
207207
}
208208
}
209209

210-
/// Extends the big integer to the specified type.
210+
/// Extends the big integer to the specified [`NonNativeLimbInteger`].
211211
pub(in super::super) fn handle_OP_EXTEND<T>() -> Script
212212
where
213213
T: NonNativeLimbInteger,
@@ -221,6 +221,7 @@ impl<const N_BITS: usize, const LIMB_SIZE: usize> NonNativeBigIntImpl<N_BITS, LI
221221
"The integers to be extended must have the same number of bits in limb"
222222
);
223223

224+
// Calculating the number of limbs to add
224225
let n_limbs_self = (Self::N_BITS + Self::LIMB_SIZE - 1) / Self::LIMB_SIZE;
225226
let n_limbs_extension = (T::N_BITS + T::LIMB_SIZE - 1) / T::LIMB_SIZE;
226227
let n_limbs_add = n_limbs_extension - n_limbs_self;
@@ -236,6 +237,36 @@ impl<const N_BITS: usize, const LIMB_SIZE: usize> NonNativeBigIntImpl<N_BITS, LI
236237
}
237238
}
238239
}
240+
241+
/// Compresses the big integer to the specified [`NonNativeLimbInteger`].
242+
pub(in super::super) fn handle_OP_COMPRESS<T>() -> Script
243+
where
244+
T: NonNativeLimbInteger,
245+
{
246+
assert!(
247+
T::N_BITS < Self::N_BITS,
248+
"The integer to be compressed to must have less bits than the current integer"
249+
);
250+
assert!(
251+
T::LIMB_SIZE == Self::LIMB_SIZE,
252+
"The integers to be compressed to must have the same number of bits in limb"
253+
);
254+
255+
// Calculating the number of limbs to remove
256+
let n_limbs_self = (Self::N_BITS + Self::LIMB_SIZE - 1) / Self::LIMB_SIZE;
257+
let n_limbs_compress = (T::N_BITS + T::LIMB_SIZE - 1) / T::LIMB_SIZE;
258+
let n_limbs_to_remove = n_limbs_self - n_limbs_compress;
259+
260+
if n_limbs_to_remove == 0 {
261+
return script! {};
262+
}
263+
264+
script! {
265+
for i in 0..n_limbs_to_remove {
266+
{ Self::N_LIMBS - i - 1 } OP_ROLL OP_DROP
267+
}
268+
}
269+
}
239270
}
240271

241272
impl<const N_BITS: usize, const LIMB_SIZE: usize> NonNativeBigIntImpl<N_BITS, LIMB_SIZE> {

src/bigint/stack/test.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,3 +488,26 @@ fn test_254_bit_widening() {
488488
assert!(exec_result.success);
489489
}
490490
}
491+
492+
#[test]
493+
/// Tests the extension of 254-bit number to 508-bit number and then
494+
/// compressing it back to 254-bit number.
495+
fn test_254_bit_compress() {
496+
print_script_size("254-bit compression", U508::OP_COMPRESS::<U254>());
497+
498+
let mut prng = ChaCha20Rng::seed_from_u64(0);
499+
for _ in 0..100 {
500+
let a: BigUint = prng.sample(RandomBits::new(254));
501+
let script = script! {
502+
{ U254::OP_PUSH_U32LESLICE(&a.to_u32_digits()) }
503+
{ U254::OP_EXTEND::<U508>() }
504+
{ U508::OP_COMPRESS::<U254>() }
505+
{ U254::OP_PUSH_U32LESLICE(&a.to_u32_digits()) }
506+
{ U254::OP_EQUALVERIFY(1, 0) }
507+
OP_TRUE
508+
};
509+
510+
let exec_result = execute_script(script);
511+
assert!(exec_result.success);
512+
}
513+
}

src/bigint/window/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,12 @@ where
204204
{
205205
T::OP_EXTEND::<Q>()
206206
}
207+
fn OP_COMPRESS<Q>() -> Script
208+
where
209+
Q: NonNativeLimbInteger,
210+
{
211+
T::OP_COMPRESS::<Q>()
212+
}
207213
}
208214

209215
#[allow(non_snake_case)]

src/bigint/window/precompute.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::marker::PhantomData;
33
use crate::traits::integer::NonNativeLimbInteger;
44
use crate::treepp::*;
55

6-
pub(in super::super) struct WindowedPrecomputeTable<T, const WIDTH: usize, const NOOVERFLOW: bool>
6+
pub struct WindowedPrecomputeTable<T, const WIDTH: usize, const NOOVERFLOW: bool>
77
where
88
T: NonNativeLimbInteger,
99
{

src/traits/integer.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ pub trait NonNativeInteger: Comparable + Arithmeticable + Bitable {
4646
where
4747
T: NonNativeLimbInteger;
4848

49+
/// Compresses the given [`NonNativeInteger`] back to the specified type.
50+
fn OP_COMPRESS<T>() -> Script
51+
where
52+
T: NonNativeLimbInteger;
53+
4954
// --- Stack operations ---
5055

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

0 commit comments

Comments
 (0)