One last builtin to do. Also switch to using bitvec for faster and more accurate shifting

This commit is contained in:
microproofs 2024-12-06 11:33:45 +07:00
parent 91d4ecc350
commit 86951ef19a
No known key found for this signature in database
GPG Key ID: 14F93C84DE6AFD17
3 changed files with 96 additions and 18 deletions

47
Cargo.lock generated vendored
View File

@ -390,6 +390,18 @@ version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "bitvec"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
@ -1021,6 +1033,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "funty"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "futures"
version = "0.3.31"
@ -1210,6 +1228,12 @@ dependencies = [
"crunchy",
]
[[package]]
name = "hamming"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1"
[[package]]
name = "hashbrown"
version = "0.12.3"
@ -2503,6 +2527,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "radium"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "rand"
version = "0.8.5"
@ -3131,6 +3161,12 @@ dependencies = [
"libc",
]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tempfile"
version = "3.14.0"
@ -3426,8 +3462,10 @@ checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
name = "uplc"
version = "1.1.7"
dependencies = [
"bitvec",
"blst",
"cryptoxide",
"hamming",
"hex",
"indexmap 1.9.3",
"indoc",
@ -3852,6 +3890,15 @@ version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
[[package]]
name = "wyz"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
dependencies = [
"tap",
]
[[package]]
name = "xdg"
version = "2.5.2"

View File

@ -33,6 +33,8 @@ strum_macros = "0.24.3"
thiserror = "1.0.39"
blst = "0.3.11"
once_cell = "1.18.0"
hamming = "0.1.3"
bitvec = "1.0.1"
[target.'cfg(not(target_family="wasm"))'.dependencies]
secp256k1 = { version = "0.26.0" }

View File

@ -9,8 +9,9 @@ use crate::{
machine::value::integer_log2,
plutus_data_to_bytes,
};
use bitvec::{order::Lsb0, vec::BitVec};
use itertools::Itertools;
use num_bigint::{BigInt, Sign};
use num_bigint::BigInt;
use num_integer::Integer;
use num_traits::{FromPrimitive, Signed, Zero};
use once_cell::sync::Lazy;
@ -1664,34 +1665,62 @@ impl DefaultFunction {
let byte_length = bytes.len();
if BigInt::from_usize(byte_length).unwrap() * 8 < shift.abs() {
if BigInt::from_usize(byte_length).unwrap() * 8 <= shift.abs() {
let mut new_vec = vec![];
new_vec.resize(byte_length, 0);
return Ok(Value::byte_string(new_vec));
}
let bytes = BigInt::from_bytes_be(Sign::NoSign, bytes);
let is_shl = shift >= &0.into();
let bytes = if is_shl {
bytes << usize::try_from(shift.abs()).unwrap()
} else {
bytes >> usize::try_from(shift.abs()).unwrap()
}
.to_bytes_be()
.1
.into_iter()
.take(byte_length)
.collect_vec();
let mut bv = BitVec::<u8, Lsb0>::from_vec(bytes.clone());
Ok(Value::byte_string(bytes))
if is_shl {
bv.shift_left(usize::try_from(shift.abs()).unwrap());
} else {
bv.shift_right(usize::try_from(shift.abs()).unwrap());
}
Ok(Value::byte_string(bv.into_vec()))
}
DefaultFunction::RotateByteString => {
let bytes = args[0].unwrap_byte_string()?;
let shift = args[1].unwrap_integer()?;
let byte_length = bytes.len();
let shift = shift % byte_length;
let mut bv = BitVec::<u8, Lsb0>::from_vec(bytes.clone());
bv.rotate_right(usize::try_from(shift).unwrap());
Ok(Value::byte_string(bv.into_vec()))
}
DefaultFunction::CountSetBits => {
let bytes = args[0].unwrap_byte_string()?;
Ok(Value::integer(hamming::weight(bytes).into()))
}
DefaultFunction::RotateByteString => todo!(),
DefaultFunction::CountSetBits => todo!(),
DefaultFunction::FindFirstSetBit => todo!(),
DefaultFunction::Ripemd_160 => todo!(),
DefaultFunction::Ripemd_160 => {
use cryptoxide::{digest::Digest, ripemd160::Ripemd160};
let arg1 = args[0].unwrap_byte_string()?;
let mut hasher = Ripemd160::new();
hasher.input(arg1);
let mut bytes = vec![0; hasher.output_bytes()];
hasher.result(&mut bytes);
let value = Value::byte_string(bytes);
Ok(value)
}
DefaultFunction::ExpModInteger => todo!(),
}
}