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
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## [Unreleased]
## [0.0.2]

- Added `mul_div` functions.
- Organized code into modules.
Expand All @@ -11,7 +11,7 @@
## [0.0.1]

Initial release!
- Сhecked arithmetic operations for `u8`, `u16`, `u32`, `u64`, and `u128`.
- Сhecked arithmetic operations for `u8`, `u16`, `u32`, `u64`, `u128` and `u256`.
- `OP_RETURN` detection utilities.
- Implementation of `and`, `or`, `not`, and `xor` binary operators.
- Basic numeric assertions.
Expand Down
27 changes: 23 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ simf/lib
├── u64
│ ├── convert.simf
│ │ └── Conversions between `u8`, `u16`, `u32`, `u64` and other uint types.
│ └── math.simf
│ └── Overflow-checked arithmetic and `gt`/`ge` functions.
│ ├── math.simf
│ │ └── Overflow-checked arithmetic and `gt`/`ge` functions.
│ └── mul_div.simf
│ └── Full-precision calculation of `floor(a * b / denominator)`.
├── u128
├── u256
│ ├── bit.simf
Expand All @@ -34,8 +36,25 @@ simf/lib
│ │ └── Basic comparison operations available as jets for `u8`-`u64` but missing for `u128` and `u256`.
│ ├── convert.simf
│ │ └── Conversions between `u128`, `u256` and other uint types.
│ └── math.simf
│ └── Carry/borrow arithmetic, multiplication, division, and overflow-checked wrappers.
│ ├── math.simf
│ │ └── Carry/borrow arithmetic, multiplication, division, and overflow-checked wrappers.
│ └── mul_div.simf
│ └── Full-precision calculation of `floor(a * b / denominator)`.
├── utxo
│ ├── asserts
│ │ ├── amount.simf
│ │ │ └── Functions for asserting `Amount` in inputs and outputs.
│ │ ├── asset_id.simf
│ │ │ └── Functions for asserting `AssetId` in inputs and outputs.
│ │ └── asset_id_with_amount.simf
│ │ └── Functions for asserting `Amount` and `AssetId` in inputs and outputs.
│ └── getters
│ ├── amount.simf
│ │ └── Functions for retrieving `Amount` in inputs and outputs.
│ ├── asset_id.simf
│ │ └── Functions for retrieving `AssetId` in inputs and outputs.
│ └── asset_id_with_amount.simf
│ └── Functions for retrieving `Amount` and `AssetId` in inputs and outputs.
├── asserts.simf
│ └── Assertion helpers: `assert_eq_*` for uints and `bool`, plus `assert_none_*` for `Option`.
├── binary.simf
Expand Down
64 changes: 32 additions & 32 deletions docs/stdlib.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion simf/lib/asserts.simf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::lib::u128::bit::eq_128;

/// Asserts that two `u1` are equal
/// Asserts that two u1 are equal
pub fn assert_eq_1(a: u1, b: u1) {
assert!(jet::eq_1(a, b))
}
Expand Down
2 changes: 1 addition & 1 deletion simf/lib/u16/math.simf
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn checked_div_16(a: u16, b: u16) -> Option<u16> {
}
}

