Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Added
- Extended functions for retrieving information from `OP_RETURN`.
- Conversion and bit functions for `u2`.

### Changed
- Bumped Simplex to 0.2.0.
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ simf/lib
├── u1
│ └── convert.simf
│ └── Conversions from `u1` to other uint types and `bool`.
├── u2
│ ├── bit.simf
│ │ └── Basic bitwise operations (`and`, `or`, `eq`).
│ └── convert.simf
│ └── Conversions between `u2` and other uint types.
├── u8
├── u16
├── u32
Expand Down
77 changes: 77 additions & 0 deletions docs/stdlib.json
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,83 @@
"output_type": "bool",
"description": "Convert a `u1` value to `bool`."
},
{
"simplicityhl_name": "and_2",
"section": "`u2` bit logic",
"input_type": "u2, u2",
"output_type": "u2",
"description": "Bitwise AND of two `u2` values."
},
{
"simplicityhl_name": "or_2",
"section": "`u2` bit logic",
"input_type": "u2, u2",
"output_type": "u2",
"description": "Bitwise OR of two `u2` values."
},
{
"simplicityhl_name": "eq_2",
"section": "`u2` bit logic",
"input_type": "u2, u2",
"output_type": "bool",
"description": "Check whether two `u2` values are equal."
},
{
"simplicityhl_name": "u2_to_u8",
"section": "`u2` conversions",
"input_type": "u2",
"output_type": "u8",
"description": "Widen a `u2` value to a `u8` value, zero-extending the high bits."
},
{
"simplicityhl_name": "u2_to_u16",
"section": "`u2` conversions",
"input_type": "u2",
"output_type": "u16",
"description": "Widen a `u2` value to a `u16` value, zero-extending the high bits."
},
{
"simplicityhl_name": "u2_to_u32",
"section": "`u2` conversions",
"input_type": "u2",
"output_type": "u32",
"description": "Widen a `u2` value to a `u32` value, zero-extending the high bits."
},
{
"simplicityhl_name": "u2_to_u64",
"section": "`u2` conversions",
"input_type": "u2",
"output_type": "u64",
"description": "Widen a `u2` value to a `u64` value, zero-extending the high bits."
},
{
"simplicityhl_name": "u2_to_u128",
"section": "`u2` conversions",
"input_type": "u2",
"output_type": "u128",
"description": "Widen a `u2` value to a `u128` value, zero-extending the high bits."
},
{
"simplicityhl_name": "u2_to_u256",
"section": "`u2` conversions",
"input_type": "u2",
"output_type": "u256",
"description": "Widen a `u2` value to a `u256` value, zero-extending the high bits."
},
{
"simplicityhl_name": "split_u2_into_u1",
"section": "`u2` conversions",
"input_type": "u2",
"output_type": "(u1, u1)",
"description": "Split a `u2` value into two `u1` words, most-significant first."
},
{
"simplicityhl_name": "safe_u2_to_u1",
"section": "`u2` conversions",
"input_type": "u2",
"output_type": "u1",
"description": "Narrow a `u2` value to a `u1` value.\n\n## Panics\nPanics if the value does not fit in `u1`."
},
{
"simplicityhl_name": "checked_add_8",
"section": "`u8` arithmetic",
Expand Down
25 changes: 25 additions & 0 deletions simf/lib/u2/bit.simf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::lib::binary::and;

/// Bitwise AND of two 2-bit values
pub fn and_2(a: u2, b: u2) -> u2 {
let (a_high, a_low): (u1, u1) = <u2>::into(a);
let (b_high, b_low): (u1, u1) = <u2>::into(b);

<(u1, u1)>::into((jet::and_1(a_high, b_high), jet::and_1(a_low, b_low)))
}

/// Bitwise OR of two 2-bit values
pub fn or_2(a: u2, b: u2) -> u2 {
let (a_high, a_low): (u1, u1) = <u2>::into(a);
let (b_high, b_low): (u1, u1) = <u2>::into(b);

<(u1, u1)>::into((jet::or_1(a_high, b_high), jet::or_1(a_low, b_low)))
}

/// Checks if two 2-bit values are equal
pub fn eq_2(a: u2, b: u2) -> bool {
let (a_high, a_low): (u1, u1) = <u2>::into(a);
let (b_high, b_low): (u1, u1) = <u2>::into(b);

and(jet::eq_1(a_high, b_high), jet::eq_1(a_low, b_low))
}
60 changes: 60 additions & 0 deletions simf/lib/u2/convert.simf
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/// Widening uint conversions

/// Converts u2 to u8
pub fn u2_to_u8(a: u2) -> u8 {
<(u2, u2, u2, u2)>::into((0, 0, 0, a))
}

/// Converts u2 to u16
pub fn u2_to_u16(a: u2) -> u16 {
let a_u8: u8 = u2_to_u8(a);

jet::left_pad_low_8_16(a_u8)
}

/// Converts u2 to u32
pub fn u2_to_u32(a: u2) -> u32 {
let a_u8: u8 = u2_to_u8(a);

jet::left_pad_low_8_32(a_u8)
}

/// Converts u2 to u64
pub fn u2_to_u64(a: u2) -> u64 {
let a_u8: u8 = u2_to_u8(a);

jet::left_pad_low_8_64(a_u8)
}

/// Converts u2 to u128
pub fn u2_to_u128(a: u2) -> u128 {
let a_u64: u64 = u2_to_u64(a);

<(u64, u64)>::into((0, a_u64))
}

/// Converts u2 to u256
pub fn u2_to_u256(a: u2) -> u256 {
let a_u128: u128 = u2_to_u128(a);

<(u128, u128)>::into((0, a_u128))
}

/// Splitting uint conversions

/// Splits u2 into two u1
pub fn split_u2_into_u1(a: u2) -> (u1, u1) {
<u2>::into(a)
}

/// Narrowing uint conversions

/// Converts u2 into u1.
/// Panics if the value does not fit in u1
pub fn safe_u2_to_u1(a: u2) -> u1 {
let (high, low): (u1, u1) = <u2>::into(a);

assert!(jet::eq_1(high, 0));

low
}
33 changes: 33 additions & 0 deletions simf/tests/u2/bit.simf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use crate::lib::u2::bit::{and_2, or_2, eq_2};

use crate::tests::support::dispatch::is_selected;
use crate::tests::support::expect::assert_bool;

fn main() {
let fn_idx: u8 = witness::FUNCTION_INDEX;

let a: u2 = witness::FIRST_ARG;
let b: u2 = witness::SECOND_ARG;
let expected: Option<u2> = witness::EXPECTED;

let expected_bool: bool = witness::EXPECTED_BOOL;

match is_selected(0, fn_idx) {
true => {
assert!(eq_2(and_2(a, b), unwrap(expected)));
},
false => (),
};
match is_selected(1, fn_idx) {
true => {
assert!(eq_2(or_2(a, b), unwrap(expected)));
},
false => (),
};
match is_selected(2, fn_idx) {
true => {
assert_bool(eq_2(a, b), expected_bool);
},
false => (),
};
}
102 changes: 102 additions & 0 deletions simf/tests/u2/convert.simf
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use crate::lib::u2::convert::{
u2_to_u8,
u2_to_u16,
u2_to_u32,
u2_to_u64,
u2_to_u128,
u2_to_u256,
split_u2_into_u1,
safe_u2_to_u1
};
use crate::lib::asserts::{
assert_eq_1,
assert_eq_8,
assert_eq_16,
assert_eq_32,
assert_eq_64,
assert_eq_128,
assert_eq_256
};

use crate::tests::support::dispatch::is_selected;

fn main() {
let fn_idx: u8 = witness::FUNCTION_INDEX;

let a: u2 = witness::FIRST_ARG;

let expected: u256 = witness::EXPECTED;
let (_, _, _, expected_64): (u64, u64, u64, u64) = <u256>::into(expected);

match is_selected(0, fn_idx) {
true => {
let expected: u8 = jet::rightmost_64_8(expected_64);

assert_eq_8(u2_to_u8(a), expected);
},
false => (),
};

match is_selected(1, fn_idx) {
true => {
let expected: u16 = jet::rightmost_64_16(expected_64);

assert_eq_16(u2_to_u16(a), expected);
},
false => (),
};

match is_selected(2, fn_idx) {
true => {
let expected: u32 = jet::rightmost_64_32(expected_64);

assert_eq_32(u2_to_u32(a), expected);
},
false => (),
};

match is_selected(3, fn_idx) {
true => {
assert_eq_64(u2_to_u64(a), expected_64);
},
false => (),
};

match is_selected(4, fn_idx) {
true => {
let (_, expected): (u128, u128) = <u256>::into(expected);

assert_eq_128(u2_to_u128(a), expected);
},
false => (),
};

match is_selected(5, fn_idx) {
true => {
assert_eq_256(u2_to_u256(a), expected);
},
false => (),
};

match is_selected(6, fn_idx) {
true => {
let (a1, a0): (u1, u1) = split_u2_into_u1(a);

let expected: u2 = jet::rightmost_64_2(expected_64);
let (expected1, expected0): (u1, u1) = <u2>::into(expected);

assert_eq_1(a1, expected1);
assert_eq_1(a0, expected0);
},
false => (),
};

match is_selected(7, fn_idx) {
true => {
let expected: u1 = jet::rightmost_64_1(expected_64);

assert_eq_1(safe_u2_to_u1(a), expected);
},
false => (),
};
}
10 changes: 1 addition & 9 deletions simf/tests/utxo/op_return.simf
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,13 @@ use crate::lib::utxo::op_return::{
assert_has_entry
};

use crate::lib::binary::and;
use crate::lib::u2::bit::eq_2;
use crate::lib::asserts::assert_eq_8;
use crate::lib::u8::convert::safe_u8_to_u1;

use crate::tests::support::dispatch::is_selected;
use crate::tests::support::expect::assert_bool;

// todo: move to lib
fn eq_2(a: u2, b: u2) -> bool {
let (a_high, a_low): (u1, u1) = <u2>::into(a);
let (b_high, b_low): (u1, u1) = <u2>::into(b);

and(jet::eq_1(a_high, b_high), jet::eq_1(a_low, b_low))
}

// todo: move to lib
fn eq_4(a: u4, b: u4) -> bool {
let a_u8: u8 = <(u4, u4)>::into((0, a));
Expand Down
1 change: 1 addition & 0 deletions tests/stdlib/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod secp256k1;
mod u1;
mod u128;
mod u16;
mod u2;
mod u256;
mod u32;
mod u64;
Expand Down
Loading
Loading