diff --git a/crates/uplc/src/machine/runtime.rs b/crates/uplc/src/machine/runtime.rs index df52d67f..12f6c86c 100644 --- a/crates/uplc/src/machine/runtime.rs +++ b/crates/uplc/src/machine/runtime.rs @@ -1702,7 +1702,42 @@ impl DefaultFunction { Ok(Value::integer(hamming::weight(bytes).into())) } - DefaultFunction::FindFirstSetBit => todo!(), + DefaultFunction::FindFirstSetBit => { + let bytes = args[0].unwrap_byte_string()?; + + let first_bit = + bytes + .into_iter() + .rev() + .enumerate() + .find_map(|(byte_index, value)| { + let value = value.reverse_bits(); + + let first_bit: Option = if value > 128 { + Some(0) + } else if value > 64 { + Some(1) + } else if value > 32 { + Some(2) + } else if value > 16 { + Some(3) + } else if value > 8 { + Some(4) + } else if value > 4 { + Some(5) + } else if value > 2 { + Some(6) + } else if value > 1 { + Some(7) + } else { + None + }; + + first_bit.map(|bit| isize::try_from(bit + byte_index * 8).unwrap()) + }); + + Ok(Value::integer(first_bit.unwrap_or(-1).into())) + } DefaultFunction::Ripemd_160 => { use cryptoxide::{digest::Digest, ripemd160::Ripemd160};