/// Returns the quotient of two u16 values, panics if the result overflows u16
/// Returns the quotient of two u16 values, panics if the divisor is zero
pub fn div_16(a: u16, b: u16) -> u16 {
unwrap(checked_div_16(a, b))
}
Expand Down
2 changes: 1 addition & 1 deletion simf/lib/u256/math.simf
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ fn normalize_to_threshold_256_63(a: u256, b: u128, is_b_u128: bool) -> (u64, u25
/// the most significant non-zero word of `b` is at least 2^127.
///
/// The normalized dividend fits into 384 bits and is returned as a
/// `(u128, u256)` pair. The normalized divisor fits into a `u256`.
/// `(u128, u256)` pair. The normalized divisor fits into a u256.
fn normalize_to_threshold_256_127(a: u256, b: u256) -> (u128, u256, u256) {
let norm: u128 = calculate_normalizer_base_128(b);

Expand Down
6 changes: 3 additions & 3 deletions simf/lib/u256/mul_div.simf
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn estimate_quotient_digit_base_128(u2: u128, u1: u128, u0: u128, v1: u128, v0:
/// the most significant non-zero word of `b` is at least 2^127.
///
/// The normalized dividend fits into 640 bits and is returned as a
/// `(u128, u256, u256)` tuple. The normalized divisor fits into a `u256`
/// `(u128, u256, u256)` tuple. The normalized divisor fits into a u256
fn normalize_to_threshold_512_127(a_high: u256, a_low: u256, b: u256) -> (u128, u256, u256, u256) {
let norm: u128 = calculate_normalizer_base_128(b);

Expand Down Expand Up @@ -125,10 +125,10 @@ fn mul_and_sub_128(q: u128, u2: u128, u1: u128, u0: u128, v: u256) -> (u128, u12
split_u256_into_u128(u_updated_1_0)
}

/// Divides a 512-bit integer by a 256-bit integer and returns a `u256` quotient.
/// Divides a 512-bit integer by a 256-bit integer and returns a u256 quotient.
/// Implements Algorithm D by Donald Knuth.
/// Requires the upper half of the divisor to be non-zero (`divisor >= 2^128`)
/// and the quotient to fit into `u256`
/// and the quotient to fit into u256
fn algorithm_d_512_256(dividend_high: u256, dividend_low: u256, divisor: u256) -> u256 {
let (
_,
Expand Down
2 changes: 1 addition & 1 deletion simf/lib/u32/math.simf
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn checked_div_32(a: u32, b: u32) -> Option<u32> {
}
}

/// Returns the quotient of two u32 values, panics if the result overflows u32
/// Returns the quotient of two u32 values, panics if the divisor is zero
pub fn div_32(a: u32, b: u32) -> u32 {
unwrap(checked_div_32(a, b))
}
Expand Down
2 changes: 1 addition & 1 deletion simf/lib/u64/math.simf
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn checked_div_64(a: u64, b: u64) -> Option<u64> {
}
}

/// Returns the quotient of two u64 values, panics if the result overflows u64
/// Returns the quotient of two u64 values, panics if the divisor is zero
pub fn div_64(a: u64, b: u64) -> u64 {
unwrap(checked_div_64(a, b))
}
Expand Down
2 changes: 1 addition & 1 deletion simf/lib/u8/math.simf
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn checked_div_8(a: u8, b: u8) -> Option<u8> {
}
}

/// Returns the quotient of two u8 values, panics if the result overflows u8
/// Returns the quotient of two u8 values, panics if the divisor is zero
pub fn div_8(a: u8, b: u8) -> u8 {
unwrap(checked_div_8(a, b))
}
Expand Down
26 changes: 17 additions & 9 deletions simf/lib/utxo/getters/amount.simf
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
/// in unnecessary overhead.

/// Returns the explicit amount at the specified input or output.
/// Panics if the specified input or output does not exist or if its amount is confidential.
///
/// Warning: using this incurs the overhead, and should be used only when the input/output selection
/// needs to be determined at runtime; otherwise, use the input- or output- specific getter directly.
/// needs to be determined at runtime; otherwise, use the input- or output- specific getter directly
pub fn get_explicit_amount(index: u32, is_input_index: bool) -> u64 {
let (
_,
Expand All @@ -21,10 +22,11 @@ pub fn get_explicit_amount(index: u32, is_input_index: bool) -> u64 {
unwrap_right::<(u1, u256)>(amount)
}

/// Returns the confidential amount at the specified input or output
/// Returns the confidential amount at the specified input or output.
/// Panics if the specified input or output does not exist or if its amount is explicit.
///
/// Warning: using this incurs the overhead, and should be used only when the input/output selection
/// needs to be determined at runtime; otherwise, use the input- or output- specific getter directly.
/// needs to be determined at runtime; otherwise, use the input- or output- specific getter directly
pub fn get_confidential_amount(index: u32, is_input_index: bool) -> Confidential1 {
let (
_,
Expand All @@ -37,42 +39,48 @@ pub fn get_confidential_amount(index: u32, is_input_index: bool) -> Confidential
unwrap_left::<u64>(amount)
}

/// Returns the explicit amount at the specified input
/// Returns the explicit amount at the specified input.
/// Panics if the specified input does not exist or if its amount is confidential
pub fn get_explicit_input_amount(index: u32) -> u64 {
let (_, amount): (Asset1, Amount1) = unwrap(jet::input_amount(index));

unwrap_right::<(u1, u256)>(amount)
}

/// Returns the confidential amount at the specified input
/// Returns the confidential amount at the specified input.
/// Panics if the specified input does not exist or if its amount is explicit
pub fn get_confidential_input_amount(index: u32) -> Confidential1 {
let (_, amount): (Asset1, Amount1) = unwrap(jet::input_amount(index));

unwrap_left::<u64>(amount)
}

/// Returns the explicit amount at the specified output
/// Returns the explicit amount at the specified output.
/// Panics if the specified output does not exist or if its amount is confidential
pub fn get_explicit_output_amount(index: u32) -> u64 {
let (_, amount): (Asset1, Amount1) = unwrap(jet::output_amount(index));

unwrap_right::<(u1, u256)>(amount)
}

/// Returns the confidential amount at the specified output
/// Returns the confidential amount at the specified output.
/// Panics if the specified output does not exist or if its amount is explicit
pub fn get_confidential_output_amount(index: u32) -> Confidential1 {
let (_, amount): (Asset1, Amount1) = unwrap(jet::output_amount(index));

unwrap_left::<u64>(amount)
}

/// Returns the explicit input amount at the current_index
/// Returns the explicit input amount at the current_index.
/// Panics if amount is confidential
pub fn get_explicit_current_amount() -> u64 {
let (_, amount): (Asset1, Amount1) = jet::current_amount();

unwrap_right::<(u1, u256)>(amount)
}

/// Returns the confidential input amount at the current_index
/// Returns the confidential input amount at the current_index.
/// Panics if amount is explicit
pub fn get_confidential_current_amount() -> Confidential1 {
let (_, amount): (Asset1, Amount1) = jet::current_amount();

Expand Down
24 changes: 16 additions & 8 deletions simf/lib/utxo/getters/asset_id.simf
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// Functions for retrieving AssetId

/// Returns the explicit asset_id at the specified input or output
/// Returns the explicit asset_id at the specified input or output.
/// Panics if the specified input or output does not exist or if its asset_id is confidential.
///
/// Warning: using this incurs the overhead, and should be used only when the input/output selection
/// needs to be determined at runtime; otherwise, use the input- or output- specific getter directly.
Expand All @@ -13,7 +14,8 @@ pub fn get_explicit_asset_id(index: u32, is_input_index: bool) -> u256 {
unwrap_right::<(u1, u256)>(asset)
}

/// Returns the confidential asset_id at the specified input or output
/// Returns the confidential asset_id at the specified input or output.
/// Panics if the specified input or output does not exist or if its asset_id is explicit
///
/// Warning: using this incurs the overhead, and should be used only when the input/output selection
/// needs to be determined at runtime; otherwise, use the input- or output- specific getter directly.
Expand All @@ -26,42 +28,48 @@ pub fn get_confidential_asset_id(index: u32, is_input_index: bool) -> Confidenti
unwrap_left::<u256>(asset)
}

/// Returns the explicit asset_id at the specified input
/// Returns the explicit asset_id at the specified input.
/// Panics if the specified input does not exist or if its asset_id is confidential
pub fn get_explicit_input_asset_id(index: u32) -> u256 {
let asset: Asset1 = unwrap(jet::input_asset(index));

unwrap_right::<(u1, u256)>(asset)
}

/// Returns the confidential asset_id at the specified input
/// Returns the confidential asset_id at the specified input.
/// Panics if the specified input does not exist or if its asset_id is explicit
pub fn get_confidential_input_asset_id(index: u32) -> Confidential1 {
let asset: Asset1 = unwrap(jet::input_asset(index));

unwrap_left::<u256>(asset)
}

/// Returns the explicit asset_id at the specified output
/// Returns the explicit asset_id at the specified output.
/// Panics if the specified output does not exist or if its asset_id is confidential
pub fn get_explicit_output_asset_id(index: u32) -> u256 {
let asset: Asset1 = unwrap(jet::output_asset(index));

unwrap_right::<(u1, u256)>(asset)
}

/// Returns the confidential asset_id at the specified output
/// Returns the confidential asset_id at the specified output.
/// Panics if the specified output does not exist or if its asset_id is explicit
pub fn get_confidential_output_asset_id(index: u32) -> Confidential1 {
let asset: Asset1 = unwrap(jet::output_asset(index));

unwrap_left::<u256>(asset)
}

/// Returns the explicit input asset_id at the current_index
/// Returns the explicit input asset_id at the current_index.
/// Panics if asset_id is confidential
pub fn get_explicit_current_asset_id() -> u256 {
let asset: Asset1 = jet::current_asset();

unwrap_right::<(u1, u256)>(asset)
}

/// Returns the confidential input asset_id at the current_index
/// Returns the confidential input asset_id at the current_index.
/// Panics if asset_id is explicit
pub fn get_confidential_current_asset_id() -> Confidential1 {
let asset: Asset1 = jet::current_asset();

Expand Down
22 changes: 15 additions & 7 deletions simf/lib/utxo/getters/asset_id_with_amount.simf
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// Functions for retrieving an `AssetId` along with an `Amount`

/// Returns explicit asset_id and amount at the specified input or output.
/// Panics if the specified input or output does not exist or if its asset_id and amount are confidential.
///
/// Warning: using this incurs the overhead, and should be used only when the input/output selection
/// needs to be determined at runtime; otherwise, use the input- or output- specific getter directly.
Expand All @@ -16,7 +17,8 @@ pub fn get_explicit_asset_id_with_amount(index: u32, is_input_index: bool) -> (u
(unwrap_right::<(u1, u256)>(asset), unwrap_right::<(u1, u256)>(amount))
}

/// Returns confidential asset_id and amount at the specified input or output
/// Returns confidential asset_id and amount at the specified input or output.
/// Panics if the specified input or output does not exist or if its asset_id and amount are explicit.
///
/// Warning: using this incurs the overhead, and should be used only when the input/output selection
/// needs to be determined at runtime; otherwise, use the input- or output- specific getter directly.
Expand All @@ -35,42 +37,48 @@ pub fn get_confidential_asset_id_with_amount(
(unwrap_left::<u256>(asset), unwrap_left::<u64>(amount))
}

/// Returns explicit asset_id and amount at the specified input
/// Returns explicit asset_id and amount at the specified input.
/// Panics if the specified input does not exist or if its asset_id and amount are confidential
pub fn get_explicit_input_asset_id_with_amount(index: u32) -> (u256, u64) {
let (asset, amount): (Asset1, Amount1) = unwrap(jet::input_amount(index));

(unwrap_right::<(u1, u256)>(asset), unwrap_right::<(u1, u256)>(amount))
}

/// Returns confidential asset_id and amount at the specified input
/// Returns confidential asset_id and amount at the specified input.
/// Panics if the specified input does not exist or if its asset_id and amount are explicit
pub fn get_confidential_input_asset_id_with_amount(index: u32) -> (Confidential1, Confidential1) {
let (asset, amount): (Asset1, Amount1) = unwrap(jet::input_amount(index));

(unwrap_left::<u256>(asset), unwrap_left::<u64>(amount))
}

/// Returns explicit asset_id and amount at the specified output
/// Returns explicit asset_id and amount at the specified output.
/// Panics if the specified output does not exist or if its asset_id and amount are confidential
pub fn get_explicit_output_asset_id_with_amount(index: u32) -> (u256, u64) {
let (asset, amount): (Asset1, Amount1) = unwrap(jet::output_amount(index));

(unwrap_right::<(u1, u256)>(asset), unwrap_right::<(u1, u256)>(amount))
}

/// Returns confidential asset_id and amount at the specified output
/// Returns confidential asset_id and amount at the specified output.
/// Panics if the specified output does not exist or if its asset_id and amount are explicit
pub fn get_confidential_output_asset_id_with_amount(index: u32) -> (Confidential1, Confidential1) {
let (asset, amount): (Asset1, Amount1) = unwrap(jet::output_amount(index));

(unwrap_left::<u256>(asset), unwrap_left::<u64>(amount))
}

/// Returns explicit input asset_id and amount at the current_index
/// Returns explicit input asset_id and amount at the current_index.
/// Panics if asset_id and amount are confidential
pub fn get_explicit_current_asset_id_with_amount() -> (u256, u64) {
let (asset, amount): (Asset1, Amount1) = jet::current_amount();

(unwrap_right::<(u1, u256)>(asset), unwrap_right::<(u1, u256)>(amount))
}

/// Returns confidential input asset_id and amount at the current_index
/// Returns confidential input asset_id and amount at the current_index.
/// Panics if asset_id and amount are explicit
pub fn get_confidential_current_asset_id_with_amount() -> (Confidential1, Confidential1) {
let (asset, amount): (Asset1, Amount1) = jet::current_amount();

Expand Down
Loading